diff --git a/app/controllers/repositories_controller.rb b/app/controllers/repositories_controller.rb index 269bc70a0..92a145c3a 100644 --- a/app/controllers/repositories_controller.rb +++ b/app/controllers/repositories_controller.rb @@ -35,6 +35,7 @@ class RepositoriesController < ApplicationController before_action :find_changeset, :only => [:revision, :add_related_issue, :remove_related_issue] before_action :authorize accept_rss_auth :revisions + accept_api_auth :add_related_issue, :remove_related_issue rescue_from Redmine::Scm::Adapters::CommandFailed, :with => :show_error_command_failed @@ -227,8 +228,14 @@ class RepositoriesController < ApplicationController @issue = nil end - if @issue - @changeset.issues << @issue + respond_to do |format| + if @issue + @changeset.issues << @issue + format.api { render_api_ok } + else + format.api { render_api_errors "#{l(:label_issue)} #{l('activerecord.errors.messages.invalid')}" } + end + format.js end end @@ -239,6 +246,10 @@ class RepositoriesController < ApplicationController if @issue @changeset.issues.delete(@issue) end + respond_to do |format| + format.api { render_api_ok } + format.js + end end def diff diff --git a/test/integration/api_test/api_routing_test.rb b/test/integration/api_test/api_routing_test.rb index 692389b2b..8af27179a 100644 --- a/test/integration/api_test/api_routing_test.rb +++ b/test/integration/api_test/api_routing_test.rb @@ -117,6 +117,11 @@ class Redmine::ApiTest::ApiRoutingTest < Redmine::ApiTest::Routing should_route 'GET /queries' => 'queries#index' end + def test_repositories + should_route 'POST /projects/1/repository/2/revisions/3/issues' => 'repositories#add_related_issue', :id => '1', :repository_id => '2', :rev => '3' + should_route 'DELETE /projects/1/repository/2/revisions/3/issues/4' => 'repositories#remove_related_issue', :id => '1', :repository_id => '2', :rev => '3', :issue_id => '4' + end + def test_roles should_route 'GET /roles' => 'roles#index' should_route 'GET /roles/2' => 'roles#show', :id => '2' diff --git a/test/integration/api_test/repositories_test.rb b/test/integration/api_test/repositories_test.rb new file mode 100644 index 000000000..29ca13d29 --- /dev/null +++ b/test/integration/api_test/repositories_test.rb @@ -0,0 +1,107 @@ +# frozen_string_literal: true + +# Redmine - project management software +# Copyright (C) 2006-2019 Jean-Philippe Lang +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + +require File.expand_path('../../../test_helper', __FILE__) + +class Redmine::ApiTest::RepositoriesTest < Redmine::ApiTest::Base + fixtures :users, + :projects, :enabled_modules, + :members, :roles, :member_roles, + :issues, + :repositories, :changesets, :changes + + test 'POST /projects/:id/repository/:repository_id/revisions/:rev/issues.xml should add related issue' do + changeset = Changeset.find(103) + assert_equal [], changeset.issue_ids + assert_difference 'Changeset.find(103).issues.size' do + post '/projects/1/repository/10/revisions/4/issues.xml', :headers => credentials('jsmith'), :params => {:issue_id => '2'} + end + assert_response :no_content + assert_equal [2], changeset.reload.issue_ids + end + + test 'POST /projects/:id/repository/:repository_id/revisions/:rev/issues.json should add related issue' do + changeset = Changeset.find(103) + assert_equal [], changeset.issue_ids + assert_difference 'Changeset.find(103).issues.size' do + post '/projects/1/repository/10/revisions/4/issues.json', :headers => credentials('jsmith'), :params => {:issue_id => '2'} + end + assert_response :no_content + assert_equal [2], changeset.reload.issue_ids + end + + test 'POST /projects/:id/repository/:repository_id/revisions/:rev/issues.xml should accept issue_id with sharp' do + changeset = Changeset.find(103) + assert_equal [], changeset.issue_ids + assert_difference 'Changeset.find(103).issues.size' do + post '/projects/1/repository/10/revisions/4/issues.xml', :headers => credentials('jsmith'), :params => {:issue_id => '#2'} + end + assert_response :no_content + assert_equal [2], changeset.reload.issue_ids + end + + test 'POST /projects/:id/repository/:repository_id/revisions/:rev/issues.json should accept issue_id with sharp' do + changeset = Changeset.find(103) + assert_equal [], changeset.issue_ids + assert_difference 'Changeset.find(103).issues.size' do + post '/projects/1/repository/10/revisions/4/issues.json', :headers => credentials('jsmith'), :params => {:issue_id => '#2'} + end + assert_response :no_content + assert_equal [2], changeset.reload.issue_ids + end + + test 'POST /projects/:id/repository/:repository_id/revisions/:rev/issues.xml with invalid issue_id' do + assert_no_difference 'Changeset.find(103).issues.size' do + post '/projects/1/repository/10/revisions/4/issues.xml', :headers => credentials('jsmith'), :params => {:issue_id => '9999'} + end + assert_response :unprocessable_entity + assert_select 'errors error', :text => 'Issue is invalid' + end + + test 'POST /projects/:id/repository/:repository_id/revisions/:rev/issues.json with invalid issue_id' do + assert_no_difference 'Changeset.find(103).issues.size' do + post '/projects/1/repository/10/revisions/4/issues.json', :headers => credentials('jsmith'), :params => {:issue_id => '9999'} + end + assert_response :unprocessable_entity + json = ActiveSupport::JSON.decode(response.body) + assert json['errors'].include?('Issue is invalid') + end + + test 'DELETE /projects/:id/repository/:repository_id/revisions/:rev/issues/:issue_id.xml should remove related issue' do + changeset = Changeset.find(103) + changeset.issues << Issue.find(1) + changeset.issues << Issue.find(2) + assert_difference 'Changeset.find(103).issues.size', -1 do + delete '/projects/1/repository/10/revisions/4/issues/2.xml', :headers => credentials('jsmith') + end + assert_response :no_content + assert_equal [1], changeset.reload.issue_ids + end + + test 'DELETE /projects/:id/repository/:repository_id/revisions/:rev/issues/:issue_id.json should remove related issue' do + changeset = Changeset.find(103) + changeset.issues << Issue.find(1) + changeset.issues << Issue.find(2) + assert_difference 'Changeset.find(103).issues.size', -1 do + delete '/projects/1/repository/10/revisions/4/issues/2.json', :headers => credentials('jsmith') + end + assert_response :no_content + assert_equal [1], changeset.reload.issue_ids + end +end