diff options
Diffstat (limited to 'spec/support/shared_examples/services')
8 files changed, 248 insertions, 17 deletions
diff --git a/spec/support/shared_examples/services/boards/lists_destroy_service_shared_examples.rb b/spec/support/shared_examples/services/boards/lists_destroy_service_shared_examples.rb index 6a4f284ec54..94da405e491 100644 --- a/spec/support/shared_examples/services/boards/lists_destroy_service_shared_examples.rb +++ b/spec/support/shared_examples/services/boards/lists_destroy_service_shared_examples.rb @@ -13,7 +13,7 @@ RSpec.shared_examples 'lists destroy service' do development = create(:list, board: board, position: 0) review = create(:list, board: board, position: 1) staging = create(:list, board: board, position: 2) - closed = board.closed_list + closed = board.lists.closed.first described_class.new(parent, user).execute(development) @@ -24,7 +24,7 @@ RSpec.shared_examples 'lists destroy service' do end it 'does not remove list from board when list type is closed' do - list = board.closed_list + list = board.lists.closed.first service = described_class.new(parent, user) expect { service.execute(list) }.not_to change(board.lists, :count) diff --git a/spec/support/shared_examples/services/boards/lists_list_service_shared_examples.rb b/spec/support/shared_examples/services/boards/lists_list_service_shared_examples.rb index 41fd286682e..e1143562661 100644 --- a/spec/support/shared_examples/services/boards/lists_list_service_shared_examples.rb +++ b/spec/support/shared_examples/services/boards/lists_list_service_shared_examples.rb @@ -2,14 +2,34 @@ RSpec.shared_examples 'lists list service' do context 'when the board has a backlog list' do - let!(:backlog_list) { create(:backlog_list, board: board) } + let!(:backlog_list) { create_backlog_list(board) } it 'does not create a backlog list' do expect { service.execute(board) }.not_to change(board.lists, :count) end it "returns board's lists" do - expect(service.execute(board)).to eq [backlog_list, list, board.closed_list] + expect(service.execute(board)).to eq [backlog_list, list, board.lists.closed.first] + end + + context 'when hide_backlog_list is true' do + before do + board.update_column(:hide_backlog_list, true) + end + + it 'hides backlog list' do + expect(service.execute(board)).to match_array([board.lists.closed.first, list]) + end + end + + context 'when hide_closed_list is true' do + before do + board.update_column(:hide_closed_list, true) + end + + it 'hides closed list' do + expect(service.execute(board)).to match_array([backlog_list, list]) + end end end @@ -23,25 +43,21 @@ RSpec.shared_examples 'lists list service' do end it "returns board's lists" do - expect(service.execute(board)).to eq [board.backlog_list, list, board.closed_list] + expect(service.execute(board)).to eq [board.lists.backlog.first, list, board.lists.closed.first] end end context 'when wanting a specific list' do - let!(:list1) { create(:list, board: board) } - it 'returns list specified by id' do - service = described_class.new(parent, user, list_id: list1.id) + service = described_class.new(parent, user, list_id: list.id) - expect(service.execute(board, create_default_lists: false)).to eq [list1] + expect(service.execute(board, create_default_lists: false)).to eq [list] end it 'returns empty result when list is not found' do - external_board = create(:board, resource_parent: create(:project)) - external_list = create(:list, board: external_board) - service = described_class.new(parent, user, list_id: external_list.id) + service = described_class.new(parent, user, list_id: unrelated_list.id) - expect(service.execute(board, create_default_lists: false)).to eq(List.none) + expect(service.execute(board, create_default_lists: false)).to be_empty end end end diff --git a/spec/support/shared_examples/services/clusters/parse_cluster_applications_artifact_shared_examples.rb b/spec/support/shared_examples/services/clusters/parse_cluster_applications_artifact_shared_examples.rb index cbe20928f98..466300017d9 100644 --- a/spec/support/shared_examples/services/clusters/parse_cluster_applications_artifact_shared_examples.rb +++ b/spec/support/shared_examples/services/clusters/parse_cluster_applications_artifact_shared_examples.rb @@ -41,7 +41,7 @@ RSpec.shared_examples 'parse cluster applications artifact' do |release_name| end.to change(application_class, :count) expect(cluster_application).to be_persisted - expect(cluster_application).to be_installed + expect(cluster_application).to be_externally_installed end end @@ -53,7 +53,7 @@ RSpec.shared_examples 'parse cluster applications artifact' do |release_name| it 'marks the application as installed' do described_class.new(job, user).execute(artifact) - expect(cluster_application).to be_installed + expect(cluster_application).to be_externally_installed end end end diff --git a/spec/support/shared_examples/services/groups_count_service_shared_examples.rb b/spec/support/shared_examples/services/groups_count_service_shared_examples.rb new file mode 100644 index 00000000000..84937c3d4d7 --- /dev/null +++ b/spec/support/shared_examples/services/groups_count_service_shared_examples.rb @@ -0,0 +1,55 @@ +# frozen_string_literal: true + +# The calling spec should use `:use_clean_rails_memory_store_caching` +# when including this shared example. E.g.: +# +# describe MyCountService, :use_clean_rails_memory_store_caching do +# it_behaves_like 'a counter caching service with threshold' +# end +RSpec.shared_examples 'a counter caching service with threshold' do + let(:cache_key) { subject.cache_key } + let(:under_threshold) { described_class::CACHED_COUNT_THRESHOLD - 1 } + let(:over_threshold) { described_class::CACHED_COUNT_THRESHOLD + 1 } + + context 'when cache is empty' do + before do + Rails.cache.delete(cache_key) + end + + it 'refreshes cache if value over threshold' do + allow(subject).to receive(:uncached_count).and_return(over_threshold) + + expect(subject.count).to eq(over_threshold) + expect(Rails.cache.read(cache_key)).to eq(over_threshold) + end + + it 'does not refresh cache if value under threshold' do + allow(subject).to receive(:uncached_count).and_return(under_threshold) + + expect(subject.count).to eq(under_threshold) + expect(Rails.cache.read(cache_key)).to be_nil + end + end + + context 'when cached count is under the threshold value' do + before do + Rails.cache.write(cache_key, under_threshold) + end + + it 'does not refresh cache' do + expect(Rails.cache).not_to receive(:write) + expect(subject.count).to eq(under_threshold) + end + end + + context 'when cached count is over the threshold value' do + before do + Rails.cache.write(cache_key, over_threshold) + end + + it 'does not refresh cache' do + expect(Rails.cache).not_to receive(:write) + expect(subject.count).to eq(over_threshold) + end + end +end diff --git a/spec/support/shared_examples/services/issuable/destroy_service_shared_examples.rb b/spec/support/shared_examples/services/issuable/destroy_service_shared_examples.rb new file mode 100644 index 00000000000..ccc287c10de --- /dev/null +++ b/spec/support/shared_examples/services/issuable/destroy_service_shared_examples.rb @@ -0,0 +1,31 @@ +# frozen_string_literal: true + +shared_examples_for 'service deleting todos' do + before do + stub_feature_flags(destroy_issuable_todos_async: group) + end + + it 'destroys associated todos asynchronously' do + expect(TodosDestroyer::DestroyedIssuableWorker) + .to receive(:perform_async) + .with(issuable.id, issuable.class.name) + + subject.execute(issuable) + end + + context 'when destroy_issuable_todos_async feature is disabled for group' do + before do + stub_feature_flags(destroy_issuable_todos_async: false) + end + + it 'destroy associated todos synchronously' do + expect_next_instance_of(TodosDestroyer::DestroyedIssuableWorker) do |worker| + expect(worker) + .to receive(:perform) + .with(issuable.id, issuable.class.name) + end + + subject.execute(issuable) + end + end +end diff --git a/spec/support/shared_examples/services/merge_request_shared_examples.rb b/spec/support/shared_examples/services/merge_request_shared_examples.rb index 56179b6cd00..178b6bc47e1 100644 --- a/spec/support/shared_examples/services/merge_request_shared_examples.rb +++ b/spec/support/shared_examples/services/merge_request_shared_examples.rb @@ -73,3 +73,93 @@ RSpec.shared_examples 'merge request reviewers cache counters invalidator' do described_class.new(project, user, {}).execute(merge_request) end end + +RSpec.shared_examples_for 'a service that can create a merge request' do + subject(:last_mr) { MergeRequest.last } + + it 'creates a merge request with the correct target branch' do + branch = push_options[:target] || project.default_branch + + expect { service.execute }.to change { MergeRequest.count }.by(1) + expect(last_mr.target_branch).to eq(branch) + end + + context 'when project has been forked', :sidekiq_might_not_need_inline do + let(:forked_project) { fork_project(project, user1, repository: true) } + let(:service) { described_class.new(forked_project, user1, changes, push_options) } + + before do + allow(forked_project).to receive(:empty_repo?).and_return(false) + end + + it 'sets the correct source and target project' do + service.execute + + expect(last_mr.source_project).to eq(forked_project) + expect(last_mr.target_project).to eq(project) + end + end +end + +RSpec.shared_examples_for 'a service that does not create a merge request' do + it do + expect { service.execute }.not_to change { MergeRequest.count } + end +end + +# In the non-foss version of GitLab, there can be many assignees, so +# there 'count' can be something other than 0 or 1. In the foss +# version of GitLab, there can be only one assignee though, so 'count' +# can only be 0 or 1. +RSpec.shared_examples_for 'a service that can change assignees of a merge request' do |count| + subject(:last_mr) { MergeRequest.last } + + it 'changes assignee count' do + service.execute + + expect(last_mr.assignees.count).to eq(count) + end +end + +RSpec.shared_examples 'with an existing branch that has a merge request open' do |count| + let(:changes) { existing_branch_changes } + let!(:merge_request) { create(:merge_request, source_project: project, source_branch: source_branch)} + + it_behaves_like 'a service that does not create a merge request' + it_behaves_like 'a service that can change assignees of a merge request', count +end + +RSpec.shared_examples 'when coupled with the `create` push option' do |count| + let(:push_options) { { create: true, assign: assigned, unassign: unassigned } } + + it_behaves_like 'a service that can create a merge request' + it_behaves_like 'a service that can change assignees of a merge request', count +end + +RSpec.shared_examples 'with a new branch' do |count| + let(:changes) { new_branch_changes } + + it_behaves_like 'a service that does not create a merge request' + + it 'adds an error to the service' do + service.execute + + expect(service.errors).to include(error_mr_required) + end + + it_behaves_like 'when coupled with the `create` push option', count +end + +RSpec.shared_examples 'with an existing branch but no open MR' do |count| + let(:changes) { existing_branch_changes } + + it_behaves_like 'a service that does not create a merge request' + + it 'adds an error to the service' do + service.execute + + expect(service.errors).to include(error_mr_required) + end + + it_behaves_like 'when coupled with the `create` push option', count +end diff --git a/spec/support/shared_examples/services/notification_service_shared_examples.rb b/spec/support/shared_examples/services/notification_service_shared_examples.rb index 43fe6789145..cfd674e3c43 100644 --- a/spec/support/shared_examples/services/notification_service_shared_examples.rb +++ b/spec/support/shared_examples/services/notification_service_shared_examples.rb @@ -45,7 +45,7 @@ RSpec.shared_examples 'group emails are disabled' do before do reset_delivered_emails! - target_group.clear_memoization(:emails_disabled) + target_group.clear_memoization(:emails_disabled_memoized) end it 'sends no emails with group emails disabled' do diff --git a/spec/support/shared_examples/services/snippets_shared_examples.rb b/spec/support/shared_examples/services/snippets_shared_examples.rb index 10add3a7299..0c4db7ded69 100644 --- a/spec/support/shared_examples/services/snippets_shared_examples.rb +++ b/spec/support/shared_examples/services/snippets_shared_examples.rb @@ -1,7 +1,8 @@ # frozen_string_literal: true RSpec.shared_examples 'checking spam' do - let(:request) { double(:request) } + let(:request) { double(:request, headers: headers) } + let(:headers) { nil } let(:api) { true } let(:captcha_response) { 'abc123' } let(:spam_log_id) { 1 } @@ -44,6 +45,44 @@ RSpec.shared_examples 'checking spam' do subject end + context 'when CAPTCHA arguments are passed in the headers' do + let(:headers) do + { + 'X-GitLab-Spam-Log-Id' => spam_log_id, + 'X-GitLab-Captcha-Response' => captcha_response + } + end + + let(:extra_opts) do + { + request: request, + api: api, + disable_spam_action_service: disable_spam_action_service + } + end + + it 'executes the SpamActionService correctly' do + spam_params = Spam::SpamParams.new( + api: api, + captcha_response: captcha_response, + spam_log_id: spam_log_id + ) + expect_next_instance_of( + Spam::SpamActionService, + { + spammable: kind_of(Snippet), + request: request, + user: an_instance_of(User), + action: action + } + ) do |instance| + expect(instance).to receive(:execute).with(spam_params: spam_params) + end + + subject + end + end + context 'when spam action service is disabled' do let(:disable_spam_action_service) { true } |