summaryrefslogtreecommitdiff
path: root/spec/services/work_items
diff options
context:
space:
mode:
Diffstat (limited to 'spec/services/work_items')
-rw-r--r--spec/services/work_items/create_service_spec.rb56
-rw-r--r--spec/services/work_items/delete_service_spec.rb50
-rw-r--r--spec/services/work_items/update_service_spec.rb69
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