diff options
author | Grzegorz Bizon <grzegorz@gitlab.com> | 2019-08-21 09:38:40 +0000 |
---|---|---|
committer | Grzegorz Bizon <grzegorz@gitlab.com> | 2019-08-21 09:38:40 +0000 |
commit | 89f6584fb30544dbd27c291c3b62e3f2b0399e63 (patch) | |
tree | 6a364a9b79bcabb4df38bb7adf4a1190f8b83a7a /spec | |
parent | 9174d60ba1ce3e183396f360c6e41ed23540b6d0 (diff) | |
parent | 926bf71e511e084fa033b4e96f5b4067e0eeca0a (diff) | |
download | gitlab-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.rb | 33 | ||||
-rw-r--r-- | spec/controllers/projects/notes_controller_spec.rb | 19 | ||||
-rw-r--r-- | spec/controllers/snippets/notes_controller_spec.rb | 6 | ||||
-rw-r--r-- | spec/finders/award_emojis_finder_spec.rb | 49 | ||||
-rw-r--r-- | spec/models/award_emoji_spec.rb | 23 | ||||
-rw-r--r-- | spec/models/concerns/awardable_spec.rb | 10 | ||||
-rw-r--r-- | spec/requests/api/award_emoji_spec.rb | 16 | ||||
-rw-r--r-- | spec/requests/api/graphql/mutations/award_emojis/add_spec.rb | 17 | ||||
-rw-r--r-- | spec/requests/api/graphql/mutations/award_emojis/toggle_spec.rb | 17 | ||||
-rw-r--r-- | spec/services/award_emojis/add_service_spec.rb | 103 | ||||
-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.rb | 89 | ||||
-rw-r--r-- | spec/services/award_emojis/toggle_service_spec.rb | 72 | ||||
-rw-r--r-- | spec/services/projects/create_service_spec.rb | 1 | ||||
-rw-r--r-- | spec/support/shared_examples/award_emoji_todo_shared_examples.rb | 59 |
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 |