diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2021-07-20 09:55:51 +0000 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2021-07-20 09:55:51 +0000 |
commit | e8d2c2579383897a1dd7f9debd359abe8ae8373d (patch) | |
tree | c42be41678c2586d49a75cabce89322082698334 /spec/requests/projects | |
parent | fc845b37ec3a90aaa719975f607740c22ba6a113 (diff) | |
download | gitlab-ce-e8d2c2579383897a1dd7f9debd359abe8ae8373d.tar.gz |
Add latest changes from gitlab-org/gitlab@14-1-stable-eev14.1.0-rc42
Diffstat (limited to 'spec/requests/projects')
-rw-r--r-- | spec/requests/projects/merge_requests/diffs_spec.rb | 126 | ||||
-rw-r--r-- | spec/requests/projects/merge_requests_discussions_spec.rb | 139 |
2 files changed, 265 insertions, 0 deletions
diff --git a/spec/requests/projects/merge_requests/diffs_spec.rb b/spec/requests/projects/merge_requests/diffs_spec.rb new file mode 100644 index 00000000000..3a64c88acc1 --- /dev/null +++ b/spec/requests/projects/merge_requests/diffs_spec.rb @@ -0,0 +1,126 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe 'Merge Requests Diffs' do + let_it_be(:project) { create(:project, :repository) } + let_it_be(:user) { create(:user) } + let_it_be(:merge_request) { create(:merge_request_with_diffs, target_project: project, source_project: project) } + + before do + project.add_maintainer(user) + sign_in(user) + end + + describe 'GET diffs_batch' do + let(:headers) { {} } + + shared_examples_for 'serializes diffs with expected arguments' do + it 'serializes paginated merge request diff collection' do + expect_next_instance_of(PaginatedDiffSerializer) do |instance| + expect(instance).to receive(:represent) + .with(an_instance_of(collection), expected_options) + .and_call_original + end + + subject + end + end + + def collection_arguments(pagination_data = {}) + { + environment: nil, + merge_request: merge_request, + diff_view: :inline, + merge_ref_head_diff: nil, + pagination_data: { + total_pages: nil + }.merge(pagination_data) + } + end + + def go(extra_params = {}) + params = { + namespace_id: project.namespace.to_param, + project_id: project, + id: merge_request.iid, + page: 0, + per_page: 20, + format: 'json' + } + + get diffs_batch_namespace_project_json_merge_request_path(params.merge(extra_params)), headers: headers + end + + context 'with caching', :use_clean_rails_memory_store_caching do + subject { go(page: 0, per_page: 5) } + + context 'when the request has not been cached' do + 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 'when the request has already been cached' do + before do + go(page: 0, per_page: 5) + end + + it 'does not serialize diffs' do + expect_next_instance_of(PaginatedDiffSerializer) do |instance| + expect(instance).not_to receive(:represent) + end + + subject + end + + context 'with the different pagination option' do + subject { go(page: 5, per_page: 5) } + + 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 the different diff_view' do + subject { go(page: 0, per_page: 5, view: :parallel) } + + it_behaves_like 'serializes diffs with expected arguments' do + let(:collection) { Gitlab::Diff::FileCollection::MergeRequestDiffBatch } + let(:expected_options) { collection_arguments(total_pages: 20).merge(diff_view: :parallel) } + end + end + + context 'with the different expanded option' do + subject { go(page: 0, per_page: 5, expanded: true ) } + + 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 the different ignore_whitespace_change option' do + subject { go(page: 0, per_page: 5, w: 1) } + + it_behaves_like 'serializes diffs with expected arguments' do + let(:collection) { Gitlab::Diff::FileCollection::Compare } + let(:expected_options) { collection_arguments(total_pages: 20) } + end + end + end + + context 'when the paths is given' do + subject { go(page: 0, per_page: 5, paths: %w[README CHANGELOG]) } + + it 'does not use cache' do + expect(Rails.cache).not_to receive(:fetch).with(/cache:gitlab:PaginatedDiffSerializer/).and_call_original + + subject + end + end + end + end +end diff --git a/spec/requests/projects/merge_requests_discussions_spec.rb b/spec/requests/projects/merge_requests_discussions_spec.rb index eb8cf9f797d..595222a9eb2 100644 --- a/spec/requests/projects/merge_requests_discussions_spec.rb +++ b/spec/requests/projects/merge_requests_discussions_spec.rb @@ -52,5 +52,144 @@ RSpec.describe 'merge requests discussions' do expect { send_request } .to change { Gitlab::GitalyClient.get_request_count }.by_at_most(4) 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!(: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) } + + before do + # Make a request to cache the discussions + send_request + end + + shared_examples 'cache miss' do + it 'does not hit a warm cache' do + expect_next_instance_of(DiscussionSerializer) do |serializer| + expect(serializer).to receive(:represent) do |arg| + expect(arg.notes).to contain_exactly(*changed_notes) + end.and_call_original + end + + send_request + end + end + + it 'gets cached on subsequent requests' do + expect_next_instance_of(DiscussionSerializer) do |serializer| + expect(serializer).not_to receive(:represent) + end + + send_request + end + + context 'when a note in a discussion got updated' do + before do + first_note.update!(updated_at: 1.minute.from_now) + 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 + first_note.resolve!(user) + end + end + + it_behaves_like 'cache miss' do + let(:changed_notes) { [first_note, second_note] } + end + end + + context 'when a note is added to a discussion' do + let!(:third_note) { create(:diff_note_on_merge_request, in_reply_to: first_note, noteable: merge_request, project: project) } + + it_behaves_like 'cache miss' do + let(:changed_notes) { [first_note, second_note, third_note] } + end + end + + context 'when a note is removed from a discussion' do + before do + second_note.destroy! + end + + it_behaves_like 'cache miss' do + let(:changed_notes) { [first_note] } + end + end + + context 'when an emoji is awarded to a note in discussion' do + before do + travel_to(1.minute.from_now) do + create(:award_emoji, awardable: first_note) + end + end + + it_behaves_like 'cache miss' do + let(:changed_notes) { [first_note, second_note] } + end + end + + context 'when an award emoji is removed from a note in discussion' do + before do + travel_to(1.minute.from_now) do + award_emoji.destroy! + end + end + + it_behaves_like 'cache miss' do + let(:changed_notes) { [first_note, second_note] } + 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 + # which is why `Gitlab::Timeless.timeless` is utilized. This is the + # same approach being used in Discussions::UpdateDiffPositionService + # which is responsible for updating the positions of diff discussions + # when MR updates. + first_note.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 + ) + + Gitlab::Timeless.timeless(first_note, &:save) + 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) + end + + it_behaves_like 'cache miss' do + let(:changed_notes) { [first_note, second_note] } + end + end + end end end |