summaryrefslogtreecommitdiff
path: root/spec/support/shared_examples/models
diff options
context:
space:
mode:
Diffstat (limited to 'spec/support/shared_examples/models')
-rw-r--r--spec/support/shared_examples/models/application_setting_shared_examples.rb15
-rw-r--r--spec/support/shared_examples/models/boards/user_preferences_shared_examples.rb68
-rw-r--r--spec/support/shared_examples/models/chat_service_shared_examples.rb11
-rw-r--r--spec/support/shared_examples/models/concerns/timebox_shared_examples.rb4
-rw-r--r--spec/support/shared_examples/models/email_format_shared_examples.rb4
-rw-r--r--spec/support/shared_examples/models/slack_mattermost_notifications_shared_examples.rb241
-rw-r--r--spec/support/shared_examples/models/wiki_shared_examples.rb46
7 files changed, 237 insertions, 152 deletions
diff --git a/spec/support/shared_examples/models/application_setting_shared_examples.rb b/spec/support/shared_examples/models/application_setting_shared_examples.rb
index 92fd4363134..60a02d85a1e 100644
--- a/spec/support/shared_examples/models/application_setting_shared_examples.rb
+++ b/spec/support/shared_examples/models/application_setting_shared_examples.rb
@@ -289,6 +289,7 @@ RSpec.shared_examples 'application settings examples' do
describe '#pick_repository_storage' do
before do
+ allow(Gitlab.config.repositories.storages).to receive(:keys).and_return(%w(default backup))
allow(setting).to receive(:repository_storages_weighted).and_return({ 'default' => 20, 'backup' => 80 })
end
@@ -304,15 +305,19 @@ RSpec.shared_examples 'application settings examples' do
describe '#normalized_repository_storage_weights' do
using RSpec::Parameterized::TableSyntax
- where(:storages, :normalized) do
- { 'default' => 0, 'backup' => 100 } | { 'default' => 0.0, 'backup' => 1.0 }
- { 'default' => 100, 'backup' => 100 } | { 'default' => 0.5, 'backup' => 0.5 }
- { 'default' => 20, 'backup' => 80 } | { 'default' => 0.2, 'backup' => 0.8 }
- { 'default' => 0, 'backup' => 0 } | { 'default' => 0.0, 'backup' => 0.0 }
+ where(:config_storages, :storages, :normalized) do
+ %w(default backup) | { 'default' => 0, 'backup' => 100 } | { 'default' => 0.0, 'backup' => 1.0 }
+ %w(default backup) | { 'default' => 100, 'backup' => 100 } | { 'default' => 0.5, 'backup' => 0.5 }
+ %w(default backup) | { 'default' => 20, 'backup' => 80 } | { 'default' => 0.2, 'backup' => 0.8 }
+ %w(default backup) | { 'default' => 0, 'backup' => 0 } | { 'default' => 0.0, 'backup' => 0.0 }
+ %w(default) | { 'default' => 0, 'backup' => 100 } | { 'default' => 0.0 }
+ %w(default) | { 'default' => 100, 'backup' => 100 } | { 'default' => 1.0 }
+ %w(default) | { 'default' => 20, 'backup' => 80 } | { 'default' => 1.0 }
end
with_them do
before do
+ allow(Gitlab.config.repositories.storages).to receive(:keys).and_return(config_storages)
allow(setting).to receive(:repository_storages_weighted).and_return(storages)
end
diff --git a/spec/support/shared_examples/models/boards/user_preferences_shared_examples.rb b/spec/support/shared_examples/models/boards/user_preferences_shared_examples.rb
new file mode 100644
index 00000000000..766aeac9476
--- /dev/null
+++ b/spec/support/shared_examples/models/boards/user_preferences_shared_examples.rb
@@ -0,0 +1,68 @@
+# frozen_string_literal: true
+
+RSpec.shared_examples 'list_preferences_for user' do |list_factory, list_id_attribute|
+ subject { create(list_factory) } # rubocop:disable Rails/SaveBang
+
+ let_it_be(:user) { create(:user) }
+
+ describe '#preferences_for' do
+ context 'when user is nil' do
+ it 'returns not persisted preferences' do
+ preferences = subject.preferences_for(nil)
+
+ expect(preferences).not_to be_persisted
+ expect(preferences[list_id_attribute]).to eq(subject.id)
+ expect(preferences.user_id).to be_nil
+ end
+ end
+
+ context 'when a user preference already exists' do
+ before do
+ subject.update_preferences_for(user, collapsed: true)
+ end
+
+ it 'loads preference for user' do
+ preferences = subject.preferences_for(user)
+
+ expect(preferences).to be_persisted
+ expect(preferences.collapsed).to eq(true)
+ end
+ end
+
+ context 'when preferences for user does not exist' do
+ it 'returns not persisted preferences' do
+ preferences = subject.preferences_for(user)
+
+ expect(preferences).not_to be_persisted
+ expect(preferences.user_id).to eq(user.id)
+ expect(preferences.public_send(list_id_attribute)).to eq(subject.id)
+ end
+ end
+ end
+
+ describe '#update_preferences_for' do
+ context 'when user is present' do
+ context 'when there are no preferences for user' do
+ it 'creates new user preferences' do
+ expect { subject.update_preferences_for(user, collapsed: true) }.to change { subject.preferences.count }.by(1)
+ expect(subject.preferences_for(user).collapsed).to eq(true)
+ end
+ end
+
+ context 'when there are preferences for user' do
+ it 'updates user preferences' do
+ subject.update_preferences_for(user, collapsed: false)
+
+ expect { subject.update_preferences_for(user, collapsed: true) }.not_to change { subject.preferences.count }
+ expect(subject.preferences_for(user).collapsed).to eq(true)
+ end
+ end
+
+ context 'when user is nil' do
+ it 'does not create user preferences' do
+ expect { subject.update_preferences_for(nil, collapsed: true) }.not_to change { subject.preferences.count }
+ end
+ end
+ end
+ end
+end
diff --git a/spec/support/shared_examples/models/chat_service_shared_examples.rb b/spec/support/shared_examples/models/chat_service_shared_examples.rb
index ad237ad9f49..59e249bb865 100644
--- a/spec/support/shared_examples/models/chat_service_shared_examples.rb
+++ b/spec/support/shared_examples/models/chat_service_shared_examples.rb
@@ -53,9 +53,13 @@ RSpec.shared_examples "chat service" do |service_name|
end
it "calls #{service_name} API" do
- subject.execute(sample_data)
+ result = subject.execute(sample_data)
- expect(WebMock).to have_requested(:post, webhook_url).with { |req| req.body =~ /\A{"#{content_key}":.+}\Z/ }.once
+ expect(result).to be(true)
+ expect(WebMock).to have_requested(:post, webhook_url).once.with { |req|
+ json_body = Gitlab::Json.parse(req.body).with_indifferent_access
+ expect(json_body).to include(payload)
+ }
end
end
@@ -67,7 +71,8 @@ RSpec.shared_examples "chat service" do |service_name|
it "does not call #{service_name} API" do
result = subject.execute(sample_data)
- expect(result).to be_falsy
+ expect(result).to be(false)
+ expect(WebMock).not_to have_requested(:post, webhook_url)
end
end
diff --git a/spec/support/shared_examples/models/concerns/timebox_shared_examples.rb b/spec/support/shared_examples/models/concerns/timebox_shared_examples.rb
index f91e4bd8cf7..68142e667a4 100644
--- a/spec/support/shared_examples/models/concerns/timebox_shared_examples.rb
+++ b/spec/support/shared_examples/models/concerns/timebox_shared_examples.rb
@@ -18,7 +18,7 @@ RSpec.shared_examples 'a timebox' do |timebox_type|
context 'with a project' do
it_behaves_like 'AtomicInternalId' do
let(:internal_id_attribute) { :iid }
- let(:instance) { build(timebox_type, *timebox_args, project: build(:project), group: nil) }
+ let(:instance) { build(timebox_type, *timebox_args, project: create(:project), group: nil) }
let(:scope) { :project }
let(:scope_attrs) { { project: instance.project } }
let(:usage) { timebox_table_name }
@@ -28,7 +28,7 @@ RSpec.shared_examples 'a timebox' do |timebox_type|
context 'with a group' do
it_behaves_like 'AtomicInternalId' do
let(:internal_id_attribute) { :iid }
- let(:instance) { build(timebox_type, *timebox_args, project: nil, group: build(:group)) }
+ let(:instance) { build(timebox_type, *timebox_args, project: nil, group: create(:group)) }
let(:scope) { :group }
let(:scope_attrs) { { namespace: instance.group } }
let(:usage) { timebox_table_name }
diff --git a/spec/support/shared_examples/models/email_format_shared_examples.rb b/spec/support/shared_examples/models/email_format_shared_examples.rb
index a8115e440a4..77ded168637 100644
--- a/spec/support/shared_examples/models/email_format_shared_examples.rb
+++ b/spec/support/shared_examples/models/email_format_shared_examples.rb
@@ -6,7 +6,7 @@
# Note: You have access to `email_value` which is the email address value
# being currently tested).
-RSpec.shared_examples 'an object with email-formated attributes' do |*attributes|
+RSpec.shared_examples 'an object with email-formatted attributes' do |*attributes|
attributes.each do |attribute|
describe "specifically its :#{attribute} attribute" do
%w[
@@ -45,7 +45,7 @@ RSpec.shared_examples 'an object with email-formated attributes' do |*attributes
end
end
-RSpec.shared_examples 'an object with RFC3696 compliant email-formated attributes' do |*attributes|
+RSpec.shared_examples 'an object with RFC3696 compliant email-formatted attributes' do |*attributes|
attributes.each do |attribute|
describe "specifically its :#{attribute} attribute" do
%w[
diff --git a/spec/support/shared_examples/models/slack_mattermost_notifications_shared_examples.rb b/spec/support/shared_examples/models/slack_mattermost_notifications_shared_examples.rb
index a1867e1ce39..71a76121d38 100644
--- a/spec/support/shared_examples/models/slack_mattermost_notifications_shared_examples.rb
+++ b/spec/support/shared_examples/models/slack_mattermost_notifications_shared_examples.rb
@@ -7,7 +7,7 @@ RSpec.shared_examples 'slack or mattermost notifications' do |service_name|
let(:webhook_url) { 'https://example.gitlab.com' }
def execute_with_options(options)
- receive(:new).with(webhook_url, options.merge(http_client: SlackService::Notifier::HTTPClient))
+ receive(:new).with(webhook_url, options.merge(http_client: SlackMattermost::Notifier::HTTPClient))
.and_return(double(:slack_service).as_null_object)
end
@@ -66,193 +66,180 @@ RSpec.shared_examples 'slack or mattermost notifications' do |service_name|
end
describe "#execute" do
- let(:user) { create(:user) }
- let(:project) { create(:project, :repository, :wiki_repo) }
- let(:username) { 'slack_username' }
- let(:channel) { 'slack_channel' }
- let(:issue_service_options) { { title: 'Awesome issue', description: 'please fix' } }
+ let_it_be(:project) { create(:project, :repository, :wiki_repo) }
+ let_it_be(:user) { create(:user) }
- let(:data) do
- Gitlab::DataBuilder::Push.build_sample(project, user)
- end
+ let(:chat_service) { described_class.new( { project: project, webhook: webhook_url, branches_to_be_notified: 'all' }.merge(chat_service_params)) }
+ let(:chat_service_params) { {} }
+ let(:data) { Gitlab::DataBuilder::Push.build_sample(project, user) }
let!(:stubbed_resolved_hostname) do
stub_full_request(webhook_url, method: :post).request_pattern.uri_pattern.to_s
end
- before do
- allow(chat_service).to receive_messages(
- project: project,
- project_id: project.id,
- service_hook: true,
- webhook: webhook_url
- )
+ subject(:execute_service) { chat_service.execute(data) }
- issue_service = Issues::CreateService.new(project, user, issue_service_options)
- @issue = issue_service.execute
- @issues_sample_data = issue_service.hook_data(@issue, 'open')
-
- project.add_developer(user)
- opts = {
- title: 'Awesome merge_request',
- description: 'please fix',
- source_branch: 'feature',
- target_branch: 'master'
- }
- merge_service = MergeRequests::CreateService.new(project,
- user, opts)
- @merge_request = merge_service.execute
- @merge_sample_data = merge_service.hook_data(@merge_request,
- 'open')
-
- opts = {
- title: "Awesome wiki_page",
- content: "Some text describing some thing or another",
- format: "md",
- message: "user created page: Awesome wiki_page"
- }
-
- @wiki_page = create(:wiki_page, wiki: project.wiki, **opts)
- @wiki_page_sample_data = Gitlab::DataBuilder::WikiPage.build(@wiki_page, user, 'create')
- end
-
- it "calls #{service_name} API for push events" do
- chat_service.execute(data)
-
- expect(WebMock).to have_requested(:post, stubbed_resolved_hostname).once
- end
+ shared_examples 'calls the service API with the event message' do |event_message|
+ specify do
+ expect_next_instance_of(Slack::Messenger) do |messenger|
+ expect(messenger).to receive(:ping).with(event_message, anything).and_call_original
+ end
- it "calls #{service_name} API for issue events" do
- chat_service.execute(@issues_sample_data)
+ execute_service
- expect(WebMock).to have_requested(:post, stubbed_resolved_hostname).once
+ expect(WebMock).to have_requested(:post, stubbed_resolved_hostname).once
+ end
end
- it "calls #{service_name} API for merge requests events" do
- chat_service.execute(@merge_sample_data)
+ context 'with username for slack configured' do
+ let(:chat_service_params) { { username: 'slack_username' } }
+
+ it 'uses the username as an option' do
+ expect(Slack::Messenger).to execute_with_options(username: 'slack_username')
- expect(WebMock).to have_requested(:post, stubbed_resolved_hostname).once
+ execute_service
+ end
end
- it "calls #{service_name} API for wiki page events" do
- chat_service.execute(@wiki_page_sample_data)
+ context 'push events' do
+ let(:data) { Gitlab::DataBuilder::Push.build_sample(project, user) }
- expect(WebMock).to have_requested(:post, stubbed_resolved_hostname).once
- end
+ it_behaves_like 'calls the service API with the event message', /pushed to branch/
- it "calls #{service_name} API for deployment events" do
- deployment_event_data = { object_kind: 'deployment' }
+ context 'with event channel' do
+ let(:chat_service_params) { { push_channel: 'random' } }
- chat_service.execute(deployment_event_data)
+ it 'uses the right channel for push event' do
+ expect(Slack::Messenger).to execute_with_options(channel: ['random'])
- expect(WebMock).to have_requested(:post, stubbed_resolved_hostname).once
+ execute_service
+ end
+ end
end
- it 'uses the username as an option for slack when configured' do
- allow(chat_service).to receive(:username).and_return(username)
-
- expect(Slack::Messenger).to execute_with_options(username: username)
+ context 'tag_push events' do
+ let(:oldrev) { Gitlab::Git::BLANK_SHA }
+ let(:newrev) { '8a2a6eb295bb170b34c24c76c49ed0e9b2eaf34b' } # gitlab-test: git rev-parse refs/tags/v1.1.0
+ let(:ref) { 'refs/tags/v1.1.0' }
+ let(:data) { Git::TagHooksService.new(project, user, change: { oldrev: oldrev, newrev: newrev, ref: ref }).send(:push_data) }
- chat_service.execute(data)
+ it_behaves_like 'calls the service API with the event message', /pushed new tag/
end
- it 'uses the channel as an option when it is configured' do
- allow(chat_service).to receive(:channel).and_return(channel)
- expect(Slack::Messenger).to execute_with_options(channel: [channel])
- chat_service.execute(data)
- end
+ context 'issue events' do
+ let_it_be(:issue) { create(:issue) }
+ let(:data) { issue.to_hook_data(user) }
- context "event channels" do
- it "uses the right channel for push event" do
- chat_service.update!(push_channel: "random")
+ it_behaves_like 'calls the service API with the event message', /Issue (.*?) opened by/
- expect(Slack::Messenger).to execute_with_options(channel: ['random'])
+ context 'whith event channel' do
+ let(:chat_service_params) { { issue_channel: 'random' } }
- chat_service.execute(data)
- end
+ it 'uses the right channel for issue event' do
+ expect(Slack::Messenger).to execute_with_options(channel: ['random'])
- it "uses the right channel for merge request event" do
- chat_service.update!(merge_request_channel: "random")
+ execute_service
+ end
- expect(Slack::Messenger).to execute_with_options(channel: ['random'])
+ context 'for confidential issues' do
+ before_all do
+ issue.update!(confidential: true)
+ end
- chat_service.execute(@merge_sample_data)
- end
+ it 'falls back to issue channel' do
+ expect(Slack::Messenger).to execute_with_options(channel: ['random'])
+
+ execute_service
+ end
- it "uses the right channel for issue event" do
- chat_service.update!(issue_channel: "random")
+ context 'and confidential_issue_channel is defined' do
+ let(:chat_service_params) { { issue_channel: 'random', confidential_issue_channel: 'confidential' } }
- expect(Slack::Messenger).to execute_with_options(channel: ['random'])
+ it 'uses the confidential issue channel when it is defined' do
+ expect(Slack::Messenger).to execute_with_options(channel: ['confidential'])
- chat_service.execute(@issues_sample_data)
+ execute_service
+ end
+ end
+ end
end
+ end
+
+ context 'merge request events' do
+ let_it_be(:merge_request) { create(:merge_request) }
+ let(:data) { merge_request.to_hook_data(user) }
- context 'for confidential issues' do
- let(:issue_service_options) { { title: 'Secret', confidential: true } }
+ it_behaves_like 'calls the service API with the event message', /opened merge request/
- it "uses confidential issue channel" do
- chat_service.update!(confidential_issue_channel: 'confidential')
+ context 'with event channel' do
+ let(:chat_service_params) { { merge_request_channel: 'random' } }
- expect(Slack::Messenger).to execute_with_options(channel: ['confidential'])
+ it 'uses the right channel for merge request event' do
+ expect(Slack::Messenger).to execute_with_options(channel: ['random'])
- chat_service.execute(@issues_sample_data)
+ execute_service
end
+ end
+ end
+
+ context 'wiki page events' do
+ let_it_be(:wiki_page) { create(:wiki_page, wiki: project.wiki, message: 'user created page: Awesome wiki_page') }
+ let(:data) { Gitlab::DataBuilder::WikiPage.build(wiki_page, user, 'create') }
- it 'falls back to issue channel' do
- chat_service.update!(issue_channel: 'fallback_channel')
+ it_behaves_like 'calls the service API with the event message', / created (.*?)wikis\/(.*?)|wiki page> in/
- expect(Slack::Messenger).to execute_with_options(channel: ['fallback_channel'])
+ context 'with event channel' do
+ let(:chat_service_params) { { wiki_page_channel: 'random' } }
- chat_service.execute(@issues_sample_data)
+ it 'uses the right channel for wiki event' do
+ expect(Slack::Messenger).to execute_with_options(channel: ['random'])
+
+ execute_service
end
end
+ end
- it "uses the right channel for wiki event" do
- chat_service.update!(wiki_page_channel: "random")
-
- expect(Slack::Messenger).to execute_with_options(channel: ['random'])
+ context 'deployment events' do
+ let_it_be(:deployment) { create(:deployment) }
+ let(:data) { Gitlab::DataBuilder::Deployment.build(deployment) }
- chat_service.execute(@wiki_page_sample_data)
- end
+ it_behaves_like 'calls the service API with the event message', /Deploy to (.*?) created/
+ end
- context "note event" do
- let(:issue_note) do
- create(:note_on_issue, project: project, note: "issue note")
- end
+ context 'note event' do
+ let_it_be(:issue_note) { create(:note_on_issue, project: project, note: "issue note") }
+ let(:data) { Gitlab::DataBuilder::Note.build(issue_note, user) }
- it "uses the right channel" do
- chat_service.update!(note_channel: "random")
+ it_behaves_like 'calls the service API with the event message', /commented on issue/
- note_data = Gitlab::DataBuilder::Note.build(issue_note, user)
+ context 'with event channel' do
+ let(:chat_service_params) { { note_channel: 'random' } }
+ it 'uses the right channel' do
expect(Slack::Messenger).to execute_with_options(channel: ['random'])
- chat_service.execute(note_data)
+ execute_service
end
context 'for confidential notes' do
- before do
- issue_note.noteable.update!(confidential: true)
+ before_all do
+ issue_note.update!(confidential: true)
end
- it "uses confidential channel" do
- chat_service.update!(confidential_note_channel: "confidential")
-
- note_data = Gitlab::DataBuilder::Note.build(issue_note, user)
-
- expect(Slack::Messenger).to execute_with_options(channel: ['confidential'])
+ it 'falls back to note channel' do
+ expect(Slack::Messenger).to execute_with_options(channel: ['random'])
- chat_service.execute(note_data)
+ execute_service
end
- it 'falls back to note channel' do
- chat_service.update!(note_channel: "fallback_channel")
-
- note_data = Gitlab::DataBuilder::Note.build(issue_note, user)
+ context 'and confidential_note_channel is defined' do
+ let(:chat_service_params) { { note_channel: 'random', confidential_note_channel: 'confidential' } }
- expect(Slack::Messenger).to execute_with_options(channel: ['fallback_channel'])
+ it 'uses confidential channel' do
+ expect(Slack::Messenger).to execute_with_options(channel: ['confidential'])
- chat_service.execute(note_data)
+ execute_service
+ end
end
end
end
diff --git a/spec/support/shared_examples/models/wiki_shared_examples.rb b/spec/support/shared_examples/models/wiki_shared_examples.rb
index 89d30688b5c..abc6e3ecce8 100644
--- a/spec/support/shared_examples/models/wiki_shared_examples.rb
+++ b/spec/support/shared_examples/models/wiki_shared_examples.rb
@@ -354,27 +354,47 @@ RSpec.shared_examples 'wiki model' do
subject.repository.create_file(user, 'image.png', image, branch_name: subject.default_branch, message: 'add image')
end
- it 'returns the latest version of the file if it exists' do
- file = subject.find_file('image.png')
+ shared_examples 'find_file results' do
+ it 'returns the latest version of the file if it exists' do
+ file = subject.find_file('image.png')
- expect(file.mime_type).to eq('image/png')
- end
+ expect(file.mime_type).to eq('image/png')
+ end
+
+ it 'returns nil if the page does not exist' do
+ expect(subject.find_file('non-existent')).to eq(nil)
+ end
+
+ it 'returns a Gitlab::Git::WikiFile instance' do
+ file = subject.find_file('image.png')
+
+ expect(file).to be_a Gitlab::Git::WikiFile
+ end
- it 'returns nil if the page does not exist' do
- expect(subject.find_file('non-existent')).to eq(nil)
+ it 'returns the whole file' do
+ file = subject.find_file('image.png')
+ image.rewind
+
+ expect(file.raw_data.b).to eq(image.read.b)
+ end
end
- it 'returns a Gitlab::Git::WikiFile instance' do
- file = subject.find_file('image.png')
+ it_behaves_like 'find_file results'
+
+ context 'when load_content is disabled' do
+ it 'includes the file data in the Gitlab::Git::WikiFile' do
+ file = subject.find_file('image.png', load_content: false)
- expect(file).to be_a Gitlab::Git::WikiFile
+ expect(file.raw_data).to be_empty
+ end
end
- it 'returns the whole file' do
- file = subject.find_file('image.png')
- image.rewind
+ context 'when feature flag :gitaly_find_file is disabled' do
+ before do
+ stub_feature_flags(gitaly_find_file: false)
+ end
- expect(file.raw_data.b).to eq(image.read.b)
+ it_behaves_like 'find_file results'
end
end