Commit 259c0cc0 authored by GitLab Bot's avatar GitLab Bot

Add latest changes from gitlab-org/gitlab@master

parent 01de60f3
......@@ -121,7 +121,7 @@ module IssuableActions
end
def bulk_update
result = Issuable::BulkUpdateService.new(current_user, bulk_update_params).execute(resource_name)
result = Issuable::BulkUpdateService.new(parent, current_user, bulk_update_params).execute(resource_name)
quantity = result[:count]
render json: { notice: "#{quantity} #{resource_name.pluralize(quantity)} updated" }
......
......@@ -133,8 +133,6 @@ class Projects::BranchesController < Projects::ApplicationController
# frontend could omit this set. To prevent excessive I/O, we require
# that a list of names be specified.
def limit_diverging_commit_counts!
return unless Feature.enabled?(:limit_diverging_commit_counts, default_enabled: true)
limit = Kaminari.config.default_per_page
# If we don't have many branches in the repository, then go ahead.
......
......@@ -4,19 +4,18 @@ module Issuable
class BulkUpdateService
include Gitlab::Allowable
attr_accessor :current_user, :params
attr_accessor :parent, :current_user, :params
def initialize(user = nil, params = {})
@current_user, @params = user, params.dup
def initialize(parent, user = nil, params = {})
@parent, @current_user, @params = parent, user, params.dup
end
# rubocop: disable CodeReuse/ActiveRecord
def execute(type)
model_class = type.classify.constantize
update_class = type.classify.pluralize.constantize::UpdateService
ids = params.delete(:issuable_ids).split(",")
items = model_class.where(id: ids)
items = find_issuables(parent, model_class, ids)
permitted_attrs(type).each do |key|
params.delete(key) unless params[key].present?
......@@ -37,7 +36,6 @@ module Issuable
success: !items.count.zero?
}
end
# rubocop: enable CodeReuse/ActiveRecord
private
......@@ -50,5 +48,15 @@ module Issuable
attrs.push(:assignee_id)
end
end
def find_issuables(parent, model_class, ids)
if parent.is_a?(Project)
model_class.id_in(ids).of_projects(parent)
elsif parent.is_a?(Group)
model_class.id_in(ids).of_projects(parent.all_projects)
end
end
end
end
Issuable::BulkUpdateService.prepend_if_ee('EE::Issuable::BulkUpdateService')
---
title: Remove feature flag for limiting diverging commit counts
merge_request: 20999
author:
type: other
......@@ -92,6 +92,7 @@ describe('DiffFileHeader component', () => {
localVue,
store,
sync: false,
attachToDocument: true,
});
};
......
......@@ -15,10 +15,11 @@ describe('DiffGutterAvatars', () => {
const createComponent = (props = {}) => {
wrapper = shallowMount(DiffGutterAvatars, {
localVue,
sync: false,
propsData: {
...props,
},
sync: false,
attachToDocument: true,
});
};
......
......@@ -10,8 +10,9 @@ describe('EditButton', () => {
const createComponent = (props = {}) => {
wrapper = shallowMount(EditButton, {
localVue,
sync: false,
propsData: { ...props },
sync: false,
attachToDocument: true,
});
};
......
......@@ -3,25 +3,31 @@ import App from '~/issuable_suggestions/components/app.vue';
import Suggestion from '~/issuable_suggestions/components/item.vue';
describe('Issuable suggestions app component', () => {
let vm;
let wrapper;
function createComponent(search = 'search') {
vm = shallowMount(App, {
wrapper = shallowMount(App, {
propsData: {
search,
projectPath: 'project',
},
sync: false,
attachToDocument: true,
});
}
beforeEach(() => {
createComponent();
});
afterEach(() => {
vm.destroy();
wrapper.destroy();
});
it('does not render with empty search', () => {
createComponent('');
wrapper.setProps({ search: '' });
expect(vm.isVisible()).toBe(false);
expect(wrapper.isVisible()).toBe(false);
});
describe('with data', () => {
......@@ -32,65 +38,65 @@ describe('Issuable suggestions app component', () => {
});
it('renders component', () => {
createComponent();
vm.setData(data);
wrapper.setData(data);
expect(vm.isEmpty()).toBe(false);
expect(wrapper.isEmpty()).toBe(false);
});
it('does not render with empty search', () => {
createComponent('');
vm.setData(data);
wrapper.setProps({ search: '' });
wrapper.setData(data);
expect(vm.isVisible()).toBe(false);
expect(wrapper.isVisible()).toBe(false);
});
it('does not render when loading', () => {
createComponent();
vm.setData({
wrapper.setData({
...data,
loading: 1,
});
expect(vm.isVisible()).toBe(false);
expect(wrapper.isVisible()).toBe(false);
});
it('does not render with empty issues data', () => {
createComponent();
vm.setData({ issues: [] });
wrapper.setData({ issues: [] });
expect(vm.isVisible()).toBe(false);
expect(wrapper.isVisible()).toBe(false);
});
it('renders list of issues', () => {
createComponent();
vm.setData(data);
wrapper.setData(data);
expect(vm.findAll(Suggestion).length).toBe(2);
return wrapper.vm.$nextTick(() => {
expect(wrapper.findAll(Suggestion).length).toBe(2);
});
});
it('adds margin class to first item', () => {
createComponent();
vm.setData(data);
expect(
vm
.findAll('li')
.at(0)
.is('.append-bottom-default'),
).toBe(true);
wrapper.setData(data);
return wrapper.vm.$nextTick(() => {
expect(
wrapper
.findAll('li')
.at(0)
.is('.append-bottom-default'),
).toBe(true);
});
});
it('does not add margin class to last item', () => {
createComponent();
vm.setData(data);
expect(
vm
.findAll('li')
.at(1)
.is('.append-bottom-default'),
).toBe(false);
wrapper.setData(data);
return wrapper.vm.$nextTick(() => {
expect(
wrapper
.findAll('li')
.at(1)
.is('.append-bottom-default'),
).toBe(false);
});
});
});
});
......@@ -16,6 +16,8 @@ describe('Issuable suggestions suggestion component', () => {
...suggestion,
},
},
sync: false,
attachToDocument: true,
});
}
......
......@@ -11,7 +11,7 @@ describe Issuable::BulkUpdateService do
.reverse_merge(issuable_ids: Array(issuables).map(&:id).join(','))
type = Array(issuables).first.model_name.param_key
Issuable::BulkUpdateService.new(user, bulk_update_params).execute(type)
Issuable::BulkUpdateService.new(parent, user, bulk_update_params).execute(type)
end
shared_examples 'updates milestones' do
......@@ -184,6 +184,8 @@ describe Issuable::BulkUpdateService do
end
context 'with issuables at a project level' do
let(:parent) { project }
describe 'close issues' do
let(:issues) { create_list(:issue, 2, project: project) }
......@@ -200,33 +202,6 @@ describe Issuable::BulkUpdateService do
expect(project.issues.opened).to be_empty
expect(project.issues.closed).not_to be_empty
end
context 'when issue for a different project is created' do
let(:private_project) { create(:project, :private) }
let(:issue) { create(:issue, project: private_project, author: user) }
context 'when user has access to the project' do
it 'closes all issues passed' do
private_project.add_maintainer(user)
bulk_update(issues + [issue], state_event: 'close')
expect(project.issues.opened).to be_empty
expect(project.issues.closed).not_to be_empty
expect(private_project.issues.closed).not_to be_empty
end
end
context 'when user does not have access to project' do
it 'only closes all issues that the user has access to' do
bulk_update(issues + [issue], state_event: 'close')
expect(project.issues.opened).to be_empty
expect(project.issues.closed).not_to be_empty
expect(private_project.issues.closed).to be_empty
end
end
end
end
describe 'reopen issues' do
......@@ -362,10 +337,29 @@ describe Issuable::BulkUpdateService do
end
end
end
describe 'updating issues from external project' do
it 'updates only issues that belong to the parent project' do
issue1 = create(:issue, project: project)
issue2 = create(:issue, project: create(:project))
result = bulk_update([issue1, issue2], assignee_ids: [user.id])
expect(result[:success]).to be_truthy
expect(result[:count]).to eq(1)
expect(issue1.reload.assignees).to eq([user])
expect(issue2.reload.assignees).to be_empty
end
end
end
context 'with issuables at a group level' do
let(:group) { create(:group) }
let(:parent) { group }
before do
group.add_reporter(user)
end
describe 'updating milestones' do
let(:milestone) { create(:milestone, group: group) }
......@@ -398,11 +392,24 @@ describe Issuable::BulkUpdateService do
let(:regression) { create(:group_label, group: group) }
let(:merge_requests) { create(:group_label, group: group) }
before do
group.add_reporter(user)
end
it_behaves_like 'updating labels'
end
describe 'with issues from external group' do
it 'updates issues that belong to the parent group or descendants' do
issue1 = create(:issue, project: create(:project, group: group))
issue2 = create(:issue, project: create(:project, group: create(:group)))
issue3 = create(:issue, project: create(:project, group: create(:group, parent: group)))
milestone = create(:milestone, group: group)
result = bulk_update([issue1, issue2, issue3], milestone_id: milestone.id)
expect(result[:success]).to be_truthy
expect(result[:count]).to eq(2)
expect(issue1.reload.milestone).to eq(milestone)
expect(issue2.reload.milestone).to be_nil
expect(issue3.reload.milestone).to eq(milestone)
end
end
end
end
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment