diff options
Diffstat (limited to 'spec/requests/projects')
-rw-r--r-- | spec/requests/projects/cycle_analytics_events_spec.rb | 18 | ||||
-rw-r--r-- | spec/requests/projects/merge_requests/diffs_spec.rb | 73 | ||||
-rw-r--r-- | spec/requests/projects/merge_requests_discussions_spec.rb | 72 | ||||
-rw-r--r-- | spec/requests/projects/merge_requests_spec.rb | 159 |
4 files changed, 300 insertions, 22 deletions
diff --git a/spec/requests/projects/cycle_analytics_events_spec.rb b/spec/requests/projects/cycle_analytics_events_spec.rb index 7921fdcb0de..89d46b64311 100644 --- a/spec/requests/projects/cycle_analytics_events_spec.rb +++ b/spec/requests/projects/cycle_analytics_events_spec.rb @@ -8,6 +8,9 @@ RSpec.describe 'value stream analytics events' do let(:issue) { create(:issue, project: project, created_at: 2.days.ago) } describe 'GET /:namespace/:project/value_stream_analytics/events/issues' do + let(:first_issue_iid) { project.issues.sort_by_attribute(:created_desc).pluck(:iid).first.to_s } + let(:first_mr_iid) { project.merge_requests.sort_by_attribute(:created_desc).pluck(:iid).first.to_s } + before do project.add_developer(user) @@ -25,8 +28,6 @@ RSpec.describe 'value stream analytics events' do it 'lists the issue events' do get project_cycle_analytics_issue_path(project, format: :json) - first_issue_iid = project.issues.sort_by_attribute(:created_desc).pluck(:iid).first.to_s - expect(json_response['events']).not_to be_empty expect(json_response['events'].first['iid']).to eq(first_issue_iid) end @@ -34,8 +35,6 @@ RSpec.describe 'value stream analytics events' do it 'lists the plan events' do get project_cycle_analytics_plan_path(project, format: :json) - first_issue_iid = project.issues.sort_by_attribute(:created_desc).pluck(:iid).first.to_s - expect(json_response['events']).not_to be_empty expect(json_response['events'].first['iid']).to eq(first_issue_iid) end @@ -45,8 +44,6 @@ RSpec.describe 'value stream analytics events' do expect(json_response['events']).not_to be_empty - first_mr_iid = project.merge_requests.sort_by_attribute(:created_desc).pluck(:iid).first.to_s - expect(json_response['events'].first['iid']).to eq(first_mr_iid) end @@ -54,15 +51,15 @@ RSpec.describe 'value stream analytics events' do get project_cycle_analytics_test_path(project, format: :json) expect(json_response['events']).not_to be_empty - expect(json_response['events'].first['date']).not_to be_empty + + expect(json_response['events'].first['iid']).to eq(first_mr_iid) end it 'lists the review events' do get project_cycle_analytics_review_path(project, format: :json) - first_mr_iid = project.merge_requests.sort_by_attribute(:created_desc).pluck(:iid).first.to_s - expect(json_response['events']).not_to be_empty + expect(json_response['events'].first['iid']).to eq(first_mr_iid) end @@ -70,7 +67,8 @@ RSpec.describe 'value stream analytics events' do get project_cycle_analytics_staging_path(project, format: :json) expect(json_response['events']).not_to be_empty - expect(json_response['events'].first['date']).not_to be_empty + + expect(json_response['events'].first['iid']).to eq(first_issue_iid) end context 'with private project and builds' do diff --git a/spec/requests/projects/merge_requests/diffs_spec.rb b/spec/requests/projects/merge_requests/diffs_spec.rb index 3a64c88acc1..349cbf1b76c 100644 --- a/spec/requests/projects/merge_requests/diffs_spec.rb +++ b/spec/requests/projects/merge_requests/diffs_spec.rb @@ -33,6 +33,7 @@ RSpec.describe 'Merge Requests Diffs' do merge_request: merge_request, diff_view: :inline, merge_ref_head_diff: nil, + allow_tree_conflicts: true, pagination_data: { total_pages: nil }.merge(pagination_data) @@ -75,6 +76,78 @@ RSpec.describe 'Merge Requests Diffs' do subject end + context 'with the different user' do + let(:another_user) { create(:user) } + + before do + project.add_maintainer(another_user) + sign_in(another_user) + end + + it_behaves_like 'serializes diffs with expected arguments' do + let(:collection) { Gitlab::Diff::FileCollection::MergeRequestDiffBatch } + let(:expected_options) { collection_arguments(total_pages: 20) } + end + end + + context 'with a new unfoldable diff position' do + let(:unfoldable_position) do + create(:diff_position) + end + + before do + expect_next_instance_of(Gitlab::Diff::PositionCollection) do |instance| + expect(instance) + .to receive(:unfoldable) + .and_return([unfoldable_position]) + end + end + + it_behaves_like 'serializes diffs with expected arguments' do + let(:collection) { Gitlab::Diff::FileCollection::MergeRequestDiffBatch } + let(:expected_options) { collection_arguments(total_pages: 20) } + end + end + + context 'with a new environment' do + let(:environment) do + create(:environment, :available, project: project) + end + + let!(:deployment) do + create(:deployment, :success, environment: environment, ref: merge_request.source_branch) + end + + it_behaves_like 'serializes diffs with expected arguments' do + let(:collection) { Gitlab::Diff::FileCollection::MergeRequestDiffBatch } + let(:expected_options) { collection_arguments(total_pages: 20).merge(environment: environment) } + end + end + + context 'with disabled display_merge_conflicts_in_diff feature' do + before do + stub_feature_flags(display_merge_conflicts_in_diff: false) + end + + it_behaves_like 'serializes diffs with expected arguments' do + let(:collection) { Gitlab::Diff::FileCollection::MergeRequestDiffBatch } + let(:expected_options) { collection_arguments(total_pages: 20).merge(allow_tree_conflicts: false) } + end + end + + context 'with diff_head option' do + subject { go(page: 0, per_page: 5, diff_head: true) } + + before do + merge_request.create_merge_head_diff! + end + + it_behaves_like 'serializes diffs with expected arguments' do + let(:collection) { Gitlab::Diff::FileCollection::MergeRequestDiffBatch } + let(:expected_options) { collection_arguments(total_pages: 20).merge(merge_ref_head_diff: true) } + end + end + context 'with the different pagination option' do subject { go(page: 5, per_page: 5) } diff --git a/spec/requests/projects/merge_requests_discussions_spec.rb b/spec/requests/projects/merge_requests_discussions_spec.rb index 595222a9eb2..c68745b9271 100644 --- a/spec/requests/projects/merge_requests_discussions_spec.rb +++ b/spec/requests/projects/merge_requests_discussions_spec.rb @@ -54,7 +54,9 @@ RSpec.describe 'merge requests discussions' do end context 'caching', :use_clean_rails_memory_store_caching do - let!(:first_note) { create(:diff_note_on_merge_request, noteable: merge_request, project: project) } + let(:reference) { create(:issue, project: project) } + let(:author) { create(:user) } + let!(:first_note) { create(:diff_note_on_merge_request, author: author, noteable: merge_request, project: project, note: "reference: #{reference.to_reference}") } let!(:second_note) { create(:diff_note_on_merge_request, in_reply_to: first_note, noteable: merge_request, project: project) } let!(:award_emoji) { create(:award_emoji, awardable: first_note) } @@ -93,6 +95,16 @@ RSpec.describe 'merge requests discussions' do end end + context 'when a note in a discussion got its reference state updated' do + before do + reference.close! + end + + it_behaves_like 'cache miss' do + let(:changed_notes) { [first_note, second_note] } + end + end + context 'when a note in a discussion got resolved' do before do travel_to(1.minute.from_now) do @@ -147,17 +159,6 @@ RSpec.describe 'merge requests discussions' do end end - context 'when cached markdown version gets bump' do - before do - settings = Gitlab::CurrentSettings.current_application_settings - settings.update!(local_markdown_version: settings.local_markdown_version + 1) - end - - it_behaves_like 'cache miss' do - let(:changed_notes) { [first_note, second_note] } - end - end - context 'when the diff note position changes' do before do # This replicates a position change wherein timestamps aren't updated @@ -181,6 +182,53 @@ RSpec.describe 'merge requests discussions' do end end + context 'when the HEAD diff note position changes' do + before do + # This replicates a DiffNotePosition change. This is the same approach + # being used in Discussions::CaptureDiffNotePositionService which is + # responsible for updating/creating DiffNotePosition of a diff discussions + # in relation to HEAD diff. + new_position = Gitlab::Diff::Position.new( + old_path: first_note.position.old_path, + new_path: first_note.position.new_path, + old_line: first_note.position.old_line, + new_line: first_note.position.new_line + 1, + diff_refs: first_note.position.diff_refs + ) + + DiffNotePosition.create_or_update_for( + first_note, + diff_type: :head, + position: new_position, + line_code: 'bd4b7bfff3a247ccf6e3371c41ec018a55230bcc_534_521' + ) + end + + it_behaves_like 'cache miss' do + let(:changed_notes) { [first_note, second_note] } + end + end + + context 'when author detail changes' do + before do + author.update!(name: "#{author.name} (Updated)") + end + + it_behaves_like 'cache miss' do + let(:changed_notes) { [first_note, second_note] } + end + end + + context 'when author status changes' do + before do + Users::SetStatusService.new(author, message: "updated status").execute + end + + it_behaves_like 'cache miss' do + let(:changed_notes) { [first_note, second_note] } + end + end + context 'when merge_request_discussion_cache is disabled' do before do stub_feature_flags(merge_request_discussion_cache: false) diff --git a/spec/requests/projects/merge_requests_spec.rb b/spec/requests/projects/merge_requests_spec.rb new file mode 100644 index 00000000000..59fde803560 --- /dev/null +++ b/spec/requests/projects/merge_requests_spec.rb @@ -0,0 +1,159 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe 'merge requests actions' do + let_it_be(:project) { create(:project, :repository) } + + let(:merge_request) do + create(:merge_request_with_diffs, target_project: project, + source_project: project, + assignees: [user], + reviewers: [user2]) + end + + let(:user) { project.owner } + let(:user2) { create(:user) } + + before do + project.add_maintainer(user2) + sign_in(user) + end + + describe 'GET /:namespace/:project/-/merge_requests/:iid' do + describe 'as json' do + def send_request(extra_params = {}) + params = { + namespace_id: project.namespace.to_param, + project_id: project, + id: merge_request.iid, + format: :json + } + + get namespace_project_merge_request_path(params.merge(extra_params)) + end + + context 'with caching', :use_clean_rails_memory_store_caching do + let(:params) { {} } + + context 'for sidebar_extras' do + let(:params) { { serializer: 'sidebar_extras' } } + + shared_examples_for 'a non-cached request' do + it 'serializes merge request' do + expect_next_instance_of(MergeRequestSerializer) do |instance| + expect(instance).to receive(:represent) + .with(an_instance_of(MergeRequest), serializer: 'sidebar_extras') + .and_call_original + end + + send_request(params) + end + end + + context 'when the request has not been cached' do + it_behaves_like 'a non-cached request' + end + + context 'when the request has already been cached' do + before do + send_request(params) + end + + it 'does not serialize merge request again' do + expect_next_instance_of(MergeRequestSerializer) do |instance| + expect(instance).not_to receive(:represent) + end + + send_request(params) + end + + context 'when the merge request is updated' do + def update_service(params) + MergeRequests::UpdateService.new(project: project, current_user: user, params: params).execute(merge_request) + end + + context 'when the logged in user is different' do + before do + sign_in(user2) + end + + it_behaves_like 'a non-cached request' + end + + context 'when the assignee is changed' do + before do + update_service( assignee_ids: [] ) + end + + it_behaves_like 'a non-cached request' + end + + context 'when the existing assignee gets updated' do + before do + user.update_attribute(:avatar, 'uploads/avatar.png') + end + + it_behaves_like 'a non-cached request' + end + + context 'when the reviewer is changed' do + before do + update_service(reviewer_ids: []) + end + + it_behaves_like 'a non-cached request' + end + + context 'when the existing reviewer gets updated' do + before do + user2.update_attribute(:avatar, 'uploads/avatar.png') + end + + it_behaves_like 'a non-cached request' + end + + context 'when the time_estimate is changed' do + before do + update_service(time_estimate: 7200) + end + + it_behaves_like 'a non-cached request' + end + + context 'when the spend_time is changed' do + before do + update_service(spend_time: { duration: 7200, user_id: user.id, spent_at: Time.now, note_id: nil }) + end + + it_behaves_like 'a non-cached request' + end + + context 'when a user leaves a note' do + before do + # We have 1 minute ThrottledTouch to account for. + # It's not ideal as it means that our participants cache could be stale for about a day if a new note is created by another person or gets a mention. + travel_to(Time.current + 61) do + Notes::CreateService.new(project, user2, { note: 'Looks good', noteable_type: 'MergeRequest', noteable_id: merge_request.id }).execute + end + end + + it_behaves_like 'a non-cached request' + end + end + end + end + + context 'for other serializer' do + let(:params) { { serializer: 'basic' } } + + it 'does not use cache' do + expect(Rails.cache).not_to receive(:fetch).with(/cache:gitlab:MergeRequestSerializer:/).and_call_original + + send_request(params) + end + end + end + end + end +end |