summaryrefslogtreecommitdiff
path: root/spec
diff options
context:
space:
mode:
authorGrzegorz Bizon <grzegorz@gitlab.com>2019-08-21 09:38:40 +0000
committerGrzegorz Bizon <grzegorz@gitlab.com>2019-08-21 09:38:40 +0000
commit89f6584fb30544dbd27c291c3b62e3f2b0399e63 (patch)
tree6a364a9b79bcabb4df38bb7adf4a1190f8b83a7a /spec
parent9174d60ba1ce3e183396f360c6e41ed23540b6d0 (diff)
parent926bf71e511e084fa033b4e96f5b4067e0eeca0a (diff)
downloadgitlab-ce-89f6584fb30544dbd27c291c3b62e3f2b0399e63.tar.gz
Merge branch '63372-award-emoji-services' into 'master'
Add service classes for mutating AwardEmoji Closes #63372 See merge request gitlab-org/gitlab-ce!29782
Diffstat (limited to 'spec')
-rw-r--r--spec/controllers/projects/issues_controller_spec.rb33
-rw-r--r--spec/controllers/projects/notes_controller_spec.rb19
-rw-r--r--spec/controllers/snippets/notes_controller_spec.rb6
-rw-r--r--spec/finders/award_emojis_finder_spec.rb49
-rw-r--r--spec/models/award_emoji_spec.rb23
-rw-r--r--spec/models/concerns/awardable_spec.rb10
-rw-r--r--spec/requests/api/award_emoji_spec.rb16
-rw-r--r--spec/requests/api/graphql/mutations/award_emojis/add_spec.rb17
-rw-r--r--spec/requests/api/graphql/mutations/award_emojis/toggle_spec.rb17
-rw-r--r--spec/services/award_emojis/add_service_spec.rb103
-rw-r--r--spec/services/award_emojis/collect_user_emoji_service_spec.rb (renamed from spec/finders/awarded_emoji_finder_spec.rb)2
-rw-r--r--spec/services/award_emojis/destroy_service_spec.rb89
-rw-r--r--spec/services/award_emojis/toggle_service_spec.rb72
-rw-r--r--spec/services/projects/create_service_spec.rb1
-rw-r--r--spec/support/shared_examples/award_emoji_todo_shared_examples.rb59
15 files changed, 482 insertions, 34 deletions
diff --git a/spec/controllers/projects/issues_controller_spec.rb b/spec/controllers/projects/issues_controller_spec.rb
index fab47aa4701..187c7864ad7 100644
--- a/spec/controllers/projects/issues_controller_spec.rb
+++ b/spec/controllers/projects/issues_controller_spec.rb
@@ -1104,18 +1104,39 @@ describe Projects::IssuesController do
project.add_developer(user)
end
+ subject do
+ post(:toggle_award_emoji, params: {
+ namespace_id: project.namespace,
+ project_id: project,
+ id: issue.iid,
+ name: emoji_name
+ })
+ end
+ let(:emoji_name) { 'thumbsup' }
+
it "toggles the award emoji" do
expect do
- post(:toggle_award_emoji, params: {
- namespace_id: project.namespace,
- project_id: project,
- id: issue.iid,
- name: "thumbsup"
- })
+ subject
end.to change { issue.award_emoji.count }.by(1)
expect(response).to have_gitlab_http_status(200)
end
+
+ it "removes the already awarded emoji" do
+ create(:award_emoji, awardable: issue, name: emoji_name, user: user)
+
+ expect { subject }.to change { AwardEmoji.count }.by(-1)
+
+ expect(response).to have_gitlab_http_status(200)
+ end
+
+ it 'marks Todos on the Issue as done' do
+ todo = create(:todo, target: issue, project: project, user: user)
+
+ subject
+
+ expect(todo.reload).to be_done
+ end
end
describe 'POST create_merge_request' do
diff --git a/spec/controllers/projects/notes_controller_spec.rb b/spec/controllers/projects/notes_controller_spec.rb
index 9ab565dc2e8..4500c412521 100644
--- a/spec/controllers/projects/notes_controller_spec.rb
+++ b/spec/controllers/projects/notes_controller_spec.rb
@@ -543,23 +543,32 @@ describe Projects::NotesController do
project.add_developer(user)
end
+ subject { post(:toggle_award_emoji, params: request_params.merge(name: emoji_name)) }
+ let(:emoji_name) { 'thumbsup' }
+
it "toggles the award emoji" do
expect do
- post(:toggle_award_emoji, params: request_params.merge(name: "thumbsup"))
+ subject
end.to change { note.award_emoji.count }.by(1)
expect(response).to have_gitlab_http_status(200)
end
it "removes the already awarded emoji" do
- post(:toggle_award_emoji, params: request_params.merge(name: "thumbsup"))
+ create(:award_emoji, awardable: note, name: emoji_name, user: user)
- expect do
- post(:toggle_award_emoji, params: request_params.merge(name: "thumbsup"))
- end.to change { AwardEmoji.count }.by(-1)
+ expect { subject }.to change { AwardEmoji.count }.by(-1)
expect(response).to have_gitlab_http_status(200)
end
+
+ it 'marks Todos on the Noteable as done' do
+ todo = create(:todo, target: note.noteable, project: project, user: user)
+
+ subject
+
+ expect(todo.reload).to be_done
+ end
end
describe "resolving and unresolving" do
diff --git a/spec/controllers/snippets/notes_controller_spec.rb b/spec/controllers/snippets/notes_controller_spec.rb
index 652533ac49f..fd4b95ce226 100644
--- a/spec/controllers/snippets/notes_controller_spec.rb
+++ b/spec/controllers/snippets/notes_controller_spec.rb
@@ -288,11 +288,13 @@ describe Snippets::NotesController do
describe 'POST toggle_award_emoji' do
let(:note) { create(:note_on_personal_snippet, noteable: public_snippet) }
+ let(:emoji_name) { 'thumbsup'}
+
before do
sign_in(user)
end
- subject { post(:toggle_award_emoji, params: { snippet_id: public_snippet, id: note.id, name: "thumbsup" }) }
+ subject { post(:toggle_award_emoji, params: { snippet_id: public_snippet, id: note.id, name: emoji_name }) }
it "toggles the award emoji" do
expect { subject }.to change { note.award_emoji.count }.by(1)
@@ -301,7 +303,7 @@ describe Snippets::NotesController do
end
it "removes the already awarded emoji when it exists" do
- note.toggle_award_emoji('thumbsup', user) # create award emoji before
+ create(:award_emoji, awardable: note, name: emoji_name, user: user)
expect { subject }.to change { AwardEmoji.count }.by(-1)
diff --git a/spec/finders/award_emojis_finder_spec.rb b/spec/finders/award_emojis_finder_spec.rb
new file mode 100644
index 00000000000..ccac475daad
--- /dev/null
+++ b/spec/finders/award_emojis_finder_spec.rb
@@ -0,0 +1,49 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe AwardEmojisFinder do
+ set(:issue_1) { create(:issue) }
+ set(:issue_1_thumbsup) { create(:award_emoji, name: 'thumbsup', awardable: issue_1) }
+ set(:issue_1_thumbsdown) { create(:award_emoji, name: 'thumbsdown', awardable: issue_1) }
+ # Create a matching set of emoji for a second issue.
+ # These should never appear in our finder results
+ set(:issue_2) { create(:issue) }
+ set(:issue_2_thumbsup) { create(:award_emoji, name: 'thumbsup', awardable: issue_2) }
+ set(:issue_2_thumbsdown) { create(:award_emoji, name: 'thumbsdown', awardable: issue_2) }
+
+ describe 'param validation' do
+ it 'raises an error if `name` is invalid' do
+ expect { described_class.new(issue_1, { name: 'invalid' }).execute }.to raise_error(
+ ArgumentError,
+ 'Invalid name param'
+ )
+ end
+
+ it 'raises an error if `awarded_by` is invalid' do
+ expectation = [ArgumentError, 'Invalid awarded_by param']
+
+ expect { described_class.new(issue_1, { awarded_by: issue_2 }).execute }.to raise_error(*expectation)
+ expect { described_class.new(issue_1, { awarded_by: 'not-an-id' }).execute }.to raise_error(*expectation)
+ expect { described_class.new(issue_1, { awarded_by: 1.123 }).execute }.to raise_error(*expectation)
+ end
+ end
+
+ describe '#execute' do
+ it 'scopes to the awardable' do
+ expect(described_class.new(issue_1).execute).to contain_exactly(
+ issue_1_thumbsup, issue_1_thumbsdown
+ )
+ end
+
+ it 'filters by emoji name' do
+ expect(described_class.new(issue_1, { name: 'thumbsup' }).execute).to contain_exactly(issue_1_thumbsup)
+ expect(described_class.new(issue_1, { name: '8ball' }).execute).to be_empty
+ end
+
+ it 'filters by user' do
+ expect(described_class.new(issue_1, { awarded_by: issue_1_thumbsup.user }).execute).to contain_exactly(issue_1_thumbsup)
+ expect(described_class.new(issue_1, { awarded_by: issue_2_thumbsup.user }).execute).to be_empty
+ end
+ end
+end
diff --git a/spec/models/award_emoji_spec.rb b/spec/models/award_emoji_spec.rb
index 8452ac69734..b15b26b1630 100644
--- a/spec/models/award_emoji_spec.rb
+++ b/spec/models/award_emoji_spec.rb
@@ -44,6 +44,29 @@ describe AwardEmoji do
end
end
+ describe 'scopes' do
+ set(:thumbsup) { create(:award_emoji, name: 'thumbsup') }
+ set(:thumbsdown) { create(:award_emoji, name: 'thumbsdown') }
+
+ describe '.upvotes' do
+ it { expect(described_class.upvotes).to contain_exactly(thumbsup) }
+ end
+
+ describe '.downvotes' do
+ it { expect(described_class.downvotes).to contain_exactly(thumbsdown) }
+ end
+
+ describe '.named' do
+ it { expect(described_class.named('thumbsup')).to contain_exactly(thumbsup) }
+ it { expect(described_class.named(%w[thumbsup thumbsdown])).to contain_exactly(thumbsup, thumbsdown) }
+ end
+
+ describe '.awarded_by' do
+ it { expect(described_class.awarded_by(thumbsup.user)).to contain_exactly(thumbsup) }
+ it { expect(described_class.awarded_by([thumbsup.user, thumbsdown.user])).to contain_exactly(thumbsup, thumbsdown) }
+ end
+ end
+
describe 'expiring ETag cache' do
context 'on a note' do
let(:note) { create(:note_on_issue) }
diff --git a/spec/models/concerns/awardable_spec.rb b/spec/models/concerns/awardable_spec.rb
index 9e7106281ee..76da42cf243 100644
--- a/spec/models/concerns/awardable_spec.rb
+++ b/spec/models/concerns/awardable_spec.rb
@@ -82,16 +82,6 @@ describe Awardable do
end
end
- describe "#toggle_award_emoji" do
- it "adds an emoji if it isn't awarded yet" do
- expect { issue.toggle_award_emoji("thumbsup", award_emoji.user) }.to change { AwardEmoji.count }.by(1)
- end
-
- it "toggles already awarded emoji" do
- expect { issue.toggle_award_emoji("thumbsdown", award_emoji.user) }.to change { AwardEmoji.count }.by(-1)
- end
- end
-
describe 'querying award_emoji on an Awardable' do
let(:issue) { create(:issue) }
diff --git a/spec/requests/api/award_emoji_spec.rb b/spec/requests/api/award_emoji_spec.rb
index 6c67d84b59b..342fcfa1041 100644
--- a/spec/requests/api/award_emoji_spec.rb
+++ b/spec/requests/api/award_emoji_spec.rb
@@ -155,6 +155,14 @@ describe API::AwardEmoji do
expect(json_response['user']['username']).to eq(user.username)
end
+ it 'marks Todos on the Issue as done' do
+ todo = create(:todo, target: issue, project: project, user: user)
+
+ post api("/projects/#{project.id}/issues/#{issue.iid}/award_emoji", user), params: { name: '8ball' }
+
+ expect(todo.reload).to be_done
+ end
+
it "returns a 400 bad request error if the name is not given" do
post api("/projects/#{project.id}/issues/#{issue.iid}/award_emoji", user)
@@ -209,6 +217,14 @@ describe API::AwardEmoji do
expect(json_response['user']['username']).to eq(user.username)
end
+ it 'marks Todos on the Noteable as done' do
+ todo = create(:todo, target: note2.noteable, project: project, user: user)
+
+ post api("/projects/#{project.id}/issues/#{issue.iid}/notes/#{note.id}/award_emoji", user), params: { name: 'rocket' }
+
+ expect(todo.reload).to be_done
+ end
+
it "normalizes +1 as thumbsup award" do
post api("/projects/#{project.id}/issues/#{issue.iid}/notes/#{note.id}/award_emoji", user), params: { name: '+1' }
diff --git a/spec/requests/api/graphql/mutations/award_emojis/add_spec.rb b/spec/requests/api/graphql/mutations/award_emojis/add_spec.rb
index 3982125a38a..5b910d5bfe0 100644
--- a/spec/requests/api/graphql/mutations/award_emojis/add_spec.rb
+++ b/spec/requests/api/graphql/mutations/award_emojis/add_spec.rb
@@ -5,9 +5,9 @@ require 'spec_helper'
describe 'Adding an AwardEmoji' do
include GraphqlHelpers
- let(:current_user) { create(:user) }
- let(:awardable) { create(:note) }
- let(:project) { awardable.project }
+ set(:current_user) { create(:user) }
+ set(:project) { create(:project) }
+ set(:awardable) { create(:note, project: project) }
let(:emoji_name) { 'thumbsup' }
let(:mutation) do
variables = {
@@ -43,7 +43,7 @@ describe 'Adding an AwardEmoji' do
end
context 'when the given awardable is not an Awardable' do
- let(:awardable) { create(:label) }
+ let(:awardable) { create(:label, project: project) }
it_behaves_like 'a mutation that does not create an AwardEmoji'
@@ -52,7 +52,7 @@ describe 'Adding an AwardEmoji' do
end
context 'when the given awardable is an Awardable but still cannot be awarded an emoji' do
- let(:awardable) { create(:system_note) }
+ let(:awardable) { create(:system_note, project: project) }
it_behaves_like 'a mutation that does not create an AwardEmoji'
@@ -73,6 +73,13 @@ describe 'Adding an AwardEmoji' do
expect(mutation_response['awardEmoji']['name']).to eq(emoji_name)
end
+ describe 'marking Todos as done' do
+ let(:user) { current_user}
+ subject { post_graphql_mutation(mutation, current_user: user) }
+
+ include_examples 'creating award emojis marks Todos as done'
+ end
+
context 'when there were active record validation errors' do
before do
expect_next_instance_of(AwardEmoji) do |award|
diff --git a/spec/requests/api/graphql/mutations/award_emojis/toggle_spec.rb b/spec/requests/api/graphql/mutations/award_emojis/toggle_spec.rb
index 31145730f10..ae628d3e56c 100644
--- a/spec/requests/api/graphql/mutations/award_emojis/toggle_spec.rb
+++ b/spec/requests/api/graphql/mutations/award_emojis/toggle_spec.rb
@@ -5,9 +5,9 @@ require 'spec_helper'
describe 'Toggling an AwardEmoji' do
include GraphqlHelpers
- let(:current_user) { create(:user) }
- let(:awardable) { create(:note) }
- let(:project) { awardable.project }
+ set(:current_user) { create(:user) }
+ set(:project) { create(:project) }
+ set(:awardable) { create(:note, project: project) }
let(:emoji_name) { 'thumbsup' }
let(:mutation) do
variables = {
@@ -40,7 +40,7 @@ describe 'Toggling an AwardEmoji' do
end
context 'when the given awardable is not an Awardable' do
- let(:awardable) { create(:label) }
+ let(:awardable) { create(:label, project: project) }
it_behaves_like 'a mutation that does not create or destroy an AwardEmoji'
@@ -49,7 +49,7 @@ describe 'Toggling an AwardEmoji' do
end
context 'when the given awardable is an Awardable but still cannot be awarded an emoji' do
- let(:awardable) { create(:system_note) }
+ let(:awardable) { create(:system_note, project: project) }
it_behaves_like 'a mutation that does not create or destroy an AwardEmoji'
@@ -81,6 +81,13 @@ describe 'Toggling an AwardEmoji' do
expect(mutation_response['toggledOn']).to eq(true)
end
+ describe 'marking Todos as done' do
+ let(:user) { current_user}
+ subject { post_graphql_mutation(mutation, current_user: user) }
+
+ include_examples 'creating award emojis marks Todos as done'
+ end
+
context 'when there were active record validation errors' do
before do
expect_next_instance_of(AwardEmoji) do |award|
diff --git a/spec/services/award_emojis/add_service_spec.rb b/spec/services/award_emojis/add_service_spec.rb
new file mode 100644
index 00000000000..037db39ba80
--- /dev/null
+++ b/spec/services/award_emojis/add_service_spec.rb
@@ -0,0 +1,103 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe AwardEmojis::AddService do
+ set(:user) { create(:user) }
+ set(:project) { create(:project) }
+ set(:awardable) { create(:note, project: project) }
+ let(:name) { 'thumbsup' }
+ subject(:service) { described_class.new(awardable, name, user) }
+
+ describe '#execute' do
+ context 'when user is not authorized' do
+ it 'does not add an emoji' do
+ expect { service.execute }.not_to change { AwardEmoji.count }
+ end
+
+ it 'returns an error state' do
+ result = service.execute
+
+ expect(result[:status]).to eq(:error)
+ expect(result[:http_status]).to eq(:forbidden)
+ end
+ end
+
+ context 'when user is authorized' do
+ before do
+ project.add_developer(user)
+ end
+
+ it 'creates an award emoji' do
+ expect { service.execute }.to change { AwardEmoji.count }.by(1)
+ end
+
+ it 'returns the award emoji' do
+ result = service.execute
+
+ expect(result[:award]).to be_kind_of(AwardEmoji)
+ end
+
+ it 'return a success status' do
+ result = service.execute
+
+ expect(result[:status]).to eq(:success)
+ end
+
+ it 'sets the correct properties on the award emoji' do
+ award = service.execute[:award]
+
+ expect(award.name).to eq(name)
+ expect(award.user).to eq(user)
+ end
+
+ describe 'marking Todos as done' do
+ subject { service.execute }
+
+ include_examples 'creating award emojis marks Todos as done'
+ end
+
+ context 'when the awardable cannot have emoji awarded to it' do
+ before do
+ expect(awardable).to receive(:emoji_awardable?).and_return(false)
+ end
+
+ it 'does not add an emoji' do
+ expect { service.execute }.not_to change { AwardEmoji.count }
+ end
+
+ it 'returns an error status' do
+ result = service.execute
+
+ expect(result[:status]).to eq(:error)
+ expect(result[:http_status]).to eq(:unprocessable_entity)
+ end
+ end
+
+ context 'when the awardable is invalid' do
+ before do
+ expect_next_instance_of(AwardEmoji) do |award|
+ expect(award).to receive(:valid?).and_return(false)
+ expect(award).to receive_message_chain(:errors, :full_messages).and_return(['Error 1', 'Error 2'])
+ end
+ end
+
+ it 'does not add an emoji' do
+ expect { service.execute }.not_to change { AwardEmoji.count }
+ end
+
+ it 'returns an error status' do
+ result = service.execute
+
+ expect(result[:status]).to eq(:error)
+ end
+
+ it 'returns an error message' do
+ result = service.execute
+
+ expect(result[:message]).to eq('Error 1 and Error 2')
+ end
+ end
+ end
+ end
+end
diff --git a/spec/finders/awarded_emoji_finder_spec.rb b/spec/services/award_emojis/collect_user_emoji_service_spec.rb
index d4479df7418..a0dea31b403 100644
--- a/spec/finders/awarded_emoji_finder_spec.rb
+++ b/spec/services/award_emojis/collect_user_emoji_service_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe AwardedEmojiFinder do
+describe AwardEmojis::CollectUserEmojiService do
describe '#execute' do
it 'returns an Array containing the awarded emoji names' do
user = create(:user)
diff --git a/spec/services/award_emojis/destroy_service_spec.rb b/spec/services/award_emojis/destroy_service_spec.rb
new file mode 100644
index 00000000000..c4a7d5ec20e
--- /dev/null
+++ b/spec/services/award_emojis/destroy_service_spec.rb
@@ -0,0 +1,89 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe AwardEmojis::DestroyService do
+ set(:user) { create(:user) }
+ set(:awardable) { create(:note) }
+ set(:project) { awardable.project }
+ let(:name) { 'thumbsup' }
+ let!(:award_from_other_user) do
+ create(:award_emoji, name: name, awardable: awardable, user: create(:user))
+ end
+ subject(:service) { described_class.new(awardable, name, user) }
+
+ describe '#execute' do
+ shared_examples_for 'a service that does not authorize the user' do |error:|
+ it 'does not remove the emoji' do
+ expect { service.execute }.not_to change { AwardEmoji.count }
+ end
+
+ it 'returns an error state' do
+ result = service.execute
+
+ expect(result[:status]).to eq(:error)
+ expect(result[:http_status]).to eq(:forbidden)
+ end
+
+ it 'returns a nil award' do
+ result = service.execute
+
+ expect(result).to have_key(:award)
+ expect(result[:award]).to be_nil
+ end
+
+ it 'returns the error' do
+ result = service.execute
+
+ expect(result[:message]).to eq(error)
+ expect(result[:errors]).to eq([error])
+ end
+ end
+
+ context 'when user is not authorized' do
+ it_behaves_like 'a service that does not authorize the user',
+ error: 'User cannot destroy emoji on the awardable'
+ end
+
+ context 'when the user is authorized' do
+ before do
+ project.add_developer(user)
+ end
+
+ context 'when user has not awarded an emoji to the awardable' do
+ let!(:award_from_user) { create(:award_emoji, name: name, user: user) }
+
+ it_behaves_like 'a service that does not authorize the user',
+ error: 'User has not awarded emoji of type thumbsup on the awardable'
+ end
+
+ context 'when user has awarded an emoji to the awardable' do
+ let!(:award_from_user) { create(:award_emoji, name: name, awardable: awardable, user: user) }
+
+ it 'removes the emoji' do
+ expect { service.execute }.to change { AwardEmoji.count }.by(-1)
+ end
+
+ it 'returns a success status' do
+ result = service.execute
+
+ expect(result[:status]).to eq(:success)
+ end
+
+ it 'returns no errors' do
+ result = service.execute
+
+ expect(result).not_to have_key(:error)
+ expect(result).not_to have_key(:errors)
+ end
+
+ it 'returns the destroyed award' do
+ result = service.execute
+
+ expect(result[:award]).to eq(award_from_user)
+ expect(result[:award]).to be_destroyed
+ end
+ end
+ end
+ end
+end
diff --git a/spec/services/award_emojis/toggle_service_spec.rb b/spec/services/award_emojis/toggle_service_spec.rb
new file mode 100644
index 00000000000..972a1d5fc06
--- /dev/null
+++ b/spec/services/award_emojis/toggle_service_spec.rb
@@ -0,0 +1,72 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe AwardEmojis::ToggleService do
+ set(:user) { create(:user) }
+ set(:project) { create(:project, :public) }
+ set(:awardable) { create(:note, project: project) }
+ let(:name) { 'thumbsup' }
+ subject(:service) { described_class.new(awardable, name, user) }
+
+ describe '#execute' do
+ context 'when user has awarded an emoji' do
+ let!(:award_from_other_user) { create(:award_emoji, name: name, awardable: awardable, user: create(:user)) }
+ let!(:award) { create(:award_emoji, name: name, awardable: awardable, user: user) }
+
+ it 'calls AwardEmojis::DestroyService' do
+ expect(AwardEmojis::AddService).not_to receive(:new)
+
+ expect_next_instance_of(AwardEmojis::DestroyService) do |service|
+ expect(service).to receive(:execute)
+ end
+
+ service.execute
+ end
+
+ it 'destroys an AwardEmoji' do
+ expect { service.execute }.to change { AwardEmoji.count }.by(-1)
+ end
+
+ it 'returns the result of DestroyService#execute' do
+ mock_result = double(foo: true)
+
+ expect_next_instance_of(AwardEmojis::DestroyService) do |service|
+ expect(service).to receive(:execute).and_return(mock_result)
+ end
+
+ result = service.execute
+
+ expect(result).to eq(mock_result)
+ end
+ end
+
+ context 'when user has not awarded an emoji' do
+ it 'calls AwardEmojis::AddService' do
+ expect_next_instance_of(AwardEmojis::AddService) do |service|
+ expect(service).to receive(:execute)
+ end
+
+ expect(AwardEmojis::DestroyService).not_to receive(:new)
+
+ service.execute
+ end
+
+ it 'creates an AwardEmoji' do
+ expect { service.execute }.to change { AwardEmoji.count }.by(1)
+ end
+
+ it 'returns the result of AddService#execute' do
+ mock_result = double(foo: true)
+
+ expect_next_instance_of(AwardEmojis::AddService) do |service|
+ expect(service).to receive(:execute).and_return(mock_result)
+ end
+
+ result = service.execute
+
+ expect(result).to eq(mock_result)
+ end
+ end
+ end
+end
diff --git a/spec/services/projects/create_service_spec.rb b/spec/services/projects/create_service_spec.rb
index b0b74407812..d4fa62fa85d 100644
--- a/spec/services/projects/create_service_spec.rb
+++ b/spec/services/projects/create_service_spec.rb
@@ -78,6 +78,7 @@ describe Projects::CreateService, '#execute' do
expect(project).to be_valid
expect(project.owner).to eq(group)
expect(project.namespace).to eq(group)
+ expect(project.team.owners).to include(user)
expect(user.authorized_projects).to include(project)
end
end
diff --git a/spec/support/shared_examples/award_emoji_todo_shared_examples.rb b/spec/support/shared_examples/award_emoji_todo_shared_examples.rb
new file mode 100644
index 00000000000..88ad37d232f
--- /dev/null
+++ b/spec/support/shared_examples/award_emoji_todo_shared_examples.rb
@@ -0,0 +1,59 @@
+# frozen_string_literal: true
+
+# Shared examples to that test code that creates AwardEmoji also mark Todos
+# as done.
+#
+# The examples expect these to be defined in the calling spec:
+# - `subject` the callable code that executes the creation of an AwardEmoji
+# - `user`
+# - `project`
+RSpec.shared_examples 'creating award emojis marks Todos as done' do
+ using RSpec::Parameterized::TableSyntax
+
+ before do
+ project.add_developer(user)
+ end
+
+ where(:type, :expectation) do
+ :issue | true
+ :merge_request | true
+ :project_snippet | false
+ end
+
+ with_them do
+ let(:project) { awardable.project }
+ let(:awardable) { create(type) }
+ let!(:todo) { create(:todo, target: awardable, project: project, user: user) }
+
+ it do
+ subject
+
+ expect(todo.reload.done?).to eq(expectation)
+ end
+ end
+
+ # Notes have more complicated rules than other Todoables
+ describe 'for notes' do
+ let!(:todo) { create(:todo, target: awardable.noteable, project: project, user: user) }
+
+ context 'regular Notes' do
+ let(:awardable) { create(:note, project: project) }
+
+ it 'marks the Todo as done' do
+ subject
+
+ expect(todo.reload.done?).to eq(true)
+ end
+ end
+
+ context 'PersonalSnippet Notes' do
+ let(:awardable) { create(:note, noteable: create(:personal_snippet, author: user)) }
+
+ it 'does not mark the Todo as done' do
+ subject
+
+ expect(todo.reload.done?).to eq(false)
+ end
+ end
+ end
+end