diff options
Diffstat (limited to 'spec/services/work_items')
-rw-r--r-- | spec/services/work_items/create_service_spec.rb | 56 | ||||
-rw-r--r-- | spec/services/work_items/delete_service_spec.rb | 50 | ||||
-rw-r--r-- | spec/services/work_items/update_service_spec.rb | 69 |
3 files changed, 153 insertions, 22 deletions
diff --git a/spec/services/work_items/create_service_spec.rb b/spec/services/work_items/create_service_spec.rb index 2c054ae59a0..f495e967b26 100644 --- a/spec/services/work_items/create_service_spec.rb +++ b/spec/services/work_items/create_service_spec.rb @@ -5,34 +5,46 @@ require 'spec_helper' RSpec.describe WorkItems::CreateService do include AfterNextHelpers - let_it_be(:group) { create(:group) } - let_it_be_with_reload(:project) { create(:project, group: group) } - let_it_be(:user) { create(:user) } + let_it_be_with_reload(:project) { create(:project) } + let_it_be(:guest) { create(:user) } + let_it_be(:user_with_no_access) { create(:user) } let(:spam_params) { double } + let(:current_user) { guest } + let(:opts) do + { + title: 'Awesome work_item', + description: 'please fix' + } + end + + before_all do + project.add_guest(guest) + end describe '#execute' do - let(:work_item) { described_class.new(project: project, current_user: user, params: opts, spam_params: spam_params).execute } + subject(:service_result) { described_class.new(project: project, current_user: current_user, params: opts, spam_params: spam_params).execute } before do stub_spam_services end - context 'when params are valid' do - before_all do - project.add_guest(user) - end + context 'when user is not allowed to create a work item in the project' do + let(:current_user) { user_with_no_access } + + it { is_expected.to be_error } - let(:opts) do - { - title: 'Awesome work_item', - description: 'please fix' - } + it 'returns an access error' do + expect(service_result.errors).to contain_exactly('Operation not allowed') end + end + context 'when params are valid' do it 'created instance is a WorkItem' do expect(Issuable::CommonSystemNotesService).to receive_message_chain(:new, :execute) + work_item = service_result[:work_item] + expect(work_item).to be_persisted expect(work_item).to be_a(::WorkItem) expect(work_item.title).to eq('Awesome work_item') @@ -41,17 +53,17 @@ RSpec.describe WorkItems::CreateService do end end - context 'checking spam' do - let(:params) do - { - title: 'Spam work_item' - } - end + context 'when params are invalid' do + let(:opts) { { title: '' } } - subject do - described_class.new(project: project, current_user: user, params: params, spam_params: spam_params) + it { is_expected.to be_error } + + it 'returns validation errors' do + expect(service_result.errors).to contain_exactly("Title can't be blank") end + end + context 'checking spam' do it 'executes SpamActionService' do expect_next_instance_of( Spam::SpamActionService, @@ -65,7 +77,7 @@ RSpec.describe WorkItems::CreateService do expect(instance).to receive(:execute) end - subject.execute + service_result end end end diff --git a/spec/services/work_items/delete_service_spec.rb b/spec/services/work_items/delete_service_spec.rb new file mode 100644 index 00000000000..6cca5018852 --- /dev/null +++ b/spec/services/work_items/delete_service_spec.rb @@ -0,0 +1,50 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe WorkItems::DeleteService do + let_it_be(:project) { create(:project, :repository) } + let_it_be(:guest) { create(:user) } + let_it_be(:work_item, refind: true) { create(:work_item, project: project, author: guest) } + + let(:user) { guest } + + before_all do + project.add_guest(guest) + # note necessary to test note removal as part of work item deletion + create(:note, project: project, noteable: work_item) + end + + describe '#execute' do + subject(:result) { described_class.new(project: project, current_user: user).execute(work_item) } + + context 'when user can delete the work item' do + it { is_expected.to be_success } + + # currently we don't expect destroy to fail. Mocking here for coverage and keeping + # the service's return type consistent + context 'when there are errors preventing to delete the work item' do + before do + allow(work_item).to receive(:destroy).and_return(false) + work_item.errors.add(:title) + end + + it { is_expected.to be_error } + + it 'returns error messages' do + expect(result.errors).to contain_exactly('Title is invalid') + end + end + end + + context 'when user cannot delete the work item' do + let(:user) { create(:user) } + + it { is_expected.to be_error } + + it 'returns error messages' do + expect(result.errors).to contain_exactly('User not authorized to delete work item') + end + end + end +end diff --git a/spec/services/work_items/update_service_spec.rb b/spec/services/work_items/update_service_spec.rb new file mode 100644 index 00000000000..f71f1060e40 --- /dev/null +++ b/spec/services/work_items/update_service_spec.rb @@ -0,0 +1,69 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe WorkItems::UpdateService do + let_it_be(:developer) { create(:user) } + let_it_be(:project) { create(:project).tap { |proj| proj.add_developer(developer) } } + let_it_be_with_reload(:work_item) { create(:work_item, project: project, assignees: [developer]) } + + let(:spam_params) { double } + let(:opts) { {} } + let(:current_user) { developer } + + describe '#execute' do + subject(:update_work_item) { described_class.new(project: project, current_user: current_user, params: opts, spam_params: spam_params).execute(work_item) } + + before do + stub_spam_services + end + + context 'when title is changed' do + let(:opts) { { title: 'changed' } } + + it 'triggers issuable_title_updated graphql subscription' do + expect(GraphqlTriggers).to receive(:issuable_title_updated).with(work_item).and_call_original + + update_work_item + end + end + + context 'when title is not changed' do + let(:opts) { { description: 'changed' } } + + it 'does not trigger issuable_title_updated graphql subscription' do + expect(GraphqlTriggers).not_to receive(:issuable_title_updated) + + update_work_item + end + end + + context 'when updating state_event' do + context 'when state_event is close' do + let(:opts) { { state_event: 'close' } } + + it 'closes the work item' do + expect do + update_work_item + work_item.reload + end.to change(work_item, :state).from('opened').to('closed') + end + end + + context 'when state_event is reopen' do + let(:opts) { { state_event: 'reopen' } } + + before do + work_item.close! + end + + it 'reopens the work item' do + expect do + update_work_item + work_item.reload + end.to change(work_item, :state).from('closed').to('opened') + end + end + end + end +end |