summaryrefslogtreecommitdiff
path: root/spec/support/shared_examples/services
diff options
context:
space:
mode:
Diffstat (limited to 'spec/support/shared_examples/services')
-rw-r--r--spec/support/shared_examples/services/boards/lists_list_service_shared_examples.rb4
-rw-r--r--spec/support/shared_examples/services/measurable_service_shared_examples.rb32
-rw-r--r--spec/support/shared_examples/services/metrics/dashboard_shared_examples.rb4
-rw-r--r--spec/support/shared_examples/services/projects/update_repository_storage_service_shared_examples.rb26
-rw-r--r--spec/support/shared_examples/services/resource_events/change_milestone_service_shared_examples.rb7
-rw-r--r--spec/support/shared_examples/services/snippets_shared_examples.rb42
-rw-r--r--spec/support/shared_examples/services/wiki_pages/create_service_shared_examples.rb94
-rw-r--r--spec/support/shared_examples/services/wiki_pages/destroy_service_shared_examples.rb50
-rw-r--r--spec/support/shared_examples/services/wiki_pages/update_service_shared_examples.rb98
-rw-r--r--spec/support/shared_examples/services/wikis/create_attachment_service_shared_examples.rb62
10 files changed, 403 insertions, 16 deletions
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 1b7fe626aea..07a6353296d 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
@@ -18,6 +18,10 @@ RSpec.shared_examples 'lists list service' do
expect { service.execute(board) }.to change(board.lists, :count).by(1)
end
+ it 'does not create a backlog list when create_default_lists is false' do
+ expect { service.execute(board, create_default_lists: false) }.not_to change(board.lists, :count)
+ end
+
it "returns board's lists" do
expect(service.execute(board)).to eq [board.backlog_list, list, board.closed_list]
end
diff --git a/spec/support/shared_examples/services/measurable_service_shared_examples.rb b/spec/support/shared_examples/services/measurable_service_shared_examples.rb
new file mode 100644
index 00000000000..206c25e49af
--- /dev/null
+++ b/spec/support/shared_examples/services/measurable_service_shared_examples.rb
@@ -0,0 +1,32 @@
+# frozen_string_literal: true
+
+RSpec.shared_examples 'measurable service' do
+ context 'when measurement is enabled' do
+ let!(:measuring) { Gitlab::Utils::Measuring.new(base_log_data) }
+
+ before do
+ stub_feature_flags(feature_flag => true)
+ end
+
+ it 'measure service execution with Gitlab::Utils::Measuring', :aggregate_failures do
+ expect(Gitlab::Utils::Measuring).to receive(:new).with(base_log_data).and_return(measuring)
+ expect(measuring).to receive(:with_measuring).and_call_original
+ end
+ end
+
+ context 'when measurement is disabled' do
+ it 'does not measure service execution' do
+ stub_feature_flags(feature_flag => false)
+
+ expect(Gitlab::Utils::Measuring).not_to receive(:new)
+ end
+ end
+
+ def feature_flag
+ "gitlab_service_measuring_#{described_class_name}"
+ end
+
+ def described_class_name
+ described_class.name.underscore.tr('/', '_')
+ end
+end
diff --git a/spec/support/shared_examples/services/metrics/dashboard_shared_examples.rb b/spec/support/shared_examples/services/metrics/dashboard_shared_examples.rb
index 90fcac0e55c..5dd1badbefc 100644
--- a/spec/support/shared_examples/services/metrics/dashboard_shared_examples.rb
+++ b/spec/support/shared_examples/services/metrics/dashboard_shared_examples.rb
@@ -23,7 +23,7 @@ RSpec.shared_examples 'valid dashboard service response for schema' do
end
RSpec.shared_examples 'valid dashboard service response' do
- let(:dashboard_schema) { JSON.parse(fixture_file('lib/gitlab/metrics/dashboard/schemas/dashboard.json')) }
+ let(:dashboard_schema) { Gitlab::Json.parse(fixture_file('lib/gitlab/metrics/dashboard/schemas/dashboard.json')) }
it_behaves_like 'valid dashboard service response for schema'
end
@@ -38,7 +38,7 @@ RSpec.shared_examples 'caches the unprocessed dashboard for subsequent calls' do
end
RSpec.shared_examples 'valid embedded dashboard service response' do
- let(:dashboard_schema) { JSON.parse(fixture_file('lib/gitlab/metrics/dashboard/schemas/embedded_dashboard.json')) }
+ let(:dashboard_schema) { Gitlab::Json.parse(fixture_file('lib/gitlab/metrics/dashboard/schemas/embedded_dashboard.json')) }
it_behaves_like 'valid dashboard service response for schema'
end
diff --git a/spec/support/shared_examples/services/projects/update_repository_storage_service_shared_examples.rb b/spec/support/shared_examples/services/projects/update_repository_storage_service_shared_examples.rb
index d6166ac8188..0e6ecf49cd0 100644
--- a/spec/support/shared_examples/services/projects/update_repository_storage_service_shared_examples.rb
+++ b/spec/support/shared_examples/services/projects/update_repository_storage_service_shared_examples.rb
@@ -47,9 +47,9 @@ RSpec.shared_examples 'moves repository to another storage' do |repository_type|
old_repository_path = repository.full_path
- result = subject.execute('test_second_storage')
+ result = subject.execute
- expect(result[:status]).to eq(:success)
+ expect(result).to be_success
expect(project).not_to be_repository_read_only
expect(project.repository_storage).to eq('test_second_storage')
expect(gitlab_shell.repository_exists?('default', old_project_repository_path)).to be(false)
@@ -62,7 +62,7 @@ RSpec.shared_examples 'moves repository to another storage' do |repository_type|
end
it 'does not enqueue a GC run' do
- expect { subject.execute('test_second_storage') }
+ expect { subject.execute }
.not_to change(GitGarbageCollectWorker.jobs, :count)
end
end
@@ -75,23 +75,25 @@ RSpec.shared_examples 'moves repository to another storage' do |repository_type|
it 'does not enqueue a GC run if housekeeping is disabled' do
stub_application_setting(housekeeping_enabled: false)
- expect { subject.execute('test_second_storage') }
+ expect { subject.execute }
.not_to change(GitGarbageCollectWorker.jobs, :count)
end
it 'enqueues a GC run' do
- expect { subject.execute('test_second_storage') }
+ expect { subject.execute }
.to change(GitGarbageCollectWorker.jobs, :count).by(1)
end
end
end
context 'when the filesystems are the same' do
+ let(:destination) { project.repository_storage }
+
it 'bails out and does nothing' do
- result = subject.execute(project.repository_storage)
+ result = subject.execute
- expect(result[:status]).to eq(:error)
- expect(result[:message]).to match(/SameFilesystemError/)
+ expect(result).to be_error
+ expect(result.message).to match(/SameFilesystemError/)
end
end
@@ -114,9 +116,9 @@ RSpec.shared_examples 'moves repository to another storage' do |repository_type|
expect(GitlabShellWorker).not_to receive(:perform_async)
- result = subject.execute('test_second_storage')
+ result = subject.execute
- expect(result[:status]).to eq(:error)
+ expect(result).to be_error
expect(project).not_to be_repository_read_only
expect(project.repository_storage).to eq('default')
end
@@ -142,9 +144,9 @@ RSpec.shared_examples 'moves repository to another storage' do |repository_type|
expect(GitlabShellWorker).not_to receive(:perform_async)
- result = subject.execute('test_second_storage')
+ result = subject.execute
- expect(result[:status]).to eq(:error)
+ expect(result).to be_error
expect(project).not_to be_repository_read_only
expect(project.repository_storage).to eq('default')
end
diff --git a/spec/support/shared_examples/services/resource_events/change_milestone_service_shared_examples.rb b/spec/support/shared_examples/services/resource_events/change_milestone_service_shared_examples.rb
index 77f64e5e8f8..c5f84e205cf 100644
--- a/spec/support/shared_examples/services/resource_events/change_milestone_service_shared_examples.rb
+++ b/spec/support/shared_examples/services/resource_events/change_milestone_service_shared_examples.rb
@@ -4,7 +4,7 @@ shared_examples 'a milestone events creator' do
let_it_be(:user) { create(:user) }
let(:created_at_time) { Time.utc(2019, 12, 30) }
- let(:service) { described_class.new(resource, user, created_at: created_at_time) }
+ let(:service) { described_class.new(resource, user, created_at: created_at_time, old_milestone: nil) }
context 'when milestone is present' do
let_it_be(:milestone) { create(:milestone) }
@@ -25,10 +25,13 @@ shared_examples 'a milestone events creator' do
resource.milestone = nil
end
+ let(:old_milestone) { create(:milestone, project: resource.project) }
+ let(:service) { described_class.new(resource, user, created_at: created_at_time, old_milestone: old_milestone) }
+
it 'creates the expected event records' do
expect { service.execute }.to change { ResourceMilestoneEvent.count }.by(1)
- expect_event_record(ResourceMilestoneEvent.last, action: 'remove', milestone: nil, state: 'opened')
+ expect_event_record(ResourceMilestoneEvent.last, action: 'remove', milestone: old_milestone, state: 'opened')
end
end
diff --git a/spec/support/shared_examples/services/snippets_shared_examples.rb b/spec/support/shared_examples/services/snippets_shared_examples.rb
new file mode 100644
index 00000000000..51a4a8b1cd9
--- /dev/null
+++ b/spec/support/shared_examples/services/snippets_shared_examples.rb
@@ -0,0 +1,42 @@
+# frozen_string_literal: true
+
+RSpec.shared_examples 'snippets spam check is performed' do
+ shared_examples 'marked as spam' do
+ it 'marks a snippet as spam' do
+ expect(snippet).to be_spam
+ end
+
+ it 'invalidates the snippet' do
+ expect(snippet).to be_invalid
+ end
+
+ it 'creates a new spam_log' do
+ expect { snippet }
+ .to have_spam_log(title: snippet.title, noteable_type: snippet.class.name)
+ end
+
+ it 'assigns a spam_log to an issue' do
+ expect(snippet.spam_log).to eq(SpamLog.last)
+ end
+ end
+
+ let(:extra_opts) do
+ { visibility_level: Gitlab::VisibilityLevel::PUBLIC, request: double(:request, env: {}) }
+ end
+
+ before do
+ expect_next_instance_of(Spam::AkismetService) do |akismet_service|
+ expect(akismet_service).to receive_messages(spam?: true)
+ end
+ end
+
+ [true, false, nil].each do |allow_possible_spam|
+ context "when allow_possible_spam flag is #{allow_possible_spam.inspect}" do
+ before do
+ stub_feature_flags(allow_possible_spam: allow_possible_spam) unless allow_possible_spam.nil?
+ end
+
+ it_behaves_like 'marked as spam'
+ end
+ end
+end
diff --git a/spec/support/shared_examples/services/wiki_pages/create_service_shared_examples.rb b/spec/support/shared_examples/services/wiki_pages/create_service_shared_examples.rb
new file mode 100644
index 00000000000..71bdd46572f
--- /dev/null
+++ b/spec/support/shared_examples/services/wiki_pages/create_service_shared_examples.rb
@@ -0,0 +1,94 @@
+# frozen_string_literal: true
+
+RSpec.shared_examples 'WikiPages::CreateService#execute' do |container_type|
+ let(:container) { create(container_type, :wiki_repo) }
+ let(:user) { create(:user) }
+ let(:page_title) { 'Title' }
+
+ let(:opts) do
+ {
+ title: page_title,
+ content: 'Content for wiki page',
+ format: 'markdown'
+ }
+ end
+
+ subject(:service) { described_class.new(container: container, current_user: user, params: opts) }
+
+ it 'creates wiki page with valid attributes' do
+ page = service.execute
+
+ expect(page).to be_valid
+ expect(page).to be_persisted
+ expect(page.title).to eq(opts[:title])
+ expect(page.content).to eq(opts[:content])
+ expect(page.format).to eq(opts[:format].to_sym)
+ end
+
+ it 'executes webhooks' do
+ expect(service).to receive(:execute_hooks).once.with(WikiPage)
+
+ service.execute
+ end
+
+ it 'counts wiki page creation' do
+ counter = Gitlab::UsageDataCounters::WikiPageCounter
+
+ expect { service.execute }.to change { counter.read(:create) }.by 1
+ end
+
+ shared_examples 'correct event created' do
+ it 'creates appropriate events' do
+ # TODO: https://gitlab.com/gitlab-org/gitlab/-/issues/216904
+ pending('group wiki support') if container_type == :group
+
+ expect { service.execute }.to change { Event.count }.by 1
+
+ expect(Event.recent.first).to have_attributes(
+ action: Event::CREATED,
+ target: have_attributes(canonical_slug: page_title)
+ )
+ end
+ end
+
+ context 'the new page is at the top level' do
+ let(:page_title) { 'root-level-page' }
+
+ include_examples 'correct event created'
+ end
+
+ context 'the new page is in a subsection' do
+ let(:page_title) { 'subsection/page' }
+
+ include_examples 'correct event created'
+ end
+
+ context 'the feature is disabled' do
+ before do
+ stub_feature_flags(wiki_events: false)
+ end
+
+ it 'does not record the activity' do
+ expect { service.execute }.not_to change(Event, :count)
+ end
+ end
+
+ context 'when the options are bad' do
+ let(:page_title) { '' }
+
+ it 'does not count a creation event' do
+ counter = Gitlab::UsageDataCounters::WikiPageCounter
+
+ expect { service.execute }.not_to change { counter.read(:create) }
+ end
+
+ it 'does not record the activity' do
+ expect { service.execute }.not_to change(Event, :count)
+ end
+
+ it 'reports the error' do
+ expect(service.execute).to be_invalid
+ .and have_attributes(errors: be_present)
+ end
+ end
+end
diff --git a/spec/support/shared_examples/services/wiki_pages/destroy_service_shared_examples.rb b/spec/support/shared_examples/services/wiki_pages/destroy_service_shared_examples.rb
new file mode 100644
index 00000000000..62541eb3da9
--- /dev/null
+++ b/spec/support/shared_examples/services/wiki_pages/destroy_service_shared_examples.rb
@@ -0,0 +1,50 @@
+# frozen_string_literal: true
+
+RSpec.shared_examples 'WikiPages::DestroyService#execute' do |container_type|
+ let(:container) { create(container_type) }
+
+ let(:user) { create(:user) }
+ let(:page) { create(:wiki_page) }
+
+ subject(:service) { described_class.new(container: container, current_user: user) }
+
+ it 'executes webhooks' do
+ expect(service).to receive(:execute_hooks).once.with(page)
+
+ service.execute(page)
+ end
+
+ it 'increments the delete count' do
+ counter = Gitlab::UsageDataCounters::WikiPageCounter
+
+ expect { service.execute(page) }.to change { counter.read(:delete) }.by 1
+ end
+
+ it 'creates a new wiki page deletion event' do
+ # TODO: https://gitlab.com/gitlab-org/gitlab/-/issues/216904
+ pending('group wiki support') if container_type == :group
+
+ expect { service.execute(page) }.to change { Event.count }.by 1
+
+ expect(Event.recent.first).to have_attributes(
+ action: Event::DESTROYED,
+ target: have_attributes(canonical_slug: page.slug)
+ )
+ end
+
+ it 'does not increment the delete count if the deletion failed' do
+ counter = Gitlab::UsageDataCounters::WikiPageCounter
+
+ expect { service.execute(nil) }.not_to change { counter.read(:delete) }
+ end
+
+ context 'the feature is disabled' do
+ before do
+ stub_feature_flags(wiki_events: false)
+ end
+
+ it 'does not record the activity' do
+ expect { service.execute(page) }.not_to change(Event, :count)
+ end
+ end
+end
diff --git a/spec/support/shared_examples/services/wiki_pages/update_service_shared_examples.rb b/spec/support/shared_examples/services/wiki_pages/update_service_shared_examples.rb
new file mode 100644
index 00000000000..0dfc99d043b
--- /dev/null
+++ b/spec/support/shared_examples/services/wiki_pages/update_service_shared_examples.rb
@@ -0,0 +1,98 @@
+# frozen_string_literal: true
+
+RSpec.shared_examples 'WikiPages::UpdateService#execute' do |container_type|
+ let(:container) { create(container_type, :wiki_repo) }
+
+ let(:user) { create(:user) }
+ let(:page) { create(:wiki_page) }
+ let(:page_title) { 'New Title' }
+
+ let(:opts) do
+ {
+ content: 'New content for wiki page',
+ format: 'markdown',
+ message: 'New wiki message',
+ title: page_title
+ }
+ end
+
+ subject(:service) { described_class.new(container: container, current_user: user, params: opts) }
+
+ it 'updates the wiki page' do
+ updated_page = service.execute(page)
+
+ expect(updated_page).to be_valid
+ expect(updated_page.message).to eq(opts[:message])
+ expect(updated_page.content).to eq(opts[:content])
+ expect(updated_page.format).to eq(opts[:format].to_sym)
+ expect(updated_page.title).to eq(page_title)
+ end
+
+ it 'executes webhooks' do
+ expect(service).to receive(:execute_hooks).once.with(WikiPage)
+
+ service.execute(page)
+ end
+
+ it 'counts edit events' do
+ counter = Gitlab::UsageDataCounters::WikiPageCounter
+
+ expect { service.execute page }.to change { counter.read(:update) }.by 1
+ end
+
+ shared_examples 'adds activity event' do
+ it 'adds a new wiki page activity event' do
+ # TODO: https://gitlab.com/gitlab-org/gitlab/-/issues/216904
+ pending('group wiki support') if container_type == :group
+
+ expect { service.execute(page) }.to change { Event.count }.by 1
+
+ expect(Event.recent.first).to have_attributes(
+ action: Event::UPDATED,
+ wiki_page: page,
+ target_title: page.title
+ )
+ end
+ end
+
+ context 'the page is at the top level' do
+ let(:page_title) { 'Top level page' }
+
+ include_examples 'adds activity event'
+ end
+
+ context 'the page is in a subsection' do
+ let(:page_title) { 'Subsection / secondary page' }
+
+ include_examples 'adds activity event'
+ end
+
+ context 'the feature is disabled' do
+ before do
+ stub_feature_flags(wiki_events: false)
+ end
+
+ it 'does not record the activity' do
+ expect { service.execute(page) }.not_to change(Event, :count)
+ end
+ end
+
+ context 'when the options are bad' do
+ let(:page_title) { '' }
+
+ it 'does not count an edit event' do
+ counter = Gitlab::UsageDataCounters::WikiPageCounter
+
+ expect { service.execute page }.not_to change { counter.read(:update) }
+ end
+
+ it 'does not record the activity' do
+ expect { service.execute page }.not_to change(Event, :count)
+ end
+
+ it 'reports the error' do
+ expect(service.execute(page)).to be_invalid
+ .and have_attributes(errors: be_present)
+ end
+ end
+end
diff --git a/spec/support/shared_examples/services/wikis/create_attachment_service_shared_examples.rb b/spec/support/shared_examples/services/wikis/create_attachment_service_shared_examples.rb
new file mode 100644
index 00000000000..541e332e3a1
--- /dev/null
+++ b/spec/support/shared_examples/services/wikis/create_attachment_service_shared_examples.rb
@@ -0,0 +1,62 @@
+# frozen_string_literal: true
+
+RSpec.shared_examples 'Wikis::CreateAttachmentService#execute' do |container_type|
+ let(:container) { create(container_type, :wiki_repo) }
+ let(:wiki) { container.wiki }
+
+ let(:user) { create(:user) }
+ let(:file_name) { 'filename.txt' }
+ let(:file_path_regex) { %r{#{described_class::ATTACHMENT_PATH}/\h{32}/#{file_name}} }
+
+ let(:file_opts) do
+ {
+ file_name: file_name,
+ file_content: 'Content of attachment'
+ }
+ end
+ let(:opts) { file_opts }
+
+ let(:service) { Wikis::CreateAttachmentService.new(container: container, current_user: user, params: opts) }
+
+ subject(:service_execute) { service.execute[:result] }
+
+ before do
+ container.add_developer(user)
+ end
+
+ context 'creates branch if it does not exists' do
+ let(:branch_name) { 'new_branch' }
+ let(:opts) { file_opts.merge(branch_name: branch_name) }
+
+ it do
+ expect(wiki.repository.branches).to be_empty
+ expect { service.execute }.to change { wiki.repository.branches.count }.by(1)
+ expect(wiki.repository.branches.first.name).to eq branch_name
+ end
+ end
+
+ it 'adds file to the repository' do
+ expect(wiki.repository.ls_files('HEAD')).to be_empty
+
+ service.execute
+
+ files = wiki.repository.ls_files('HEAD')
+ expect(files.count).to eq 1
+ expect(files.first).to match(file_path_regex)
+ end
+
+ context 'returns' do
+ before do
+ allow(SecureRandom).to receive(:hex).and_return('fixed_hex')
+
+ service_execute
+ end
+
+ it 'returns related information', :aggregate_failures do
+ expect(service_execute[:file_name]).to eq file_name
+ expect(service_execute[:file_path]).to eq 'uploads/fixed_hex/filename.txt'
+ expect(service_execute[:branch]).to eq wiki.default_branch
+ expect(service_execute[:commit]).not_to be_empty
+ end
+ end
+end