diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2020-06-23 18:08:41 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2020-06-23 18:08:41 +0300 |
commit | 5eeb39104356356bec81abe19479bca591e6f299 (patch) | |
tree | 7534ccf94fb8100ce39b78278d275b2061773f95 /spec | |
parent | b7e512c8970dcce6feabc096885c7a1ea91e4694 (diff) |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'spec')
-rw-r--r-- | spec/finders/resource_milestone_event_finder_spec.rb | 16 | ||||
-rw-r--r-- | spec/frontend/alert_management/components/alert_managment_sidebar_assignees_spec.js | 22 | ||||
-rw-r--r-- | spec/models/issue_assignee_spec.rb | 35 | ||||
-rw-r--r-- | spec/models/merge_request_assignee_spec.rb | 22 | ||||
-rw-r--r-- | spec/models/snippet_spec.rb | 11 | ||||
-rw-r--r-- | spec/models/snippet_statistics_spec.rb | 81 | ||||
-rw-r--r-- | spec/routing/project_routing_spec.rb | 4 | ||||
-rw-r--r-- | spec/services/alert_management/alerts/update_service_spec.rb | 131 | ||||
-rw-r--r-- | spec/services/members/destroy_service_spec.rb | 29 | ||||
-rw-r--r-- | spec/services/members/unassign_issuables_service_spec.rb | 66 | ||||
-rw-r--r-- | spec/simplecov_env.rb | 10 | ||||
-rw-r--r-- | spec/support/shared_examples/requests/api/resource_milestone_events_api_shared_examples.rb | 37 | ||||
-rw-r--r-- | spec/workers/members_destroyer/unassign_issuables_worker_spec.rb | 27 |
13 files changed, 413 insertions, 78 deletions
diff --git a/spec/finders/resource_milestone_event_finder_spec.rb b/spec/finders/resource_milestone_event_finder_spec.rb index ff4508996e2..27e124afe2e 100644 --- a/spec/finders/resource_milestone_event_finder_spec.rb +++ b/spec/finders/resource_milestone_event_finder_spec.rb @@ -42,18 +42,6 @@ RSpec.describe ResourceMilestoneEventFinder do expect(subject).to be_empty end - it 'paginates results' do - milestone = create(:milestone, project: issue_project) - create_event(milestone) - create_event(milestone) - issue_project.add_guest(user) - - paginated = described_class.new(user, issue, per_page: 1).execute - - expect(subject.count).to eq 2 - expect(paginated.count).to eq 1 - end - context 'when multiple events share the same milestone' do it 'avoids N+1 queries' do issue_project.add_developer(user) @@ -71,8 +59,8 @@ RSpec.describe ResourceMilestoneEventFinder do create_event(milestone2, :add) create_event(milestone2, :remove) - # 1 events + 1 milestones + 1 project + 1 user + 4 ability - expect { described_class.new(user, issue).execute }.not_to exceed_query_limit(control_count + 7) + # 1 milestones + 1 project + 1 user + 4 ability + expect { described_class.new(user, issue).execute }.not_to exceed_query_limit(control_count + 6) end end diff --git a/spec/frontend/alert_management/components/alert_managment_sidebar_assignees_spec.js b/spec/frontend/alert_management/components/alert_managment_sidebar_assignees_spec.js index 2452ba7c63b..2cab761f730 100644 --- a/spec/frontend/alert_management/components/alert_managment_sidebar_assignees_spec.js +++ b/spec/frontend/alert_management/components/alert_managment_sidebar_assignees_spec.js @@ -59,7 +59,7 @@ describe('Alert Details Sidebar Assignees', () => { describe('updating the alert status', () => { const mockUpdatedMutationResult = { data: { - updateAlertStatus: { + alertSetAssignees: { errors: [], alert: { assigneeUsernames: ['root'], @@ -125,6 +125,26 @@ describe('Alert Details Sidebar Assignees', () => { }); }); + it('shows an error when request contains error messages', () => { + wrapper.setData({ isDropdownSearching: false }); + const errorMutationResult = { + data: { + alertSetAssignees: { + errors: ['There was a problem for sure.'], + alert: {}, + }, + }, + }; + + jest.spyOn(wrapper.vm.$apollo, 'mutate').mockResolvedValue(errorMutationResult); + + return wrapper.vm.$nextTick().then(() => { + const SideBarAssigneeItem = wrapper.findAll(SidebarAssignee).at(0); + SideBarAssigneeItem.vm.$emit('click'); + expect(wrapper.emitted('alert-refresh')).toBeUndefined(); + }); + }); + it('stops updating and cancels loading when the request fails', () => { jest.spyOn(wrapper.vm.$apollo, 'mutate').mockReturnValue(Promise.reject(new Error())); wrapper.vm.updateAlertAssignees('root'); diff --git a/spec/models/issue_assignee_spec.rb b/spec/models/issue_assignee_spec.rb index 2d59ba15101..df8e91cd133 100644 --- a/spec/models/issue_assignee_spec.rb +++ b/spec/models/issue_assignee_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -describe IssueAssignee do +RSpec.describe IssueAssignee do let(:issue) { create(:issue) } subject { issue.issue_assignees.build(assignee: create(:user)) } @@ -15,4 +15,37 @@ describe IssueAssignee do describe 'validations' do it { is_expected.to validate_uniqueness_of(:assignee).scoped_to(:issue_id) } end + + describe 'scopes' do + let_it_be(:user) { create(:user) } + let_it_be(:project) { create(:project) } + let_it_be(:project_issue) { create(:issue, project: project, assignee_ids: [user.id]) } + + before do + issue.update!(assignee_ids: [user.id]) + end + + context 'in_projects' do + it 'returns issue assignees for given project' do + expect(IssueAssignee.count).to eq 2 + + assignees = IssueAssignee.in_projects([project]) + + expect(assignees.count).to eq 1 + expect(assignees.first.user_id).to eq project_issue.issue_assignees.first.user_id + expect(assignees.first.issue_id).to eq project_issue.issue_assignees.first.issue_id + end + end + + context 'on_issues' do + it 'returns issue assignees for given issues' do + expect(IssueAssignee.count).to eq 2 + + assignees = IssueAssignee.on_issues([project_issue]) + + expect(assignees.count).to eq 1 + expect(assignees.first.issue_id).to eq project_issue.issue_assignees.first.issue_id + end + end + end end diff --git a/spec/models/merge_request_assignee_spec.rb b/spec/models/merge_request_assignee_spec.rb index d6aab15d990..bd2df428ed0 100644 --- a/spec/models/merge_request_assignee_spec.rb +++ b/spec/models/merge_request_assignee_spec.rb @@ -15,4 +15,26 @@ describe MergeRequestAssignee do describe 'validations' do it { is_expected.to validate_uniqueness_of(:assignee).scoped_to(:merge_request_id) } end + + describe 'scopes' do + let_it_be(:user) { create(:user) } + let_it_be(:project) { create(:project, :repository) } + let_it_be(:project_merge_request) { create(:merge_request, target_project: project, source_project: project, assignee_ids: [user.id]) } + + before do + merge_request.update!(assignee_ids: [user.id]) + end + + context 'in_projects' do + it 'returns issue assignees for given project' do + expect(MergeRequestAssignee.count).to eq 2 + + assignees = MergeRequestAssignee.in_projects([project]) + + expect(assignees.count).to eq 1 + expect(assignees.first.user_id).to eq project_merge_request.merge_request_assignees.first.user_id + expect(assignees.first.merge_request_id).to eq project_merge_request.merge_request_assignees.first.merge_request_id + end + end + end end diff --git a/spec/models/snippet_spec.rb b/spec/models/snippet_spec.rb index 6edaf0410f5..7ded8c380fe 100644 --- a/spec/models/snippet_spec.rb +++ b/spec/models/snippet_spec.rb @@ -92,6 +92,17 @@ describe Snippet do end end + describe 'callbacks' do + it 'creates snippet statistics when the snippet is created' do + snippet = build(:snippet) + expect(snippet.statistics).to be_nil + + snippet.save + + expect(snippet.statistics).to be_persisted + end + end + describe '#to_reference' do context 'when snippet belongs to a project' do let(:project) { build(:project, name: 'sample-project') } diff --git a/spec/models/snippet_statistics_spec.rb b/spec/models/snippet_statistics_spec.rb index d76fe5fb589..1bfb80e2c1d 100644 --- a/spec/models/snippet_statistics_spec.rb +++ b/spec/models/snippet_statistics_spec.rb @@ -3,6 +3,87 @@ require 'spec_helper' describe SnippetStatistics do + let_it_be(:snippet_without_repo) { create(:snippet) } + let_it_be(:snippet_with_repo) { create(:snippet, :repository) } + + let(:statistics) { snippet_with_repo.statistics } + it { is_expected.to belong_to(:snippet) } it { is_expected.to validate_presence_of(:snippet) } + + describe '#update_commit_count' do + subject { statistics.update_commit_count } + + it 'updates the count of commits' do + commit_count = snippet_with_repo.repository.commit_count + + subject + + expect(statistics.commit_count).to eq commit_count + end + + context 'when the snippet does not have a repository' do + let(:statistics) { snippet_without_repo.statistics } + + it 'returns 0' do + expect(subject).to eq 0 + expect(statistics.commit_count).to eq 0 + end + end + end + + describe '#update_file_count' do + subject { statistics.update_file_count } + + it 'updates the count of files' do + file_count = snippet_with_repo.repository.ls_files(nil).count + + subject + + expect(statistics.file_count).to eq file_count + end + + context 'when the snippet does not have a repository' do + let(:statistics) { snippet_without_repo.statistics } + + it 'returns 0' do + expect(subject).to eq 0 + expect(statistics.file_count).to eq 0 + end + end + end + + describe '#update_repository_size' do + subject { statistics.update_repository_size } + + it 'updates the repository_size' do + repository_size = snippet_with_repo.repository.size.megabytes.to_i + + subject + + expect(statistics.repository_size).to eq repository_size + end + + context 'when the snippet does not have a repository' do + let(:statistics) { snippet_without_repo.statistics } + + it 'returns 0' do + expect(subject).to eq 0 + expect(statistics.repository_size).to eq 0 + end + end + end + + describe '#refresh!' do + subject { statistics.refresh! } + + it 'retrieves and saves statistic data from repository' do + expect(statistics).to receive(:update_commit_count) + expect(statistics).to receive(:update_file_count) + expect(statistics).to receive(:update_repository_size) + expect(statistics).to receive(:save!) + + subject + end + end end diff --git a/spec/routing/project_routing_spec.rb b/spec/routing/project_routing_spec.rb index 966d6f7b106..0a57c76ee75 100644 --- a/spec/routing/project_routing_spec.rb +++ b/spec/routing/project_routing_spec.rb @@ -407,6 +407,10 @@ describe 'project routing' do it 'to #destroy' do expect(delete('/gitlab/gitlabhq/snippets/1')).to route_to('projects/snippets#destroy', namespace_id: 'gitlab', project_id: 'gitlabhq', id: '1') end + + it 'to #show from scope routing' do + expect(get('/gitlab/gitlabhq/-/snippets/1')).to route_to('projects/snippets#show', namespace_id: 'gitlab', project_id: 'gitlabhq', id: '1') + end end # test_project_hook POST /:project_id/hooks/:id/test(.:format) hooks#test diff --git a/spec/services/alert_management/alerts/update_service_spec.rb b/spec/services/alert_management/alerts/update_service_spec.rb index e185e67c5cf..69a9287ce2a 100644 --- a/spec/services/alert_management/alerts/update_service_spec.rb +++ b/spec/services/alert_management/alerts/update_service_spec.rb @@ -4,6 +4,7 @@ require 'spec_helper' describe AlertManagement::Alerts::UpdateService do let_it_be(:user_with_permissions) { create(:user) } + let_it_be(:other_user_with_permissions) { create(:user) } let_it_be(:user_without_permissions) { create(:user) } let_it_be(:alert, reload: true) { create(:alert_management_alert) } let_it_be(:project) { alert.project } @@ -15,119 +16,131 @@ describe AlertManagement::Alerts::UpdateService do before_all do project.add_developer(user_with_permissions) + project.add_developer(other_user_with_permissions) end describe '#execute' do + shared_examples 'does not add a todo' do + specify { expect { response }.not_to change(Todo, :count) } + end + + shared_examples 'does not add a system note' do + specify { expect { response }.not_to change(Note, :count) } + end + + shared_examples 'error response' do |message| + it_behaves_like 'does not add a todo' + it_behaves_like 'does not add a system note' + + it 'has an informative message' do + expect(response).to be_error + expect(response.message).to eq(message) + end + end + subject(:response) { service.execute } context 'when the current_user is nil' do let(:current_user) { nil } - it 'results in an error' do - expect(response).to be_error - expect(response.message).to eq('You have no permissions') - end + it_behaves_like 'error response', 'You have no permissions' end - context 'when user does not have permission to update alerts' do + context 'when current_user does not have permission to update alerts' do let(:current_user) { user_without_permissions } - it 'results in an error' do - expect(response).to be_error - expect(response.message).to eq('You have no permissions') - end + it_behaves_like 'error response', 'You have no permissions' end context 'when no parameters are included' do - it 'results in an error' do - expect(response).to be_error - expect(response.message).to eq('Please provide attributes to update') - end + it_behaves_like 'error response', 'Please provide attributes to update' end - context 'when an error occures during update' do + context 'when an error occurs during update' do let(:params) { { title: nil } } - it 'results in an error' do - expect { response }.not_to change { alert.reload.notes.count } - expect(response).to be_error - expect(response.message).to eq("Title can't be blank") - end + it_behaves_like 'error response', "Title can't be blank" end context 'when a model attribute is included without assignees' do let(:params) { { title: 'This is an updated alert.' } } + it_behaves_like 'does not add a todo' + it_behaves_like 'does not add a system note' + it 'updates the attribute' do original_title = alert.title expect { response }.to change { alert.title }.from(original_title).to(params[:title]) expect(response).to be_success end - - it 'skips adding a todo' do - expect { response }.not_to change(Todo, :count) - end end context 'when assignees are included' do - let(:params) { { assignees: [user_with_permissions] } } + shared_examples 'adds a todo' do + let(:assignee) { expected_assignees.first } - after do - alert.assignees = [] + specify do + expect { response }.to change { assignee.reload.todos.count }.by(1) + expect(assignee.todos.last.author).to eq(current_user) + end end - it 'assigns the user' do - expect { response }.to change { alert.reload.assignees }.from([]).to(params[:assignees]) - expect(response).to be_success + shared_examples 'adds a system note' do + specify { expect { response }.to change { alert.reload.notes.count }.by(1) } end - it 'creates a system note for the assignment' do - expect { response }.to change { alert.reload.notes.count }.by(1) - end + shared_examples 'successful assignment' do + it_behaves_like 'adds a system note' + it_behaves_like 'adds a todo' - it 'adds a todo' do - expect { response }.to change { Todo.where(user: user_with_permissions).count }.by(1) + after do + alert.assignees = [] + end + + specify do + expect { response }.to change { alert.reload.assignees }.from([]).to(expected_assignees) + expect(response).to be_success + end end - context 'when current user is not the assignee' do - let(:assignee_user) { create(:user) } - let(:params) { { assignees: [assignee_user] } } + let(:expected_assignees) { params[:assignees] } - it 'skips adding todo for assignee without permission to read alert' do - expect { response }.not_to change(Todo, :count) - end + context 'when the assignee is the current user' do + let(:params) { { assignees: [current_user] } } - context 'when assignee has read permission' do - before do - project.add_developer(assignee_user) - end + it_behaves_like 'successful assignment' + end - it 'adds a todo' do - response + context 'when the assignee has read permissions' do + let(:params) { { assignees: [other_user_with_permissions] } } - expect(Todo.first.author).to eq(current_user) - end - end + it_behaves_like 'successful assignment' + end - context 'when current_user is nil' do - let(:current_user) { nil } + context 'when the assignee does not have read permissions' do + let(:params) { { assignees: [user_without_permissions] } } - it 'skips adding todo if current_user is nil' do - project.add_developer(assignee_user) + it_behaves_like 'error response', 'Assignee has no permissions' + end - expect { response }.not_to change(Todo, :count) - end + context 'when user is already assigned' do + let(:params) { { assignees: [user_with_permissions] } } + + before do + alert.assignees << user_with_permissions end + + it_behaves_like 'does not add a system note' + # TODO: We should not add another todo in this scenario + it_behaves_like 'adds a todo' end context 'with multiple users included' do let(:params) { { assignees: [user_with_permissions, user_without_permissions] } } + let(:expected_assignees) { [user_with_permissions] } - it 'assigns the first permissioned user' do - expect { response }.to change { alert.reload.assignees }.from([]).to([user_with_permissions]) - expect(response).to be_success - end + it_behaves_like 'successful assignment' end end end diff --git a/spec/services/members/destroy_service_spec.rb b/spec/services/members/destroy_service_spec.rb index 73ac0bd7716..5b01a538d1f 100644 --- a/spec/services/members/destroy_service_spec.rb +++ b/spec/services/members/destroy_service_spec.rb @@ -56,12 +56,23 @@ describe Members::DestroyService do expect(member_user.todos_pending_count).to be(1) expect(member_user.todos_done_count).to be(1) - described_class.new(current_user).execute(member, opts) + service = described_class.new(current_user) + + if opts[:unassign_issuables] + expect(service).to receive(:enqueue_unassign_issuables).with(member) + end + + service.execute(member, opts) expect(member_user.assigned_open_merge_requests_count).to be(0) expect(member_user.assigned_open_issues_count).to be(0) expect(member_user.todos_pending_count).to be(0) expect(member_user.todos_done_count).to be(0) + + unless opts[:unassign_issuables] + expect(member_user.assigned_merge_requests.opened.count).to be(1) + expect(member_user.assigned_issues.opened.count).to be(1) + end end end @@ -100,7 +111,7 @@ describe Members::DestroyService do it_behaves_like 'a service raising Gitlab::Access::AccessDeniedError' it_behaves_like 'a service destroying a member with access' do - let(:opts) { { skip_authorization: true } } + let(:opts) { { skip_authorization: true, unassign_issuables: true } } end end @@ -114,7 +125,7 @@ describe Members::DestroyService do it_behaves_like 'a service raising Gitlab::Access::AccessDeniedError' it_behaves_like 'a service destroying a member with access' do - let(:opts) { { skip_authorization: true } } + let(:opts) { { skip_authorization: true, unassign_issuables: true } } end end end @@ -133,6 +144,12 @@ describe Members::DestroyService do end it_behaves_like 'a service destroying a member with access' + + context 'unassign issuables' do + it_behaves_like 'a service destroying a member with access' do + let(:opts) { { unassign_issuables: true } } + end + end end context 'with a group member' do @@ -143,6 +160,12 @@ describe Members::DestroyService do end it_behaves_like 'a service destroying a member with access' + + context 'unassign issuables' do + it_behaves_like 'a service destroying a member with access' do + let(:opts) { { unassign_issuables: true } } + end + end end end end diff --git a/spec/services/members/unassign_issuables_service_spec.rb b/spec/services/members/unassign_issuables_service_spec.rb new file mode 100644 index 00000000000..3f7ccb7bab3 --- /dev/null +++ b/spec/services/members/unassign_issuables_service_spec.rb @@ -0,0 +1,66 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe Members::UnassignIssuablesService do + let_it_be(:group) { create(:group, :private) } + let_it_be(:project) { create(:project, group: group) } + let_it_be(:user, reload: true) { create(:user) } + let_it_be(:assigned_issue1, reload: true) { create(:issue, project: project, assignees: [user]) } + let_it_be(:assigned_issue2, reload: true) { create(:issue, project: project, assignees: [user]) } + + let!(:assigned_merge_request1) { create(:merge_request, :simple, :closed, target_project: project, source_project: project, assignees: [user], title: 'Test1') } + let!(:assigned_merge_request2) { create(:merge_request, :simple, :opened, target_project: project, source_project: project, assignees: [user], title: 'Test2') } + + describe '#execute' do + RSpec.shared_examples 'un-assigning issuables' do |issue_count, mr_count, open_issue_count, open_mr_count| + it 'removes issuable assignments', :aggregate_failures do + expect(user.assigned_issues.count).to eq(issue_count) + expect(user.assigned_merge_requests.count).to eq(mr_count) + + subject + + expect(user.assigned_issues.count).to eq(0) + expect(user.assigned_merge_requests.count).to eq(0) + end + + it 'invalidates user cache', :aggregate_failures, :clean_gitlab_redis_cache do + expect(user.assigned_open_merge_requests_count).to eq(open_mr_count) + expect(user.assigned_open_issues_count).to eq(open_issue_count) + + subject + + expect(user.assigned_open_merge_requests_count).to eq(0) + expect(user.assigned_open_issues_count).to eq(0) + end + end + + context 'when a user leaves a project' do + before do + project.add_maintainer(user) + end + + subject { described_class.new(user, project).execute } + + it_behaves_like 'un-assigning issuables', 2, 2, 2, 1 + end + + context 'when a user leaves a group' do + let_it_be(:project2) { create(:project, group: group) } + + let_it_be(:assigned_issue3, reload: true) { create(:issue, project: project2, assignees: [user]) } + let_it_be(:assigned_issue4, reload: true) { create(:issue, project: project2, assignees: [user]) } + + let!(:assigned_merge_request3) { create(:merge_request, :simple, :closed, target_project: project2, source_project: project2, assignees: [user], title: 'Test1') } + let!(:assigned_merge_request4) { create(:merge_request, :simple, :opened, target_project: project2, source_project: project2, assignees: [user], title: 'Test2') } + + before do + group.add_maintainer(user) + end + + subject { described_class.new(user, group).execute } + + it_behaves_like 'un-assigning issuables', 4, 4, 4, 2 + end + end +end diff --git a/spec/simplecov_env.rb b/spec/simplecov_env.rb index d618c83d78e..efd0c07b1b2 100644 --- a/spec/simplecov_env.rb +++ b/spec/simplecov_env.rb @@ -1,6 +1,7 @@ # frozen_string_literal: true require 'simplecov' +require 'simplecov-cobertura' require 'active_support/core_ext/numeric/time' require_relative '../lib/gitlab/utils' @@ -12,10 +13,19 @@ module SimpleCovEnv configure_profile configure_job + configure_formatter SimpleCov.start end + def configure_formatter + SimpleCov.formatters = SimpleCov::Formatter::MultiFormatter.new([ + SimpleCov::Formatter::SimpleFormatter, + SimpleCov::Formatter::HTMLFormatter, + SimpleCov::Formatter::CoberturaFormatter + ]) + end + def configure_job SimpleCov.configure do if ENV['CI_JOB_NAME'] diff --git a/spec/support/shared_examples/requests/api/resource_milestone_events_api_shared_examples.rb b/spec/support/shared_examples/requests/api/resource_milestone_events_api_shared_examples.rb index bca51dab353..d21a9f419fd 100644 --- a/spec/support/shared_examples/requests/api/resource_milestone_events_api_shared_examples.rb +++ b/spec/support/shared_examples/requests/api/resource_milestone_events_api_shared_examples.rb @@ -16,6 +16,29 @@ RSpec.shared_examples 'resource_milestone_events API' do |parent_type, eventable expect(json_response.first['action']).to eq(event.action) end + context 'when there is an event with a milestone which is not visible for requesting user' do + let!(:private_project) { create(:project, :private) } + let!(:private_milestone) { create(:milestone, project: private_project) } + + let!(:other_user) { create(:user) } + + it 'returns the expected events' do + create_event(private_milestone) + + get api("/#{parent_type}/#{parent.id}/#{eventable_type}/#{eventable[id_name]}/resource_milestone_events", other_user) + + expect(response).to have_gitlab_http_status(:ok) + expect(response).to include_pagination_headers + expect(response.headers['X-Total']).to eq('1') + expect(json_response).to be_an Array + expect(json_response.size).to eq(1) + + expect(json_response.first['id']).to eq(event.id) + expect(json_response.first['milestone']['id']).to eq(event.milestone.id) + expect(json_response.first['action']).to eq(event.action) + end + end + it "returns a 404 error when eventable id not found" do get api("/#{parent_type}/#{parent.id}/#{eventable_type}/#{non_existing_record_id}/resource_milestone_events", user) @@ -60,6 +83,20 @@ RSpec.shared_examples 'resource_milestone_events API' do |parent_type, eventable end end + describe 'pagination' do + let!(:event1) { create_event(milestone) } + let!(:event2) { create_event(milestone) } + + # https://gitlab.com/gitlab-org/gitlab/-/issues/220192 + it 'returns the second page' do + get api("/#{parent_type}/#{parent.id}/#{eventable_type}/#{eventable[id_name]}/resource_milestone_events?page=2&per_page=1", user) + + expect(response).to have_gitlab_http_status(:ok) + expect(json_response.count).to eq(1) + expect(json_response.first['id']).to eq(event2.id) + end + end + def create_event(milestone, action: :add) create(:resource_milestone_event, eventable.class.name.underscore => eventable, milestone: milestone, action: action) end diff --git a/spec/workers/members_destroyer/unassign_issuables_worker_spec.rb b/spec/workers/members_destroyer/unassign_issuables_worker_spec.rb new file mode 100644 index 00000000000..2a325be1225 --- /dev/null +++ b/spec/workers/members_destroyer/unassign_issuables_worker_spec.rb @@ -0,0 +1,27 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe MembersDestroyer::UnassignIssuablesWorker do + let_it_be(:group) { create(:group, :private) } + let_it_be(:user, reload: true) { create(:user) } + + context 'when unsupported membership source entity' do + it 'exits early and logs error' do + params = { message: "SomeEntity is not a supported entity.", entity_type: 'SomeEntity', entity_id: group.id, user_id: user.id } + + expect(Sidekiq.logger).to receive(:error).with(params) + + described_class.new.perform(user.id, group.id, 'SomeEntity') + end + end + + it "calls the Members::UnassignIssuablesService with the params it was given" do + service = double + + expect(Members::UnassignIssuablesService).to receive(:new).with(user, group).and_return(service) + expect(service).to receive(:execute) + + described_class.new.perform(user.id, group.id, 'Group') + end +end |