Fix "ArgumentError: Invalid response name: unprocessable_entity" with Rack 3.1.0+ in assert_response (#39889).

Rack 3.1.0 changed the symbol for HTTP status code 422 from `:unprocessable_entity` to `:unprocessable_content`.
Due to the change, `assert_response(:unprocessable_entity, ...)` raises ArgumentError with Rack 3.1.0+.

This fix is a follow-up to r22837.


git-svn-id: https://svn.redmine.org/redmine/trunk@22876 e93f8b46-1217-0410-a6f0-8f06a7374b81
This commit is contained in:
Go MAEDA
2024-06-12 16:09:37 +00:00
parent e41bc39322
commit b803bddb1f
33 changed files with 56 additions and 55 deletions

View File

@@ -15,6 +15,7 @@ gem 'rbpdf', '~> 1.21.3'
gem 'addressable'
gem 'rubyzip', '~> 2.3.0'
gem 'propshaft', '~> 0.8.0'
gem 'rack', '>= 3.1.3'
# Ruby Standard Gems
gem 'csv', '~> 3.2.8'

View File

@@ -766,7 +766,7 @@ class ApplicationController < ActionController::Base
def render_api_errors(*messages)
@error_messages = messages.flatten
render :template => 'common/error_messages', :format => [:api], :status => :unprocessable_entity, :layout => nil
render :template => 'common/error_messages', :format => [:api], :status => :unprocessable_content, :layout => nil
end
# Overrides #_include_layout? so that #render with no arguments

View File

@@ -98,7 +98,7 @@ class BoardsController < ApplicationController
else
respond_to do |format|
format.html {render :action => 'edit'}
format.js {head :unprocessable_entity}
format.js {head :unprocessable_content}
end
end
end

View File

@@ -75,7 +75,7 @@ class CustomFieldsController < ApplicationController
else
respond_to do |format|
format.html {render :action => 'edit'}
format.js {head :unprocessable_entity}
format.js {head :unprocessable_content}
end
end
end

View File

@@ -70,7 +70,7 @@ class EnumerationsController < ApplicationController
else
respond_to do |format|
format.html {render :action => 'edit'}
format.js {head :unprocessable_entity}
format.js {head :unprocessable_content}
end
end
end

View File

@@ -66,7 +66,7 @@ class IssueStatusesController < ApplicationController
else
respond_to do |format|
format.html {render :action => 'edit'}
format.js {head :unprocessable_entity}
format.js {head :unprocessable_content}
end
end
end

View File

@@ -84,7 +84,7 @@ class IssuesController < ApplicationController
else
respond_to do |format|
format.html {render :layout => !request.xhr?}
format.any(:atom, :csv, :pdf) {head :unprocessable_entity}
format.any(:atom, :csv, :pdf) {head :unprocessable_content}
format.api {render_validation_errors(@query)}
end
end

View File

@@ -61,7 +61,7 @@ class MailHandlerController < ActionController::Base
if MailHandler.safe_receive(email, options)
head :created
else
head :unprocessable_entity
head :unprocessable_content
end
end

View File

@@ -115,7 +115,7 @@ class MembersController < ApplicationController
if @member.destroyed?
render_api_ok
else
head :unprocessable_entity
head :unprocessable_content
end
end
end

View File

@@ -90,7 +90,7 @@ class RolesController < ApplicationController
else
respond_to do |format|
format.html {render :action => 'edit'}
format.js {head :unprocessable_entity}
format.js {head :unprocessable_content}
end
end
end

View File

@@ -46,7 +46,7 @@ class SysController < ActionController::Base
if repository.save
render :json => {repository.class.name.underscore.tr('/', '-') => {:id => repository.id, :url => repository.url}}, :status => :created
else
head :unprocessable_entity
head :unprocessable_content
end
end
end

View File

@@ -81,7 +81,7 @@ class TrackersController < ApplicationController
edit
render :action => 'edit'
end
format.js {head :unprocessable_entity}
format.js {head :unprocessable_content}
end
end
end

View File

@@ -81,7 +81,7 @@ class UsersController < ApplicationController
else
respond_to do |format|
format.html {render :layout => !request.xhr?}
format.csv {head :unprocessable_entity}
format.csv {head :unprocessable_content}
format.api {render_validation_errors(@query)}
end
end

View File

@@ -165,7 +165,7 @@ class VersionsController < ApplicationController
flash[:error] = l(:notice_unable_delete_version)
redirect_to settings_project_path(@project, :tab => 'versions')
end
format.api {head :unprocessable_entity}
format.api {head :unprocessable_content}
end
end
end

View File

@@ -4748,7 +4748,7 @@ class IssuesControllerTest < Redmine::ControllerTest
}
}
)
assert_response :unprocessable_entity
assert_response :unprocessable_content
end
end

View File

@@ -117,7 +117,7 @@ class MailHandlerControllerTest < Redmine::ControllerTest
)
end
end
assert_response :unprocessable_entity
assert_response :unprocessable_content
end
def test_should_not_allow_with_api_disabled

View File

@@ -730,7 +730,7 @@ class MyControllerTest < Redmine::ControllerTest
:block => 'invalid'
}
)
assert_response :unprocessable_entity
assert_response :unprocessable_content
end
def test_remove_block

View File

@@ -95,7 +95,7 @@ class SysControllerTest < Redmine::ControllerTest
:repository => {:url => 'invalid url'}
}
)
assert_response :unprocessable_entity
assert_response :unprocessable_content
end
def test_fetch_changesets

View File

@@ -1114,7 +1114,7 @@ class UsersControllerTest < Redmine::ControllerTest
assert_no_difference 'User.count' do
delete :destroy, params: {id: user.id}
end
assert_response :unprocessable_entity
assert_response :unprocessable_content
end
end
@@ -1125,7 +1125,7 @@ class UsersControllerTest < Redmine::ControllerTest
assert_no_difference 'User.count' do
delete :destroy, params: {id: user.id}
end
assert_response :unprocessable_entity
assert_response :unprocessable_content
end
end

View File

@@ -118,7 +118,7 @@ class Redmine::ApiTest::AttachmentsTest < Redmine::ApiTest::Base
:params => {:attachment => {:filename => '', :description => 'updated'}},
:headers => credentials('jsmith')
)
assert_response :unprocessable_entity
assert_response :unprocessable_content
assert_equal 'application/json', response.media_type
json = ActiveSupport::JSON.decode(response.body)
assert_include "File cannot be blank", json['errors']
@@ -224,7 +224,7 @@ class Redmine::ApiTest::AttachmentsTest < Redmine::ApiTest::Base
"CONTENT_TYPE" => 'application/octet-stream'
}.merge(credentials('jsmith'))
)
assert_response :unprocessable_entity
assert_response :unprocessable_content
assert_select 'error', :text => /exceeds the maximum allowed file size/
end
end

View File

@@ -150,7 +150,7 @@ class Redmine::ApiTest::GroupsTest < Redmine::ApiTest::Base
:headers => credentials('admin')
)
end
assert_response :unprocessable_entity
assert_response :unprocessable_content
assert_equal 'application/xml', response.media_type
assert_select 'errors' do
@@ -179,7 +179,7 @@ class Redmine::ApiTest::GroupsTest < Redmine::ApiTest::Base
:params => {:group => {:name => ''}},
:headers => credentials('admin')
)
assert_response :unprocessable_entity
assert_response :unprocessable_content
assert_equal 'application/xml', response.media_type
assert_select 'errors' do
@@ -220,7 +220,7 @@ class Redmine::ApiTest::GroupsTest < Redmine::ApiTest::Base
:params => {:user_id => 5},
:headers => credentials('admin')
)
assert_response :unprocessable_entity
assert_response :unprocessable_content
end
assert_select 'errors' do

View File

@@ -62,7 +62,7 @@ class Redmine::ApiTest::IssueCategoriesTest < Redmine::ApiTest::Base
:params => {:issue_category => {:name => ''}},
:headers => credentials('jsmith'))
end
assert_response :unprocessable_entity
assert_response :unprocessable_content
assert_equal 'application/xml', @response.media_type
assert_select 'errors error', :text => "Name cannot be blank"
@@ -87,7 +87,7 @@ class Redmine::ApiTest::IssueCategoriesTest < Redmine::ApiTest::Base
:params => {:issue_category => {:name => ''}},
:headers => credentials('jsmith'))
end
assert_response :unprocessable_entity
assert_response :unprocessable_content
assert_equal 'application/xml', @response.media_type
assert_select 'errors error', :text => "Name cannot be blank"

View File

@@ -87,7 +87,7 @@ class Redmine::ApiTest::IssueRelationsTest < Redmine::ApiTest::Base
)
end
assert_response :unprocessable_entity
assert_response :unprocessable_content
assert_select 'errors error', :text => /Relation type is not included in the list/
end

View File

@@ -105,7 +105,7 @@ class Redmine::ApiTest::IssuesTest < Redmine::ApiTest::Base
test "GET /issues.xml with invalid query params" do
get '/issues.xml', :params => {:f => ['start_date'], :op => {:start_date => '='}}
assert_response :unprocessable_entity
assert_response :unprocessable_content
assert_equal 'application/xml', @response.media_type
assert_select 'errors error', :text => "Start date cannot be blank"
end
@@ -725,7 +725,7 @@ class Redmine::ApiTest::IssuesTest < Redmine::ApiTest::Base
'/issues.json',
:params => {:issue => {:project_id => 999, :subject => "API"}},
:headers => credentials('jsmith'))
assert_response :unprocessable_entity
assert_response :unprocessable_content
end
test "POST /issues.json with invalid project_id and any assigned_to_id should respond with 422" do
@@ -739,7 +739,7 @@ class Redmine::ApiTest::IssuesTest < Redmine::ApiTest::Base
}
},
:headers => credentials('jsmith'))
assert_response :unprocessable_entity
assert_response :unprocessable_content
end
test "POST /issues.json with invalid project_id and any fixed_version_id should respond with 422" do
@@ -753,7 +753,7 @@ class Redmine::ApiTest::IssuesTest < Redmine::ApiTest::Base
}
},
:headers => credentials('jsmith'))
assert_response :unprocessable_entity
assert_response :unprocessable_content
end
test "PUT /issues/:id.xml" do
@@ -885,7 +885,7 @@ class Redmine::ApiTest::IssuesTest < Redmine::ApiTest::Base
'/issues/6.xml',
:params => {:issue => {:subject => ''}},
:headers => credentials('jsmith'))
assert_response :unprocessable_entity
assert_response :unprocessable_content
assert_select 'errors error', :text => "Subject cannot be blank"
end
@@ -895,7 +895,7 @@ class Redmine::ApiTest::IssuesTest < Redmine::ApiTest::Base
'/issues/6.xml',
:params => {:issue => {:assigned_to_id => user.id}},
:headers => credentials('jsmith'))
assert_response :unprocessable_entity
assert_response :unprocessable_content
assert_select 'errors error', :text => "Assignee is invalid"
end
@@ -920,7 +920,7 @@ class Redmine::ApiTest::IssuesTest < Redmine::ApiTest::Base
'/issues/6.json',
:params => {:issue => {:subject => ''}},
:headers => credentials('jsmith'))
assert_response :unprocessable_entity
assert_response :unprocessable_content
json = ActiveSupport::JSON.decode(response.body)
assert json['errors'].include?("Subject cannot be blank")
end

View File

@@ -101,7 +101,7 @@ class Redmine::ApiTest::MembershipsTest < Redmine::ApiTest::Base
:params => {:membership => {:role_ids => [2, 3]}},
:headers => credentials('jsmith')
)
assert_response :unprocessable_entity
assert_response :unprocessable_content
assert_equal 'application/xml', @response.media_type
assert_select 'errors error', :text => 'User or Group cannot be blank'
end
@@ -158,7 +158,7 @@ class Redmine::ApiTest::MembershipsTest < Redmine::ApiTest::Base
:params => {:membership => {:user_id => 3, :role_ids => [99]}},
:headers => credentials('jsmith')
)
assert_response :unprocessable_entity
assert_response :unprocessable_content
assert_equal 'application/xml', @response.media_type
assert_select 'errors error', :text => "Role cannot be empty"
end
@@ -179,7 +179,7 @@ class Redmine::ApiTest::MembershipsTest < Redmine::ApiTest::Base
Member.find(2).member_roles.first.update_attribute :inherited_from, 99
delete '/memberships/2.xml', :headers => credentials('jsmith')
assert_response :unprocessable_entity
assert_response :unprocessable_content
end
end
end

View File

@@ -81,7 +81,7 @@ class Redmine::ApiTest::MyTest < Redmine::ApiTest::Base
}
},
:headers => credentials('dlopper', 'foo'))
assert_response :unprocessable_entity
assert_response :unprocessable_content
assert_equal 'application/xml', @response.media_type
assert_select 'errors error', :text => "First name cannot be blank"
end
@@ -95,7 +95,7 @@ class Redmine::ApiTest::MyTest < Redmine::ApiTest::Base
}
},
:headers => credentials('dlopper', 'foo'))
assert_response :unprocessable_entity
assert_response :unprocessable_content
assert_equal 'application/json', @response.media_type
json = ActiveSupport::JSON.decode(response.body)
assert_kind_of Hash, json

View File

@@ -310,7 +310,7 @@ class Redmine::ApiTest::NewsTest < Redmine::ApiTest::Base
'/news/1.xml',
:params => {:news => {:title => ''}},
:headers => credentials('jsmith'))
assert_response :unprocessable_entity
assert_response :unprocessable_content
assert_select 'errors error', :text => "Title cannot be blank"
end
@@ -319,7 +319,7 @@ class Redmine::ApiTest::NewsTest < Redmine::ApiTest::Base
'/news/1.json',
:params => {:news => {:title => ''}},
:headers => credentials('jsmith'))
assert_response :unprocessable_entity
assert_response :unprocessable_content
json = ActiveSupport::JSON.decode(response.body)
assert json['errors'].include?("Title cannot be blank")
end

View File

@@ -304,7 +304,7 @@ class Redmine::ApiTest::ProjectsTest < Redmine::ApiTest::Base
)
end
assert_response :unprocessable_entity
assert_response :unprocessable_content
assert_equal 'application/xml', @response.media_type
assert_select 'errors error', :text => "Identifier cannot be blank"
end
@@ -366,7 +366,7 @@ class Redmine::ApiTest::ProjectsTest < Redmine::ApiTest::Base
)
end
assert_response :unprocessable_entity
assert_response :unprocessable_content
assert_equal 'application/xml', @response.media_type
assert_select 'errors error', :text => "Name cannot be blank"
end

View File

@@ -70,7 +70,7 @@ class Redmine::ApiTest::RepositoriesTest < Redmine::ApiTest::Base
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_response :unprocessable_content
assert_select 'errors error', :text => 'Issue is invalid'
end
@@ -78,7 +78,7 @@ class Redmine::ApiTest::RepositoriesTest < Redmine::ApiTest::Base
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
assert_response :unprocessable_content
json = ActiveSupport::JSON.decode(response.body)
assert json['errors'].include?('Issue is invalid')
end

View File

@@ -141,7 +141,7 @@ class Redmine::ApiTest::TimeEntriesTest < Redmine::ApiTest::Base
:params => {:time_entry => {:project_id => '1', :spent_on => '2010-12-02', :activity_id => '11'}},
:headers => credentials('jsmith'))
end
assert_response :unprocessable_entity
assert_response :unprocessable_content
assert_equal 'application/xml', @response.media_type
assert_select 'errors error', :text => "Hours cannot be blank"
@@ -200,7 +200,7 @@ class Redmine::ApiTest::TimeEntriesTest < Redmine::ApiTest::Base
:params => {:time_entry => {:hours => '', :comments => 'API Update'}},
:headers => credentials('jsmith'))
end
assert_response :unprocessable_entity
assert_response :unprocessable_content
assert_equal 'application/xml', @response.media_type
assert_select 'errors error', :text => "Hours cannot be blank"
@@ -229,7 +229,7 @@ class Redmine::ApiTest::TimeEntriesTest < Redmine::ApiTest::Base
assert_no_difference 'TimeEntry.count' do
delete '/time_entries/2.xml', :headers => credentials('jsmith')
end
assert_response :unprocessable_entity
assert_response :unprocessable_content
assert_equal 'application/xml', @response.media_type
assert_select 'errors'
end

View File

@@ -417,7 +417,7 @@ class Redmine::ApiTest::UsersTest < Redmine::ApiTest::Base
:headers => credentials('admin'))
end
assert_response :unprocessable_entity
assert_response :unprocessable_content
assert_equal 'application/xml', @response.media_type
assert_select 'errors error', :text => "First name cannot be blank"
end
@@ -434,7 +434,7 @@ class Redmine::ApiTest::UsersTest < Redmine::ApiTest::Base
:headers => credentials('admin'))
end
assert_response :unprocessable_entity
assert_response :unprocessable_content
assert_equal 'application/json', @response.media_type
json = ActiveSupport::JSON.decode(response.body)
assert_kind_of Hash, json
@@ -503,7 +503,7 @@ class Redmine::ApiTest::UsersTest < Redmine::ApiTest::Base
:headers => credentials('admin'))
end
assert_response :unprocessable_entity
assert_response :unprocessable_content
assert_equal 'application/xml', @response.media_type
assert_select 'errors error', :text => "First name cannot be blank"
end
@@ -521,7 +521,7 @@ class Redmine::ApiTest::UsersTest < Redmine::ApiTest::Base
:headers => credentials('admin'))
end
assert_response :unprocessable_entity
assert_response :unprocessable_content
assert_equal 'application/json', @response.media_type
json = ActiveSupport::JSON.decode(response.body)
assert_kind_of Hash, json

View File

@@ -120,7 +120,7 @@ class Redmine::ApiTest::VersionsTest < Redmine::ApiTest::Base
:params => {:version => {:name => ''}},
:headers => credentials('jsmith'))
end
assert_response :unprocessable_entity
assert_response :unprocessable_content
assert_select 'errors error', :text => "Name cannot be blank"
end

View File

@@ -73,7 +73,7 @@ class ApplicationTest < Redmine::IntegrationTest
def test_invalid_token_should_call_custom_handler
ActionController::Base.allow_forgery_protection = true
post '/issues'
assert_response :unprocessable_entity
assert_response :unprocessable_content
assert_include "Invalid form authenticity token.", response.body
ensure
ActionController::Base.allow_forgery_protection = false
@@ -83,7 +83,7 @@ class ApplicationTest < Redmine::IntegrationTest
ActionController::Base.allow_forgery_protection = true
Setting.default_language = 'en'
post '/issues', :headers => {'HTTP_ACCEPT_LANGUAGE' => 'fr,fr-fr;q=0.8,en-us;q=0.5,en;q=0.3'}
assert_response :unprocessable_entity
assert_response :unprocessable_content
assert_equal :fr, current_language
assert_select "html[lang=?]", "fr"
ensure