Skip to content
Snippets Groups Projects
Commit 7e71f958 authored by Manolis Mavrofidis's avatar Manolis Mavrofidis Committed by manolis
Browse files

/move project functionality. Squash commit.

 Update to add all issues to be updated.
 Added functionality, proper tests, documentation and changelog.
parent 420d835e
No related branches found
No related tags found
No related merge requests found
Loading
Loading
@@ -56,6 +56,7 @@ class IssuableBaseService < BaseService
params.delete(:assignee_id)
params.delete(:due_date)
params.delete(:canonical_issue_id)
params.delete(:project)
end
 
filter_assignee(issuable)
Loading
Loading
Loading
Loading
@@ -6,7 +6,7 @@ module Issues
handle_move_between_iids(issue)
filter_spam_check_params
change_issue_duplicate(issue)
update(issue)
move_issue_to_new_project(issue) || update(issue)
end
 
def before_update(issue)
Loading
Loading
@@ -74,6 +74,17 @@ module Issues
end
end
 
def move_issue_to_new_project(issue)
target_project = params.delete(:target_project)
return unless target_project &&
issue.can_move?(current_user, target_project) &&
target_project != issue.project
update(issue)
Issues::MoveService.new(project, current_user).execute(issue, target_project)
end
private
 
def get_issue_if_allowed(project, iid)
Loading
Loading
Loading
Loading
@@ -505,6 +505,24 @@ module QuickActions
end
end
 
desc 'Move this issue to another project.'
explanation do |path_to_project|
"Moves this issue to #{path_to_project}."
end
params 'path/to/project'
condition do
issuable.is_a?(Issue) &&
issuable.persisted? &&
current_user.can?(:"admin_#{issuable.to_ability_name}", project)
end
command :move do |target_project_path|
target_project = Project.find_by_full_path(target_project_path)
if target_project.present?
@updates[:target_project] = target_project
end
end
def extract_users(params)
return [] if params.nil?
 
Loading
Loading
---
title: Allow users to move issues to other projects using a / command
merge_request: 13436
author: Manolis Mavrofidis
Loading
Loading
@@ -38,3 +38,4 @@ do.
| `/award :emoji:` | Toggle award for :emoji: |
| `/board_move ~column` | Move issue to column on the board |
| `/duplicate #issue` | Closes this issue and marks it as a duplicate of another issue |
| `/move path/to/project` | Moves issue to another project |
Loading
Loading
@@ -155,5 +155,114 @@ feature 'Issues > User uses quick actions', js: true do
end
end
end
describe 'move the issue to another project' do
let(:issue) { create(:issue, project: project) }
context 'when the project is valid', js: true do
let(:target_project) { create(:project, :public) }
before do
target_project.team << [user, :master]
sign_in(user)
visit project_issue_path(project, issue)
end
it 'moves the issue' do
write_note("/move #{target_project.full_path}")
expect(page).to have_content 'Commands applied'
expect(issue.reload).to be_closed
visit project_issue_path(target_project, issue)
expect(page).to have_content 'Issues 1'
end
end
context 'when the project is valid but the user not authorized', js: true do
let(:project_unauthorized) {create(:project, :public)}
before do
sign_in(user)
visit project_issue_path(project, issue)
end
it 'does not move the issue' do
write_note("/move #{project_unauthorized.full_path}")
expect(page).not_to have_content 'Commands applied'
expect(issue.reload).to be_open
end
end
context 'when the project is invalid', js: true do
before do
sign_in(user)
visit project_issue_path(project, issue)
end
it 'does not move the issue' do
write_note("/move not/valid")
expect(page).not_to have_content 'Commands applied'
expect(issue.reload).to be_open
end
end
context 'when the user issues multiple commands', js: true do
let(:target_project) { create(:project, :public) }
let(:milestone) { create(:milestone, title: '1.0', project: project) }
let(:target_milestone) { create(:milestone, title: '1.0', project: target_project) }
let(:bug) { create(:label, project: project, title: 'bug') }
let(:wontfix) { create(:label, project: project, title: 'wontfix') }
let(:bug_target) { create(:label, project: target_project, title: 'bug') }
let(:wontfix_target) { create(:label, project: target_project, title: 'wontfix') }
before do
target_project.team << [user, :master]
sign_in(user)
visit project_issue_path(project, issue)
end
it 'applies the commands to both issues and moves the issue' do
write_note("/label ~#{bug.title} ~#{wontfix.title}\n/milestone %\"#{milestone.title}\"\n/move #{target_project.full_path}")
expect(page).to have_content 'Commands applied'
expect(issue.reload).to be_closed
visit project_issue_path(target_project, issue)
expect(page).to have_content 'bug'
expect(page).to have_content 'wontfix'
expect(page).to have_content '1.0'
visit project_issue_path(project, issue)
expect(page).to have_content 'Closed'
expect(page).to have_content 'bug'
expect(page).to have_content 'wontfix'
expect(page).to have_content '1.0'
end
it 'moves the issue and applies the commands to both issues' do
write_note("/move #{target_project.full_path}\n/label ~#{bug.title} ~#{wontfix.title}\n/milestone %\"#{milestone.title}\"")
expect(page).to have_content 'Commands applied'
expect(issue.reload).to be_closed
visit project_issue_path(target_project, issue)
expect(page).to have_content 'bug'
expect(page).to have_content 'wontfix'
expect(page).to have_content '1.0'
visit project_issue_path(project, issue)
expect(page).to have_content 'Closed'
expect(page).to have_content 'bug'
expect(page).to have_content 'wontfix'
expect(page).to have_content '1.0'
end
end
end
end
end
Loading
Loading
@@ -510,6 +510,26 @@ describe Issues::UpdateService, :mailer do
end
end
 
context 'move issue to another project' do
let(:target_project) { create(:project) }
context 'valid project' do
before do
target_project.team << [user, :master]
end
it 'calls the move service with the proper issue and project' do
move_stub = class_double("Issues::MoveService").as_stubbed_const
allow(Issues::MoveService).to receive(:new).and_return(move_stub)
allow(move_stub).to receive(:execute).with(issue, target_project).and_return(issue)
expect(move_stub).to receive(:execute).with(issue, target_project)
update_issue(target_project: target_project)
end
end
end
include_examples 'issuable update service' do
let(:open_issuable) { issue }
let(:closed_issuable) { create(:closed_issue, project: project) }
Loading
Loading
Loading
Loading
@@ -1147,5 +1147,15 @@ describe QuickActions::InterpretService do
expect(explanations).to eq(["Moves issue to ~#{bug.id} column in the board."])
end
end
describe 'move issue to another project command' do
let(:content) { '/move test/project' }
it 'includes the project name' do
_, explanations = service.explain(content, issue)
expect(explanations).to eq(["Moves this issue to test/project."])
end
end
end
end
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment