Redmine 3.4.4
This commit is contained in:
commit
64924a6376
2112 changed files with 259028 additions and 0 deletions
413
test/integration/account_test.rb
Normal file
413
test/integration/account_test.rb
Normal file
|
@ -0,0 +1,413 @@
|
|||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2017 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 AccountTest < Redmine::IntegrationTest
|
||||
fixtures :users, :email_addresses, :roles
|
||||
|
||||
def test_login
|
||||
get "/my/page"
|
||||
assert_redirected_to "/login?back_url=http%3A%2F%2Fwww.example.com%2Fmy%2Fpage"
|
||||
log_user('jsmith', 'jsmith')
|
||||
|
||||
get "/my/account"
|
||||
assert_response :success
|
||||
end
|
||||
|
||||
def test_login_should_set_session_token
|
||||
assert_difference 'Token.count' do
|
||||
log_user('jsmith', 'jsmith')
|
||||
|
||||
assert_equal 2, session[:user_id]
|
||||
assert_not_nil session[:tk]
|
||||
end
|
||||
end
|
||||
|
||||
def test_autologin
|
||||
user = User.find(1)
|
||||
Token.delete_all
|
||||
|
||||
with_settings :autologin => '7' do
|
||||
assert_difference 'Token.count', 2 do
|
||||
# User logs in with 'autologin' checked
|
||||
post '/login', :params => {
|
||||
:username => user.login,
|
||||
:password => 'admin',
|
||||
:autologin => 1
|
||||
}
|
||||
assert_redirected_to '/my/page'
|
||||
end
|
||||
token = Token.where(:action => 'autologin').order(:id => :desc).first
|
||||
assert_not_nil token
|
||||
assert_equal user, token.user
|
||||
assert_equal 'autologin', token.action
|
||||
assert_equal user.id, session[:user_id]
|
||||
assert_equal token.value, cookies['autologin']
|
||||
|
||||
# Session is cleared
|
||||
reset!
|
||||
User.current = nil
|
||||
# Clears user's last login timestamp
|
||||
user.update_attribute :last_login_on, nil
|
||||
assert_nil user.reload.last_login_on
|
||||
|
||||
# User comes back with user's autologin cookie
|
||||
cookies[:autologin] = token.value
|
||||
get '/my/page'
|
||||
assert_response :success
|
||||
assert_equal user.id, session[:user_id]
|
||||
assert_not_nil user.reload.last_login_on
|
||||
end
|
||||
end
|
||||
|
||||
def test_autologin_should_use_autologin_cookie_name
|
||||
Token.delete_all
|
||||
Redmine::Configuration.stubs(:[]).with('autologin_cookie_name').returns('custom_autologin')
|
||||
Redmine::Configuration.stubs(:[]).with('autologin_cookie_path').returns('/')
|
||||
Redmine::Configuration.stubs(:[]).with('autologin_cookie_secure').returns(false)
|
||||
Redmine::Configuration.stubs(:[]).with('sudo_mode_timeout').returns(15)
|
||||
|
||||
with_settings :autologin => '7' do
|
||||
assert_difference 'Token.count', 2 do
|
||||
post '/login', :params => {
|
||||
:username => 'admin',
|
||||
:password => 'admin',
|
||||
:autologin => 1
|
||||
}
|
||||
assert_response 302
|
||||
end
|
||||
assert cookies['custom_autologin'].present?
|
||||
token = cookies['custom_autologin']
|
||||
|
||||
# Session is cleared
|
||||
reset!
|
||||
cookies['custom_autologin'] = token
|
||||
get '/my/page'
|
||||
assert_response :success
|
||||
|
||||
assert_difference 'Token.count', -2 do
|
||||
post '/logout'
|
||||
end
|
||||
assert cookies['custom_autologin'].blank?
|
||||
end
|
||||
end
|
||||
|
||||
def test_lost_password
|
||||
Token.delete_all
|
||||
|
||||
get "/account/lost_password"
|
||||
assert_response :success
|
||||
assert_select 'input[name=mail]'
|
||||
|
||||
post "/account/lost_password", :params => {
|
||||
:mail => 'jSmith@somenet.foo'
|
||||
}
|
||||
assert_redirected_to "/login"
|
||||
|
||||
token = Token.first
|
||||
assert_equal 'recovery', token.action
|
||||
assert_equal 'jsmith@somenet.foo', token.user.mail
|
||||
assert !token.expired?
|
||||
|
||||
get "/account/lost_password", :params => {
|
||||
:token => token.value
|
||||
}
|
||||
assert_redirected_to '/account/lost_password'
|
||||
|
||||
follow_redirect!
|
||||
assert_response :success
|
||||
assert_select 'input[type=hidden][name=token][value=?]', token.value
|
||||
assert_select 'input[name=new_password]'
|
||||
assert_select 'input[name=new_password_confirmation]'
|
||||
|
||||
post "/account/lost_password", :params => {
|
||||
:token => token.value, :new_password => 'newpass123',
|
||||
:new_password_confirmation => 'newpass123'
|
||||
}
|
||||
assert_redirected_to "/login"
|
||||
assert_equal 'Password was successfully updated.', flash[:notice]
|
||||
|
||||
log_user('jsmith', 'newpass123')
|
||||
assert_equal false, Token.exists?(token.id), "Password recovery token was not deleted"
|
||||
end
|
||||
|
||||
def test_user_with_must_change_passwd_should_be_forced_to_change_its_password
|
||||
User.find_by_login('jsmith').update_attribute :must_change_passwd, true
|
||||
|
||||
post '/login', :params => {
|
||||
:username => 'jsmith',
|
||||
:password => 'jsmith'
|
||||
}
|
||||
assert_redirected_to '/my/page'
|
||||
follow_redirect!
|
||||
assert_redirected_to '/my/password'
|
||||
|
||||
get '/issues'
|
||||
assert_redirected_to '/my/password'
|
||||
end
|
||||
|
||||
def test_flash_message_should_use_user_language_when_redirecting_user_for_password_change
|
||||
user = User.find_by_login('jsmith')
|
||||
user.must_change_passwd = true
|
||||
user.language = 'it'
|
||||
user.save!
|
||||
|
||||
post '/login', :params => {
|
||||
:username => 'jsmith',
|
||||
:password => 'jsmith'
|
||||
}
|
||||
assert_redirected_to '/my/page'
|
||||
follow_redirect!
|
||||
assert_redirected_to '/my/password'
|
||||
follow_redirect!
|
||||
|
||||
assert_select 'div.error', :text => /richiesto che sia cambiata/
|
||||
end
|
||||
|
||||
def test_user_with_must_change_passwd_should_be_able_to_change_its_password
|
||||
User.find_by_login('jsmith').update_attribute :must_change_passwd, true
|
||||
|
||||
post '/login', :params => {
|
||||
:username => 'jsmith',
|
||||
:password => 'jsmith'
|
||||
}
|
||||
assert_redirected_to '/my/page'
|
||||
follow_redirect!
|
||||
assert_redirected_to '/my/password'
|
||||
follow_redirect!
|
||||
assert_response :success
|
||||
post '/my/password', :params => {
|
||||
:password => 'jsmith',
|
||||
:new_password => 'newpassword',
|
||||
:new_password_confirmation => 'newpassword'
|
||||
}
|
||||
assert_redirected_to '/my/account'
|
||||
follow_redirect!
|
||||
assert_response :success
|
||||
|
||||
assert_equal false, User.find_by_login('jsmith').must_change_passwd?
|
||||
end
|
||||
|
||||
def test_user_with_expired_password_should_be_forced_to_change_its_password
|
||||
User.find_by_login('jsmith').update_attribute :passwd_changed_on, 14.days.ago
|
||||
|
||||
with_settings :password_max_age => 7 do
|
||||
post '/login', :params => {
|
||||
:username => 'jsmith',
|
||||
:password => 'jsmith'
|
||||
}
|
||||
assert_redirected_to '/my/page'
|
||||
follow_redirect!
|
||||
assert_redirected_to '/my/password'
|
||||
|
||||
get '/issues'
|
||||
assert_redirected_to '/my/password'
|
||||
end
|
||||
end
|
||||
|
||||
def test_user_with_expired_password_should_be_able_to_change_its_password
|
||||
User.find_by_login('jsmith').update_attribute :passwd_changed_on, 14.days.ago
|
||||
|
||||
with_settings :password_max_age => 7 do
|
||||
post '/login', :params => {
|
||||
:username => 'jsmith',
|
||||
:password => 'jsmith'
|
||||
}
|
||||
assert_redirected_to '/my/page'
|
||||
follow_redirect!
|
||||
assert_redirected_to '/my/password'
|
||||
follow_redirect!
|
||||
assert_response :success
|
||||
post '/my/password', :params => {
|
||||
:password => 'jsmith',
|
||||
:new_password => 'newpassword',
|
||||
:new_password_confirmation => 'newpassword'
|
||||
}
|
||||
assert_redirected_to '/my/account'
|
||||
follow_redirect!
|
||||
assert_response :success
|
||||
|
||||
assert_equal false, User.find_by_login('jsmith').must_change_passwd?
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
def test_register_with_automatic_activation
|
||||
Setting.self_registration = '3'
|
||||
|
||||
get '/account/register'
|
||||
assert_response :success
|
||||
|
||||
post '/account/register', :params => {
|
||||
:user => {
|
||||
:login => "newuser", :language => "en",
|
||||
:firstname => "New", :lastname => "User", :mail => "newuser@foo.bar",
|
||||
:password => "newpass123", :password_confirmation => "newpass123"
|
||||
}
|
||||
}
|
||||
assert_redirected_to '/my/account'
|
||||
follow_redirect!
|
||||
assert_response :success
|
||||
|
||||
user = User.find_by_login('newuser')
|
||||
assert_not_nil user
|
||||
assert user.active?
|
||||
assert_not_nil user.last_login_on
|
||||
end
|
||||
|
||||
def test_register_with_manual_activation
|
||||
Setting.self_registration = '2'
|
||||
|
||||
post '/account/register', :params => {
|
||||
:user => {
|
||||
:login => "newuser", :language => "en",
|
||||
:firstname => "New", :lastname => "User", :mail => "newuser@foo.bar",
|
||||
:password => "newpass123", :password_confirmation => "newpass123"
|
||||
}
|
||||
}
|
||||
assert_redirected_to '/login'
|
||||
assert !User.find_by_login('newuser').active?
|
||||
end
|
||||
|
||||
def test_register_with_email_activation
|
||||
Setting.self_registration = '1'
|
||||
Token.delete_all
|
||||
|
||||
post '/account/register', :params => {
|
||||
:user => {
|
||||
:login => "newuser", :language => "en",
|
||||
:firstname => "New", :lastname => "User", :mail => "newuser@foo.bar",
|
||||
:password => "newpass123", :password_confirmation => "newpass123"
|
||||
}
|
||||
}
|
||||
assert_redirected_to '/login'
|
||||
assert !User.find_by_login('newuser').active?
|
||||
|
||||
token = Token.first
|
||||
assert_equal 'register', token.action
|
||||
assert_equal 'newuser@foo.bar', token.user.mail
|
||||
assert !token.expired?
|
||||
|
||||
get '/account/activate', :params => {
|
||||
:token => token.value
|
||||
}
|
||||
assert_redirected_to '/login'
|
||||
log_user('newuser', 'newpass123')
|
||||
end
|
||||
|
||||
def test_onthefly_registration
|
||||
# disable registration
|
||||
Setting.self_registration = '0'
|
||||
AuthSource.expects(:authenticate).returns(
|
||||
{:login => 'foo', :firstname => 'Foo', :lastname => 'Smith',
|
||||
:mail => 'foo@bar.com', :auth_source_id => 66})
|
||||
|
||||
post '/login', :params => {
|
||||
:username => 'foo',
|
||||
:password => 'bar'
|
||||
}
|
||||
assert_redirected_to '/my/page'
|
||||
|
||||
user = User.find_by_login('foo')
|
||||
assert user.is_a?(User)
|
||||
assert_equal 66, user.auth_source_id
|
||||
assert user.hashed_password.blank?
|
||||
end
|
||||
|
||||
def test_onthefly_registration_with_invalid_attributes
|
||||
# disable registration
|
||||
Setting.self_registration = '0'
|
||||
AuthSource.expects(:authenticate).returns(
|
||||
{:login => 'foo', :lastname => 'Smith', :auth_source_id => 66})
|
||||
|
||||
post '/login', :params => {
|
||||
:username => 'foo',
|
||||
:password => 'bar'
|
||||
}
|
||||
assert_response :success
|
||||
assert_select 'input[name=?][value=""]', 'user[firstname]'
|
||||
assert_select 'input[name=?][value=Smith]', 'user[lastname]'
|
||||
assert_select 'input[name=?]', 'user[login]', 0
|
||||
assert_select 'input[name=?]', 'user[password]', 0
|
||||
|
||||
post '/account/register', :params => {
|
||||
:user => {
|
||||
:firstname => 'Foo', :lastname => 'Smith', :mail => 'foo@bar.com'
|
||||
}
|
||||
}
|
||||
assert_redirected_to '/my/account'
|
||||
|
||||
user = User.find_by_login('foo')
|
||||
assert user.is_a?(User)
|
||||
assert_equal 66, user.auth_source_id
|
||||
assert user.hashed_password.blank?
|
||||
end
|
||||
|
||||
def test_registered_user_should_be_able_to_get_a_new_activation_email
|
||||
Token.delete_all
|
||||
|
||||
with_settings :self_registration => '1', :default_language => 'en' do
|
||||
# register a new account
|
||||
assert_difference 'User.count' do
|
||||
assert_difference 'Token.count' do
|
||||
post '/account/register', :params => {
|
||||
:user => {
|
||||
:login => "newuser", :language => "en",
|
||||
:firstname => "New", :lastname => "User", :mail => "newuser@foo.bar",
|
||||
:password => "newpass123", :password_confirmation => "newpass123"
|
||||
}
|
||||
}
|
||||
end
|
||||
end
|
||||
user = User.order('id desc').first
|
||||
assert_equal User::STATUS_REGISTERED, user.status
|
||||
reset!
|
||||
|
||||
# try to use "lost password"
|
||||
assert_no_difference 'ActionMailer::Base.deliveries.size' do
|
||||
post '/account/lost_password', :params => {
|
||||
:mail => 'newuser@foo.bar'
|
||||
}
|
||||
end
|
||||
assert_redirected_to '/account/lost_password'
|
||||
follow_redirect!
|
||||
assert_response :success
|
||||
assert_select 'div.flash', :text => /new activation email/
|
||||
assert_select 'div.flash a[href="/account/activation_email"]'
|
||||
|
||||
# request a new action activation email
|
||||
assert_difference 'ActionMailer::Base.deliveries.size' do
|
||||
get '/account/activation_email'
|
||||
end
|
||||
assert_redirected_to '/login'
|
||||
token = Token.order('id desc').first
|
||||
activation_path = "/account/activate?token=#{token.value}"
|
||||
assert_include activation_path, mail_body(ActionMailer::Base.deliveries.last)
|
||||
|
||||
# activate the account
|
||||
get activation_path
|
||||
assert_redirected_to '/login'
|
||||
|
||||
post '/login', :params => {
|
||||
:username => 'newuser',
|
||||
:password => 'newpass123'
|
||||
}
|
||||
assert_redirected_to '/my/page'
|
||||
end
|
||||
end
|
||||
end
|
72
test/integration/admin_test.rb
Normal file
72
test/integration/admin_test.rb
Normal file
|
@ -0,0 +1,72 @@
|
|||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2017 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 AdminTest < Redmine::IntegrationTest
|
||||
fixtures :projects, :trackers, :issue_statuses, :issues,
|
||||
:enumerations, :users, :issue_categories,
|
||||
:projects_trackers,
|
||||
:roles,
|
||||
:member_roles,
|
||||
:members,
|
||||
:enabled_modules
|
||||
|
||||
def test_add_user
|
||||
log_user("admin", "admin")
|
||||
get "/users/new"
|
||||
assert_response :success
|
||||
|
||||
post "/users", :params => {
|
||||
:user => {
|
||||
:login => "psmith", :firstname => "Paul",
|
||||
:lastname => "Smith", :mail => "psmith@somenet.foo",
|
||||
:language => "en", :password => "psmith09",
|
||||
:password_confirmation => "psmith09"
|
||||
}
|
||||
}
|
||||
|
||||
user = User.find_by_login("psmith")
|
||||
assert_kind_of User, user
|
||||
assert_redirected_to "/users/#{ user.id }/edit"
|
||||
|
||||
logged_user = User.try_to_login("psmith", "psmith09")
|
||||
assert_kind_of User, logged_user
|
||||
assert_equal "Paul", logged_user.firstname
|
||||
|
||||
put "/users/#{user.id}", :params => {
|
||||
:id => user.id,
|
||||
:user => {
|
||||
:status => User::STATUS_LOCKED
|
||||
}
|
||||
}
|
||||
assert_redirected_to "/users/#{ user.id }/edit"
|
||||
locked_user = User.try_to_login("psmith", "psmith09")
|
||||
assert_nil locked_user
|
||||
end
|
||||
|
||||
test "Add a user as an anonymous user should fail" do
|
||||
post '/users', :params => {
|
||||
:user => {
|
||||
:login => 'psmith', :firstname => 'Paul',
|
||||
:password => "psmith09", :password_confirmation => "psmith09"
|
||||
}
|
||||
}
|
||||
assert_response :redirect
|
||||
assert_redirected_to "/login?back_url=http%3A%2F%2Fwww.example.com%2Fusers"
|
||||
end
|
||||
end
|
165
test/integration/api_test/api_routing_test.rb
Normal file
165
test/integration/api_test/api_routing_test.rb
Normal file
|
@ -0,0 +1,165 @@
|
|||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2017 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::ApiRoutingTest < Redmine::ApiTest::Routing
|
||||
|
||||
def test_attachments
|
||||
should_route 'GET /attachments/1' => 'attachments#show', :id => '1'
|
||||
should_route 'PATCH /attachments/1' => 'attachments#update', :id => '1'
|
||||
should_route 'DELETE /attachments/1' => 'attachments#destroy', :id => '1'
|
||||
should_route 'POST /uploads' => 'attachments#upload'
|
||||
end
|
||||
|
||||
def test_custom_fields
|
||||
should_route 'GET /custom_fields' => 'custom_fields#index'
|
||||
end
|
||||
|
||||
def test_enumerations
|
||||
should_route 'GET /enumerations/issue_priorities' => 'enumerations#index', :type => 'issue_priorities'
|
||||
end
|
||||
|
||||
def test_files
|
||||
should_route 'GET /projects/foo/files' => 'files#index', :project_id => 'foo'
|
||||
should_route 'POST /projects/foo/files' => 'files#create', :project_id => 'foo'
|
||||
end
|
||||
|
||||
def test_groups
|
||||
should_route 'GET /groups' => 'groups#index'
|
||||
should_route 'POST /groups' => 'groups#create'
|
||||
|
||||
should_route 'GET /groups/1' => 'groups#show', :id => '1'
|
||||
should_route 'PUT /groups/1' => 'groups#update', :id => '1'
|
||||
should_route 'DELETE /groups/1' => 'groups#destroy', :id => '1'
|
||||
end
|
||||
|
||||
def test_group_users
|
||||
should_route 'POST /groups/567/users' => 'groups#add_users', :id => '567'
|
||||
should_route 'DELETE /groups/567/users/12' => 'groups#remove_user', :id => '567', :user_id => '12'
|
||||
end
|
||||
|
||||
def test_issue_categories
|
||||
should_route 'GET /projects/foo/issue_categories' => 'issue_categories#index', :project_id => 'foo'
|
||||
should_route 'POST /projects/foo/issue_categories' => 'issue_categories#create', :project_id => 'foo'
|
||||
|
||||
should_route 'GET /issue_categories/1' => 'issue_categories#show', :id => '1'
|
||||
should_route 'PUT /issue_categories/1' => 'issue_categories#update', :id => '1'
|
||||
should_route 'DELETE /issue_categories/1' => 'issue_categories#destroy', :id => '1'
|
||||
end
|
||||
|
||||
def test_issue_relations
|
||||
should_route 'GET /issues/1/relations' => 'issue_relations#index', :issue_id => '1'
|
||||
should_route 'POST /issues/1/relations' => 'issue_relations#create', :issue_id => '1'
|
||||
|
||||
should_route 'GET /relations/23' => 'issue_relations#show', :id => '23'
|
||||
should_route 'DELETE /relations/23' => 'issue_relations#destroy', :id => '23'
|
||||
end
|
||||
|
||||
def test_issue_statuses
|
||||
should_route 'GET /issue_statuses' => 'issue_statuses#index'
|
||||
end
|
||||
|
||||
def test_issues
|
||||
should_route 'GET /issues' => 'issues#index'
|
||||
should_route 'POST /issues' => 'issues#create'
|
||||
|
||||
should_route 'GET /issues/64' => 'issues#show', :id => '64'
|
||||
should_route 'PUT /issues/64' => 'issues#update', :id => '64'
|
||||
should_route 'DELETE /issues/64' => 'issues#destroy', :id => '64'
|
||||
end
|
||||
|
||||
def test_issue_watchers
|
||||
should_route 'POST /issues/12/watchers' => 'watchers#create', :object_type => 'issue', :object_id => '12'
|
||||
should_route 'DELETE /issues/12/watchers/3' => 'watchers#destroy', :object_type => 'issue', :object_id => '12', :user_id => '3'
|
||||
end
|
||||
|
||||
def test_memberships
|
||||
should_route 'GET /projects/5234/memberships' => 'members#index', :project_id => '5234'
|
||||
should_route 'POST /projects/5234/memberships' => 'members#create', :project_id => '5234'
|
||||
|
||||
should_route 'GET /memberships/5234' => 'members#show', :id => '5234'
|
||||
should_route 'PUT /memberships/5234' => 'members#update', :id => '5234'
|
||||
should_route 'DELETE /memberships/5234' => 'members#destroy', :id => '5234'
|
||||
end
|
||||
|
||||
def test_news
|
||||
should_route 'GET /news' => 'news#index'
|
||||
should_route 'GET /projects/567/news' => 'news#index', :project_id => '567'
|
||||
end
|
||||
|
||||
def test_projects
|
||||
should_route 'GET /projects' => 'projects#index'
|
||||
should_route 'POST /projects' => 'projects#create'
|
||||
|
||||
should_route 'GET /projects/1' => 'projects#show', :id => '1'
|
||||
should_route 'PUT /projects/1' => 'projects#update', :id => '1'
|
||||
should_route 'DELETE /projects/1' => 'projects#destroy', :id => '1'
|
||||
end
|
||||
|
||||
def test_queries
|
||||
should_route 'GET /queries' => 'queries#index'
|
||||
end
|
||||
|
||||
def test_roles
|
||||
should_route 'GET /roles' => 'roles#index'
|
||||
should_route 'GET /roles/2' => 'roles#show', :id => '2'
|
||||
end
|
||||
|
||||
def test_time_entries
|
||||
should_route 'GET /time_entries' => 'timelog#index'
|
||||
should_route 'POST /time_entries' => 'timelog#create'
|
||||
|
||||
should_route 'GET /time_entries/1' => 'timelog#show', :id => '1'
|
||||
should_route 'PUT /time_entries/1' => 'timelog#update', :id => '1'
|
||||
should_route 'DELETE /time_entries/1' => 'timelog#destroy', :id => '1'
|
||||
end
|
||||
|
||||
def test_trackers
|
||||
should_route 'GET /trackers' => 'trackers#index'
|
||||
end
|
||||
|
||||
def test_users
|
||||
should_route 'GET /users' => 'users#index'
|
||||
should_route 'POST /users' => 'users#create'
|
||||
|
||||
should_route 'GET /users/44' => 'users#show', :id => '44'
|
||||
should_route 'GET /users/current' => 'users#show', :id => 'current'
|
||||
should_route 'PUT /users/44' => 'users#update', :id => '44'
|
||||
should_route 'DELETE /users/44' => 'users#destroy', :id => '44'
|
||||
end
|
||||
|
||||
def test_versions
|
||||
should_route 'GET /projects/foo/versions' => 'versions#index', :project_id => 'foo'
|
||||
should_route 'POST /projects/foo/versions' => 'versions#create', :project_id => 'foo'
|
||||
|
||||
should_route 'GET /versions/1' => 'versions#show', :id => '1'
|
||||
should_route 'PUT /versions/1' => 'versions#update', :id => '1'
|
||||
should_route 'DELETE /versions/1' => 'versions#destroy', :id => '1'
|
||||
end
|
||||
|
||||
def test_wiki
|
||||
should_route 'GET /projects/567/wiki/index' => 'wiki#index', :project_id => '567'
|
||||
|
||||
should_route 'GET /projects/567/wiki/my_page' => 'wiki#show', :project_id => '567', :id => 'my_page'
|
||||
should_route 'GET /projects/567/wiki/my_page' => 'wiki#show', :project_id => '567', :id => 'my_page'
|
||||
should_route 'GET /projects/1/wiki/my_page/2' => 'wiki#show', :project_id => '1', :id => 'my_page', :version => '2'
|
||||
|
||||
should_route 'PUT /projects/567/wiki/my_page' => 'wiki#update', :project_id => '567', :id => 'my_page'
|
||||
should_route 'DELETE /projects/567/wiki/my_page' => 'wiki#destroy', :project_id => '567', :id => 'my_page'
|
||||
end
|
||||
end
|
55
test/integration/api_test/api_test.rb
Normal file
55
test/integration/api_test/api_test.rb
Normal file
|
@ -0,0 +1,55 @@
|
|||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2017 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::ApiTest < Redmine::ApiTest::Base
|
||||
fixtures :users, :email_addresses, :members, :member_roles, :roles, :projects
|
||||
|
||||
def test_api_should_work_with_protect_from_forgery
|
||||
ActionController::Base.allow_forgery_protection = true
|
||||
assert_difference('User.count') do
|
||||
post '/users.xml',
|
||||
:params => {
|
||||
:user => {
|
||||
:login => 'foo', :firstname => 'Firstname', :lastname => 'Lastname',
|
||||
:mail => 'foo@example.net', :password => 'secret123'}
|
||||
},
|
||||
:headers => credentials('admin')
|
||||
assert_response 201
|
||||
end
|
||||
ensure
|
||||
ActionController::Base.allow_forgery_protection = false
|
||||
end
|
||||
|
||||
def test_json_datetime_format
|
||||
get '/users/1.json', :headers => credentials('admin')
|
||||
assert_include '"created_on":"2006-07-19T17:12:21Z"', response.body
|
||||
end
|
||||
|
||||
def test_xml_datetime_format
|
||||
get '/users/1.xml', :headers => credentials('admin')
|
||||
assert_include '<created_on>2006-07-19T17:12:21Z</created_on>', response.body
|
||||
end
|
||||
|
||||
def test_head_response_should_have_empty_body
|
||||
put '/users/7.xml', :params => {:user => {:login => 'foo'}}, :headers => credentials('admin')
|
||||
|
||||
assert_response :ok
|
||||
assert_equal '', response.body
|
||||
end
|
||||
end
|
236
test/integration/api_test/attachments_test.rb
Normal file
236
test/integration/api_test/attachments_test.rb
Normal file
|
@ -0,0 +1,236 @@
|
|||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2017 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::AttachmentsTest < Redmine::ApiTest::Base
|
||||
fixtures :projects, :trackers, :issue_statuses, :issues,
|
||||
:enumerations, :users, :issue_categories,
|
||||
:projects_trackers,
|
||||
:roles,
|
||||
:member_roles,
|
||||
:members,
|
||||
:enabled_modules,
|
||||
:attachments
|
||||
|
||||
def setup
|
||||
super
|
||||
set_fixtures_attachments_directory
|
||||
end
|
||||
|
||||
def teardown
|
||||
super
|
||||
set_tmp_attachments_directory
|
||||
end
|
||||
|
||||
test "GET /attachments/:id.xml should return the attachment" do
|
||||
get '/attachments/7.xml', :headers => credentials('jsmith')
|
||||
assert_response :success
|
||||
assert_equal 'application/xml', @response.content_type
|
||||
assert_select 'attachment id', :text => '7' do
|
||||
assert_select '~ filename', :text => 'archive.zip'
|
||||
assert_select '~ content_url', :text => 'http://www.example.com/attachments/download/7/archive.zip'
|
||||
end
|
||||
end
|
||||
|
||||
test "GET /attachments/:id.xml for image should include thumbnail_url" do
|
||||
get '/attachments/16.xml', :headers => credentials('jsmith')
|
||||
assert_response :success
|
||||
assert_equal 'application/xml', @response.content_type
|
||||
assert_select 'attachment id:contains(16)' do
|
||||
assert_select '~ thumbnail_url', :text => 'http://www.example.com/attachments/thumbnail/16'
|
||||
end
|
||||
end
|
||||
|
||||
test "GET /attachments/:id.xml should deny access without credentials" do
|
||||
get '/attachments/7.xml'
|
||||
assert_response 401
|
||||
set_tmp_attachments_directory
|
||||
end
|
||||
|
||||
test "GET /attachments/download/:id/:filename should return the attachment content" do
|
||||
get '/attachments/download/7/archive.zip', :headers => credentials('jsmith')
|
||||
assert_response :success
|
||||
assert_equal 'application/zip', @response.content_type
|
||||
set_tmp_attachments_directory
|
||||
end
|
||||
|
||||
test "GET /attachments/download/:id/:filename should deny access without credentials" do
|
||||
get '/attachments/download/7/archive.zip'
|
||||
assert_response 302
|
||||
set_tmp_attachments_directory
|
||||
end
|
||||
|
||||
test "GET /attachments/thumbnail/:id should return the thumbnail" do
|
||||
skip unless convert_installed?
|
||||
get '/attachments/thumbnail/16', :headers => credentials('jsmith')
|
||||
assert_response :success
|
||||
end
|
||||
|
||||
test "DELETE /attachments/:id.xml should return ok and delete Attachment" do
|
||||
assert_difference 'Attachment.count', -1 do
|
||||
delete '/attachments/7.xml', :headers => credentials('jsmith')
|
||||
assert_response :ok
|
||||
assert_equal '', response.body
|
||||
end
|
||||
assert_nil Attachment.find_by_id(7)
|
||||
end
|
||||
|
||||
test "DELETE /attachments/:id.json should return ok and delete Attachment" do
|
||||
assert_difference 'Attachment.count', -1 do
|
||||
delete '/attachments/7.json', :headers => credentials('jsmith')
|
||||
assert_response :ok
|
||||
assert_equal '', response.body
|
||||
end
|
||||
assert_nil Attachment.find_by_id(7)
|
||||
end
|
||||
|
||||
test "PATCH /attachments/:id.json should update the attachment" do
|
||||
patch '/attachments/7.json',
|
||||
:params => {:attachment => {:filename => 'renamed.zip', :description => 'updated'}},
|
||||
:headers => credentials('jsmith')
|
||||
|
||||
assert_response :ok
|
||||
assert_equal 'application/json', response.content_type
|
||||
attachment = Attachment.find(7)
|
||||
assert_equal 'renamed.zip', attachment.filename
|
||||
assert_equal 'updated', attachment.description
|
||||
end
|
||||
|
||||
test "PATCH /attachments/:id.json with failure should return the errors" do
|
||||
patch '/attachments/7.json',
|
||||
:params => {:attachment => {:filename => '', :description => 'updated'}},
|
||||
:headers => credentials('jsmith')
|
||||
|
||||
assert_response 422
|
||||
assert_equal 'application/json', response.content_type
|
||||
json = ActiveSupport::JSON.decode(response.body)
|
||||
assert_include "File cannot be blank", json['errors']
|
||||
end
|
||||
|
||||
test "POST /uploads.xml should return the token" do
|
||||
set_tmp_attachments_directory
|
||||
assert_difference 'Attachment.count' do
|
||||
post '/uploads.xml', :headers => {
|
||||
"RAW_POST_DATA" => 'File content',
|
||||
"CONTENT_TYPE" => 'application/octet-stream'
|
||||
}.merge(credentials('jsmith'))
|
||||
assert_response :created
|
||||
assert_equal 'application/xml', response.content_type
|
||||
end
|
||||
|
||||
xml = Hash.from_xml(response.body)
|
||||
assert_kind_of Hash, xml['upload']
|
||||
token = xml['upload']['token']
|
||||
assert_not_nil token
|
||||
attachment_id = xml['upload']['id']
|
||||
assert_not_nil attachment_id
|
||||
|
||||
attachment = Attachment.order('id DESC').first
|
||||
assert_equal token, attachment.token
|
||||
assert_equal attachment_id, attachment.id.to_s
|
||||
assert_nil attachment.container
|
||||
assert_equal 2, attachment.author_id
|
||||
assert_equal 'File content'.size, attachment.filesize
|
||||
assert attachment.content_type.blank?
|
||||
assert attachment.filename.present?
|
||||
assert_match %r{\d+_[0-9a-z]+}, attachment.diskfile
|
||||
assert File.exist?(attachment.diskfile)
|
||||
assert_equal 'File content', File.read(attachment.diskfile)
|
||||
end
|
||||
|
||||
test "POST /uploads.json should return the token" do
|
||||
set_tmp_attachments_directory
|
||||
assert_difference 'Attachment.count' do
|
||||
post '/uploads.json', :headers => {
|
||||
"RAW_POST_DATA" => 'File content',
|
||||
"CONTENT_TYPE" => 'application/octet-stream'
|
||||
}.merge(credentials('jsmith'))
|
||||
assert_response :created
|
||||
assert_equal 'application/json', response.content_type
|
||||
end
|
||||
|
||||
json = ActiveSupport::JSON.decode(response.body)
|
||||
assert_kind_of Hash, json['upload']
|
||||
token = json['upload']['token']
|
||||
assert_not_nil token
|
||||
|
||||
attachment = Attachment.order('id DESC').first
|
||||
assert_equal token, attachment.token
|
||||
end
|
||||
|
||||
test "POST /uploads.xml should accept :filename param as the attachment filename" do
|
||||
set_tmp_attachments_directory
|
||||
assert_difference 'Attachment.count' do
|
||||
post '/uploads.xml?filename=test.txt', :headers => {
|
||||
"RAW_POST_DATA" => 'File content',
|
||||
"CONTENT_TYPE" => 'application/octet-stream'
|
||||
}.merge(credentials('jsmith'))
|
||||
assert_response :created
|
||||
end
|
||||
|
||||
attachment = Attachment.order('id DESC').first
|
||||
assert_equal 'test.txt', attachment.filename
|
||||
assert_match /_test\.txt$/, attachment.diskfile
|
||||
end
|
||||
|
||||
test "POST /uploads.xml should not accept other content types" do
|
||||
set_tmp_attachments_directory
|
||||
assert_no_difference 'Attachment.count' do
|
||||
post '/uploads.xml', :headers => {
|
||||
"RAW_POST_DATA" => 'PNG DATA',
|
||||
"CONTENT_TYPE" => 'image/png'
|
||||
}.merge(credentials('jsmith'))
|
||||
assert_response 406
|
||||
end
|
||||
end
|
||||
|
||||
test "POST /uploads.xml should return errors if file is too big" do
|
||||
set_tmp_attachments_directory
|
||||
with_settings :attachment_max_size => 1 do
|
||||
assert_no_difference 'Attachment.count' do
|
||||
post '/uploads.xml', :headers => {
|
||||
"RAW_POST_DATA" => ('x' * 2048),
|
||||
"CONTENT_TYPE" => 'application/octet-stream'
|
||||
}.merge(credentials('jsmith'))
|
||||
assert_response 422
|
||||
assert_select 'error', :text => /exceeds the maximum allowed file size/
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
test "POST /uploads.json should create an empty file and return a valid token" do
|
||||
set_tmp_attachments_directory
|
||||
assert_difference 'Attachment.count' do
|
||||
post '/uploads.json', :headers => {
|
||||
"CONTENT_TYPE" => 'application/octet-stream'
|
||||
}.merge(credentials('jsmith'))
|
||||
assert_response :created
|
||||
|
||||
end
|
||||
|
||||
json = ActiveSupport::JSON.decode(response.body)
|
||||
assert_kind_of Hash, json['upload']
|
||||
token = json['upload']['token']
|
||||
assert token.present?
|
||||
|
||||
assert attachment = Attachment.find_by_token(token)
|
||||
assert_equal 0, attachment.filesize
|
||||
assert attachment.digest.present?
|
||||
assert File.exist? attachment.diskfile
|
||||
end
|
||||
end
|
158
test/integration/api_test/authentication_test.rb
Normal file
158
test/integration/api_test/authentication_test.rb
Normal file
|
@ -0,0 +1,158 @@
|
|||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2017 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::AuthenticationTest < Redmine::ApiTest::Base
|
||||
fixtures :users
|
||||
|
||||
def test_api_should_deny_without_credentials
|
||||
get '/users/current.xml'
|
||||
assert_response 401
|
||||
assert_equal User.anonymous, User.current
|
||||
assert response.headers.has_key?('WWW-Authenticate')
|
||||
end
|
||||
|
||||
def test_api_should_accept_http_basic_auth_using_username_and_password
|
||||
user = User.generate! do |user|
|
||||
user.password = 'my_password'
|
||||
end
|
||||
get '/users/current.xml', :headers => credentials(user.login, 'my_password')
|
||||
assert_response 200
|
||||
assert_equal user, User.current
|
||||
end
|
||||
|
||||
def test_api_should_deny_http_basic_auth_using_username_and_wrong_password
|
||||
user = User.generate! do |user|
|
||||
user.password = 'my_password'
|
||||
end
|
||||
get '/users/current.xml', :headers => credentials(user.login, 'wrong_password')
|
||||
assert_response 401
|
||||
assert_equal User.anonymous, User.current
|
||||
end
|
||||
|
||||
def test_api_should_accept_http_basic_auth_using_api_key
|
||||
user = User.generate!
|
||||
token = Token.create!(:user => user, :action => 'api')
|
||||
get '/users/current.xml', :headers => credentials(token.value, 'X')
|
||||
assert_response 200
|
||||
assert_equal user, User.current
|
||||
end
|
||||
|
||||
def test_api_should_deny_http_basic_auth_using_wrong_api_key
|
||||
user = User.generate!
|
||||
token = Token.create!(:user => user, :action => 'feeds') # not the API key
|
||||
get '/users/current.xml', :headers => credentials(token.value, 'X')
|
||||
assert_response 401
|
||||
assert_equal User.anonymous, User.current
|
||||
end
|
||||
|
||||
def test_api_should_accept_auth_using_api_key_as_parameter
|
||||
user = User.generate!
|
||||
token = Token.create!(:user => user, :action => 'api')
|
||||
get "/users/current.xml?key=#{token.value}"
|
||||
assert_response 200
|
||||
assert_equal user, User.current
|
||||
end
|
||||
|
||||
def test_api_should_deny_auth_using_wrong_api_key_as_parameter
|
||||
user = User.generate!
|
||||
token = Token.create!(:user => user, :action => 'feeds') # not the API key
|
||||
get "/users/current.xml?key=#{token.value}"
|
||||
assert_response 401
|
||||
assert_equal User.anonymous, User.current
|
||||
end
|
||||
|
||||
def test_api_should_accept_auth_using_api_key_as_request_header
|
||||
user = User.generate!
|
||||
token = Token.create!(:user => user, :action => 'api')
|
||||
get "/users/current.xml", :headers => {'X-Redmine-API-Key' => token.value.to_s}
|
||||
assert_response 200
|
||||
assert_equal user, User.current
|
||||
end
|
||||
|
||||
def test_api_should_deny_auth_using_wrong_api_key_as_request_header
|
||||
user = User.generate!
|
||||
token = Token.create!(:user => user, :action => 'feeds') # not the API key
|
||||
get "/users/current.xml", :headers => {'X-Redmine-API-Key' => token.value.to_s}
|
||||
assert_response 401
|
||||
assert_equal User.anonymous, User.current
|
||||
end
|
||||
|
||||
def test_api_should_trigger_basic_http_auth_with_basic_authorization_header
|
||||
ApplicationController.any_instance.expects(:authenticate_with_http_basic).once
|
||||
get '/users/current.xml', :headers => credentials('jsmith')
|
||||
assert_response 401
|
||||
end
|
||||
|
||||
def test_api_should_not_trigger_basic_http_auth_with_non_basic_authorization_header
|
||||
ApplicationController.any_instance.expects(:authenticate_with_http_basic).never
|
||||
get '/users/current.xml', :headers => {'HTTP_AUTHORIZATION' => 'Digest foo bar'}
|
||||
assert_response 401
|
||||
end
|
||||
|
||||
def test_invalid_utf8_credentials_should_not_trigger_an_error
|
||||
invalid_utf8 = "\x82".force_encoding('UTF-8')
|
||||
assert !invalid_utf8.valid_encoding?
|
||||
assert_nothing_raised do
|
||||
get '/users/current.xml', :headers => credentials(invalid_utf8, "foo")
|
||||
end
|
||||
end
|
||||
|
||||
def test_api_request_should_not_use_user_session
|
||||
log_user('jsmith', 'jsmith')
|
||||
|
||||
get '/users/current'
|
||||
assert_response :success
|
||||
|
||||
get '/users/current.json'
|
||||
assert_response 401
|
||||
end
|
||||
|
||||
def test_api_should_accept_switch_user_header_for_admin_user
|
||||
user = User.find(1)
|
||||
su = User.find(4)
|
||||
|
||||
get '/users/current', :headers => {'X-Redmine-API-Key' => user.api_key, 'X-Redmine-Switch-User' => su.login}
|
||||
assert_response :success
|
||||
assert_select 'h2', :text => su.name
|
||||
assert_equal su, User.current
|
||||
end
|
||||
|
||||
def test_api_should_respond_with_412_when_trying_to_switch_to_a_invalid_user
|
||||
get '/users/current', :headers => {'X-Redmine-API-Key' => User.find(1).api_key, 'X-Redmine-Switch-User' => 'foobar'}
|
||||
assert_response 412
|
||||
end
|
||||
|
||||
def test_api_should_respond_with_412_when_trying_to_switch_to_a_locked_user
|
||||
user = User.find(5)
|
||||
assert user.locked?
|
||||
|
||||
get '/users/current', :headers => {'X-Redmine-API-Key' => User.find(1).api_key, 'X-Redmine-Switch-User' => user.login}
|
||||
assert_response 412
|
||||
end
|
||||
|
||||
def test_api_should_not_accept_switch_user_header_for_non_admin_user
|
||||
user = User.find(2)
|
||||
su = User.find(4)
|
||||
|
||||
get '/users/current', :headers => {'X-Redmine-API-Key' => user.api_key, 'X-Redmine-Switch-User' => su.login}
|
||||
assert_response :success
|
||||
assert_select 'h2', :text => user.name
|
||||
assert_equal user, User.current
|
||||
end
|
||||
end
|
99
test/integration/api_test/custom_fields_attribute_test.rb
Normal file
99
test/integration/api_test/custom_fields_attribute_test.rb
Normal file
|
@ -0,0 +1,99 @@
|
|||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2017 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::CustomFieldsAttributeTest < Redmine::ApiTest::Base
|
||||
fixtures :users
|
||||
|
||||
def test_integer_custom_fields_should_accept_strings
|
||||
field = GroupCustomField.generate!(:field_format => 'int')
|
||||
|
||||
post '/groups.json',
|
||||
:params => %({"group":{"name":"Foo","custom_field_values":{"#{field.id}":"52"}}}),
|
||||
:headers => {
|
||||
'CONTENT_TYPE' => 'application/json'
|
||||
}.merge(credentials('admin'))
|
||||
assert_response :created
|
||||
group = Group.order('id DESC').first
|
||||
assert_equal "52", group.custom_field_value(field)
|
||||
end
|
||||
|
||||
def test_integer_custom_fields_should_accept_integers
|
||||
field = GroupCustomField.generate!(:field_format => 'int')
|
||||
|
||||
post '/groups.json',
|
||||
:params => %({"group":{"name":"Foo","custom_field_values":{"#{field.id}":52}}}),
|
||||
:headers => {
|
||||
'CONTENT_TYPE' => 'application/json'
|
||||
}.merge(credentials('admin'))
|
||||
assert_response :created
|
||||
group = Group.order('id DESC').first
|
||||
assert_equal "52", group.custom_field_value(field)
|
||||
end
|
||||
|
||||
def test_boolean_custom_fields_should_accept_strings
|
||||
field = GroupCustomField.generate!(:field_format => 'bool')
|
||||
|
||||
post '/groups.json',
|
||||
:params => %({"group":{"name":"Foo","custom_field_values":{"#{field.id}": "1"}}}),
|
||||
:headers => {
|
||||
'CONTENT_TYPE' => 'application/json'
|
||||
}.merge(credentials('admin'))
|
||||
assert_response :created
|
||||
group = Group.order('id DESC').first
|
||||
assert_equal "1", group.custom_field_value(field)
|
||||
end
|
||||
|
||||
def test_boolean_custom_fields_should_accept_integers
|
||||
field = GroupCustomField.generate!(:field_format => 'bool')
|
||||
|
||||
post '/groups.json',
|
||||
:params => %({"group":{"name":"Foo","custom_field_values":{"#{field.id}": 1}}}),
|
||||
:headers => {
|
||||
'CONTENT_TYPE' => 'application/json'
|
||||
}.merge(credentials('admin'))
|
||||
assert_response :created
|
||||
group = Group.order('id DESC').first
|
||||
assert_equal "1", group.custom_field_value(field)
|
||||
end
|
||||
|
||||
def test_multivalued_custom_fields_should_accept_an_array
|
||||
field = GroupCustomField.generate!(
|
||||
:field_format => 'list',
|
||||
:multiple => true,
|
||||
:possible_values => ["V1", "V2", "V3"],
|
||||
:default_value => "V2"
|
||||
)
|
||||
|
||||
payload = <<-JSON
|
||||
{"group": {"name":"Foooo",
|
||||
"custom_field_values":{"#{field.id}":["V1","V3"]}
|
||||
}
|
||||
}
|
||||
JSON
|
||||
|
||||
post '/groups.json',
|
||||
:params => payload,
|
||||
:headers => {
|
||||
'CONTENT_TYPE' => 'application/json'
|
||||
}.merge(credentials('admin'))
|
||||
assert_response :created
|
||||
group = Group.order('id DESC').first
|
||||
assert_equal ["V1", "V3"], group.custom_field_value(field).sort
|
||||
end
|
||||
end
|
56
test/integration/api_test/custom_fields_test.rb
Normal file
56
test/integration/api_test/custom_fields_test.rb
Normal file
|
@ -0,0 +1,56 @@
|
|||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2017 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::CustomFieldsTest < Redmine::ApiTest::Base
|
||||
fixtures :users, :custom_fields
|
||||
|
||||
test "GET /custom_fields.xml should return custom fields" do
|
||||
get '/custom_fields.xml', :headers => credentials('admin')
|
||||
assert_response :success
|
||||
assert_equal 'application/xml', response.content_type
|
||||
|
||||
assert_select 'custom_fields' do
|
||||
assert_select 'custom_field' do
|
||||
assert_select 'name', :text => 'Database'
|
||||
assert_select 'id', :text => '2'
|
||||
assert_select 'customized_type', :text => 'issue'
|
||||
assert_select 'possible_values[type=array]' do
|
||||
assert_select 'possible_value>value', :text => 'PostgreSQL'
|
||||
assert_select 'possible_value>label', :text => 'PostgreSQL'
|
||||
end
|
||||
assert_select 'trackers[type=array]'
|
||||
assert_select 'roles[type=array]'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
test "GET /custom_fields.xml should include value and label for enumeration custom fields" do
|
||||
field = IssueCustomField.generate!(:field_format => 'enumeration')
|
||||
foo = field.enumerations.create!(:name => 'Foo')
|
||||
bar = field.enumerations.create!(:name => 'Bar')
|
||||
|
||||
get '/custom_fields.xml', :headers => credentials('admin')
|
||||
assert_response :success
|
||||
|
||||
assert_select 'possible_value' do
|
||||
assert_select "value:contains(?) + label:contains(?)", foo.id.to_s, 'Foo'
|
||||
assert_select "value:contains(?) + label:contains(?)", bar.id.to_s, 'Bar'
|
||||
end
|
||||
end
|
||||
end
|
78
test/integration/api_test/disabled_rest_api_test.rb
Normal file
78
test/integration/api_test/disabled_rest_api_test.rb
Normal file
|
@ -0,0 +1,78 @@
|
|||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2017 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::DisabledRestApiTest < Redmine::ApiTest::Base
|
||||
fixtures :projects, :trackers, :issue_statuses, :issues,
|
||||
:enumerations, :users, :issue_categories,
|
||||
:projects_trackers,
|
||||
:roles,
|
||||
:member_roles,
|
||||
:members,
|
||||
:enabled_modules
|
||||
|
||||
def setup
|
||||
Setting.rest_api_enabled = '0'
|
||||
Setting.login_required = '1'
|
||||
end
|
||||
|
||||
def teardown
|
||||
Setting.rest_api_enabled = '1'
|
||||
Setting.login_required = '0'
|
||||
end
|
||||
|
||||
def test_with_a_valid_api_token
|
||||
@user = User.generate!
|
||||
@token = Token.create!(:user => @user, :action => 'api')
|
||||
|
||||
get "/news.xml?key=#{@token.value}"
|
||||
assert_response :unauthorized
|
||||
assert_equal User.anonymous, User.current
|
||||
|
||||
get "/news.json?key=#{@token.value}"
|
||||
assert_response :unauthorized
|
||||
assert_equal User.anonymous, User.current
|
||||
end
|
||||
|
||||
def test_with_valid_username_password_http_authentication
|
||||
@user = User.generate! do |user|
|
||||
user.password = 'my_password'
|
||||
end
|
||||
|
||||
get "/news.xml", :headers => credentials(@user.login, 'my_password')
|
||||
assert_response :unauthorized
|
||||
assert_equal User.anonymous, User.current
|
||||
|
||||
get "/news.json", :headers => credentials(@user.login, 'my_password')
|
||||
assert_response :unauthorized
|
||||
assert_equal User.anonymous, User.current
|
||||
end
|
||||
|
||||
def test_with_valid_token_http_authentication
|
||||
@user = User.generate!
|
||||
@token = Token.create!(:user => @user, :action => 'api')
|
||||
|
||||
get "/news.xml", :headers => credentials(@token.value, 'X')
|
||||
assert_response :unauthorized
|
||||
assert_equal User.anonymous, User.current
|
||||
|
||||
get "/news.json", :headers => credentials(@token.value, 'X')
|
||||
assert_response :unauthorized
|
||||
assert_equal User.anonymous, User.current
|
||||
end
|
||||
end
|
40
test/integration/api_test/enumerations_test.rb
Normal file
40
test/integration/api_test/enumerations_test.rb
Normal file
|
@ -0,0 +1,40 @@
|
|||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2017 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::EnumerationsTest < Redmine::ApiTest::Base
|
||||
fixtures :enumerations
|
||||
|
||||
test "GET /enumerations/issue_priorities.xml should return priorities" do
|
||||
get '/enumerations/issue_priorities.xml'
|
||||
assert_response :success
|
||||
assert_equal 'application/xml', response.content_type
|
||||
assert_select 'issue_priorities[type=array]' do
|
||||
assert_select 'issue_priority' do
|
||||
assert_select 'id', :text => '6'
|
||||
assert_select 'name', :text => 'High'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
test "GET /enumerations/invalid_subclass.xml should return 404" do
|
||||
get '/enumerations/invalid_subclass.xml'
|
||||
assert_response 404
|
||||
assert_equal 'application/xml', response.content_type
|
||||
end
|
||||
end
|
133
test/integration/api_test/files_test.rb
Normal file
133
test/integration/api_test/files_test.rb
Normal file
|
@ -0,0 +1,133 @@
|
|||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2017 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::FilesTest < Redmine::ApiTest::Base
|
||||
fixtures :projects,
|
||||
:users,
|
||||
:members,
|
||||
:roles,
|
||||
:member_roles,
|
||||
:enabled_modules,
|
||||
:attachments,
|
||||
:versions
|
||||
|
||||
test "GET /projects/:project_id/files.xml should return the list of uploaded files" do
|
||||
get '/projects/1/files.xml', :headers => credentials('jsmith')
|
||||
assert_response :success
|
||||
assert_select 'files>file>id', :text => '8'
|
||||
end
|
||||
|
||||
test "POST /projects/:project_id/files.json should create a file" do
|
||||
set_tmp_attachments_directory
|
||||
post '/uploads.xml',
|
||||
:params => 'File content',
|
||||
:headers => {"CONTENT_TYPE" => 'application/octet-stream'}.merge(credentials('jsmith'))
|
||||
token = Attachment.last.token
|
||||
payload = <<-JSON
|
||||
{ "file": {
|
||||
"token": "#{token}"
|
||||
}
|
||||
}
|
||||
JSON
|
||||
post '/projects/1/files.json',
|
||||
:params => payload,
|
||||
:headers => {"CONTENT_TYPE" => 'application/json'}.merge(credentials('jsmith'))
|
||||
assert_response :success
|
||||
assert_equal 1, Attachment.last.container_id
|
||||
assert_equal "Project", Attachment.last.container_type
|
||||
end
|
||||
|
||||
test "POST /projects/:project_id/files.xml should create a file" do
|
||||
set_tmp_attachments_directory
|
||||
post '/uploads.xml',
|
||||
:params => 'File content',
|
||||
:headers => {"CONTENT_TYPE" => 'application/octet-stream'}.merge(credentials('jsmith'))
|
||||
token = Attachment.last.token
|
||||
payload = <<-XML
|
||||
<file>
|
||||
<token>#{token}</token>
|
||||
</file>
|
||||
XML
|
||||
post '/projects/1/files.xml',
|
||||
:params => payload,
|
||||
:headers => {"CONTENT_TYPE" => 'application/xml'}.merge(credentials('jsmith'))
|
||||
assert_response :success
|
||||
assert_equal 1, Attachment.last.container_id
|
||||
assert_equal "Project", Attachment.last.container_type
|
||||
end
|
||||
|
||||
test "POST /projects/:project_id/files.json should refuse requests without the :token parameter" do
|
||||
payload = <<-JSON
|
||||
{ "file": {
|
||||
"filename": "project_file.zip",
|
||||
}
|
||||
}
|
||||
JSON
|
||||
post '/projects/1/files.json',
|
||||
:params => payload,
|
||||
:headers => {"CONTENT_TYPE" => 'application/json'}.merge(credentials('jsmith'))
|
||||
assert_response :bad_request
|
||||
end
|
||||
|
||||
test "POST /projects/:project_id/files.json should accept :filename, :description, :content_type as optional parameters" do
|
||||
set_tmp_attachments_directory
|
||||
post '/uploads.xml',
|
||||
:params => 'File content',
|
||||
:headers => {"CONTENT_TYPE" => 'application/octet-stream'}.merge(credentials('jsmith'))
|
||||
token = Attachment.last.token
|
||||
payload = <<-JSON
|
||||
{ "file": {
|
||||
"filename": "New filename",
|
||||
"description": "New description",
|
||||
"content_type": "application/txt",
|
||||
"token": "#{token}"
|
||||
}
|
||||
}
|
||||
JSON
|
||||
post '/projects/1/files.json',
|
||||
:params => payload,
|
||||
:headers => {"CONTENT_TYPE" => 'application/json'}.merge(credentials('jsmith'))
|
||||
assert_response :success
|
||||
assert_equal "New filename", Attachment.last.filename
|
||||
assert_equal "New description", Attachment.last.description
|
||||
assert_equal "application/txt", Attachment.last.content_type
|
||||
end
|
||||
|
||||
test "POST /projects/:project_id/files.json should accept :version_id to attach the files to a version" do
|
||||
set_tmp_attachments_directory
|
||||
post '/uploads.xml',
|
||||
:params => 'File content',
|
||||
:headers => {"CONTENT_TYPE" => 'application/octet-stream'}.merge(credentials('jsmith'))
|
||||
token = Attachment.last.token
|
||||
payload = <<-JSON
|
||||
{ "file": {
|
||||
"version_id": 3,
|
||||
"filename": "New filename",
|
||||
"description": "New description",
|
||||
"token": "#{token}"
|
||||
}
|
||||
}
|
||||
JSON
|
||||
post '/projects/1/files.json',
|
||||
:params => payload,
|
||||
:headers => {"CONTENT_TYPE" => 'application/json'}.merge(credentials('jsmith'))
|
||||
assert_equal 3, Attachment.last.container_id
|
||||
assert_equal "Version", Attachment.last.container_type
|
||||
end
|
||||
end
|
228
test/integration/api_test/groups_test.rb
Normal file
228
test/integration/api_test/groups_test.rb
Normal file
|
@ -0,0 +1,228 @@
|
|||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2017 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::GroupsTest < Redmine::ApiTest::Base
|
||||
fixtures :users, :groups_users, :email_addresses
|
||||
|
||||
test "GET /groups.xml should require authentication" do
|
||||
get '/groups.xml'
|
||||
assert_response 401
|
||||
end
|
||||
|
||||
test "GET /groups.xml should return givable groups" do
|
||||
get '/groups.xml', :headers => credentials('admin')
|
||||
assert_response :success
|
||||
assert_equal 'application/xml', response.content_type
|
||||
|
||||
assert_select 'groups' do
|
||||
assert_select 'group', Group.givable.count
|
||||
assert_select 'group' do
|
||||
assert_select 'name', :text => 'A Team'
|
||||
assert_select 'id', :text => '10'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
test "GET /groups.xml?builtin=1 should return all groups" do
|
||||
get '/groups.xml?builtin=1', :headers => credentials('admin')
|
||||
assert_response :success
|
||||
assert_equal 'application/xml', response.content_type
|
||||
|
||||
assert_select 'groups' do
|
||||
assert_select 'group', Group.givable.count + 2
|
||||
assert_select 'group' do
|
||||
assert_select 'builtin', :text => 'non_member'
|
||||
assert_select 'id', :text => '12'
|
||||
end
|
||||
assert_select 'group' do
|
||||
assert_select 'builtin', :text => 'anonymous'
|
||||
assert_select 'id', :text => '13'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
test "GET /groups.json should require authentication" do
|
||||
get '/groups.json'
|
||||
assert_response 401
|
||||
end
|
||||
|
||||
test "GET /groups.json should return groups" do
|
||||
get '/groups.json', :headers => credentials('admin')
|
||||
assert_response :success
|
||||
assert_equal 'application/json', response.content_type
|
||||
|
||||
json = ActiveSupport::JSON.decode(response.body)
|
||||
groups = json['groups']
|
||||
assert_kind_of Array, groups
|
||||
group = groups.detect {|g| g['name'] == 'A Team'}
|
||||
assert_not_nil group
|
||||
assert_equal({'id' => 10, 'name' => 'A Team'}, group)
|
||||
end
|
||||
|
||||
test "GET /groups/:id.xml should return the group" do
|
||||
get '/groups/10.xml', :headers => credentials('admin')
|
||||
assert_response :success
|
||||
assert_equal 'application/xml', response.content_type
|
||||
|
||||
assert_select 'group' do
|
||||
assert_select 'name', :text => 'A Team'
|
||||
assert_select 'id', :text => '10'
|
||||
end
|
||||
end
|
||||
|
||||
test "GET /groups/:id.xml should return the builtin group" do
|
||||
get '/groups/12.xml', :headers => credentials('admin')
|
||||
assert_response :success
|
||||
assert_equal 'application/xml', response.content_type
|
||||
|
||||
assert_select 'group' do
|
||||
assert_select 'builtin', :text => 'non_member'
|
||||
assert_select 'id', :text => '12'
|
||||
end
|
||||
end
|
||||
|
||||
test "GET /groups/:id.xml should include users if requested" do
|
||||
get '/groups/10.xml?include=users', :headers => credentials('admin')
|
||||
assert_response :success
|
||||
assert_equal 'application/xml', response.content_type
|
||||
|
||||
assert_select 'group' do
|
||||
assert_select 'users' do
|
||||
assert_select 'user', Group.find(10).users.count
|
||||
assert_select 'user[id="8"]'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
test "GET /groups/:id.xml include memberships if requested" do
|
||||
get '/groups/10.xml?include=memberships', :headers => credentials('admin')
|
||||
assert_response :success
|
||||
assert_equal 'application/xml', response.content_type
|
||||
|
||||
assert_select 'group' do
|
||||
assert_select 'memberships'
|
||||
end
|
||||
end
|
||||
|
||||
test "POST /groups.xml with valid parameters should create the group" do
|
||||
assert_difference('Group.count') do
|
||||
post '/groups.xml',
|
||||
:params => {:group => {:name => 'Test', :user_ids => [2, 3]}},
|
||||
:headers => credentials('admin')
|
||||
assert_response :created
|
||||
assert_equal 'application/xml', response.content_type
|
||||
end
|
||||
|
||||
group = Group.order('id DESC').first
|
||||
assert_equal 'Test', group.name
|
||||
assert_equal [2, 3], group.users.map(&:id).sort
|
||||
|
||||
assert_select 'group' do
|
||||
assert_select 'name', :text => 'Test'
|
||||
end
|
||||
end
|
||||
|
||||
test "POST /groups.xml with invalid parameters should return errors" do
|
||||
assert_no_difference('Group.count') do
|
||||
post '/groups.xml',
|
||||
:params => {:group => {:name => ''}},
|
||||
:headers => credentials('admin')
|
||||
end
|
||||
assert_response :unprocessable_entity
|
||||
assert_equal 'application/xml', response.content_type
|
||||
|
||||
assert_select 'errors' do
|
||||
assert_select 'error', :text => /Name cannot be blank/
|
||||
end
|
||||
end
|
||||
|
||||
test "PUT /groups/:id.xml with valid parameters should update the group" do
|
||||
group = Group.generate!
|
||||
put "/groups/#{group.id}.xml",
|
||||
:params => {:group => {:name => 'New name', :user_ids => [2, 3]}},
|
||||
:headers => credentials('admin')
|
||||
assert_response :ok
|
||||
assert_equal '', @response.body
|
||||
|
||||
assert_equal 'New name', group.reload.name
|
||||
assert_equal [2, 3], group.users.map(&:id).sort
|
||||
end
|
||||
|
||||
test "PUT /groups/:id.xml with invalid parameters should return errors" do
|
||||
group = Group.generate!
|
||||
put "/groups/#{group.id}.xml",
|
||||
:params => {:group => {:name => ''}},
|
||||
:headers => credentials('admin')
|
||||
assert_response :unprocessable_entity
|
||||
assert_equal 'application/xml', response.content_type
|
||||
|
||||
assert_select 'errors' do
|
||||
assert_select 'error', :text => /Name cannot be blank/
|
||||
end
|
||||
end
|
||||
|
||||
test "DELETE /groups/:id.xml should delete the group" do
|
||||
group = Group.generate!
|
||||
assert_difference 'Group.count', -1 do
|
||||
delete "/groups/#{group.id}.xml", :headers => credentials('admin')
|
||||
assert_response :ok
|
||||
assert_equal '', @response.body
|
||||
end
|
||||
end
|
||||
|
||||
test "POST /groups/:id/users.xml should add user to the group" do
|
||||
group = Group.generate!
|
||||
assert_difference 'group.reload.users.count' do
|
||||
post "/groups/#{group.id}/users.xml",
|
||||
:params => {:user_id => 5},
|
||||
:headers => credentials('admin')
|
||||
assert_response :ok
|
||||
assert_equal '', @response.body
|
||||
end
|
||||
assert_include User.find(5), group.reload.users
|
||||
end
|
||||
|
||||
test "POST /groups/:id/users.xml should not add the user if already added" do
|
||||
group = Group.generate!
|
||||
group.users << User.find(5)
|
||||
|
||||
assert_no_difference 'group.reload.users.count' do
|
||||
post "/groups/#{group.id}/users.xml",
|
||||
:params => {:user_id => 5},
|
||||
:headers => credentials('admin')
|
||||
assert_response :unprocessable_entity
|
||||
end
|
||||
|
||||
assert_select 'errors' do
|
||||
assert_select 'error', :text => /User is invalid/
|
||||
end
|
||||
end
|
||||
|
||||
test "DELETE /groups/:id/users/:user_id.xml should remove user from the group" do
|
||||
group = Group.generate!
|
||||
group.users << User.find(8)
|
||||
|
||||
assert_difference 'group.reload.users.count', -1 do
|
||||
delete "/groups/#{group.id}/users/8.xml", :headers => credentials('admin')
|
||||
assert_response :ok
|
||||
assert_equal '', @response.body
|
||||
end
|
||||
assert_not_include User.find(8), group.reload.users
|
||||
end
|
||||
end
|
114
test/integration/api_test/issue_categories_test.rb
Normal file
114
test/integration/api_test/issue_categories_test.rb
Normal file
|
@ -0,0 +1,114 @@
|
|||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2017 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::IssueCategoriesTest < Redmine::ApiTest::Base
|
||||
fixtures :projects, :users, :issue_categories, :issues,
|
||||
:roles,
|
||||
:member_roles,
|
||||
:members,
|
||||
:enabled_modules
|
||||
|
||||
test "GET /projects/:project_id/issue_categories.xml should return the issue categories" do
|
||||
get '/projects/1/issue_categories.xml', :headers => credentials('jsmith')
|
||||
assert_response :success
|
||||
assert_equal 'application/xml', @response.content_type
|
||||
assert_select 'issue_categories issue_category id', :text => '2'
|
||||
end
|
||||
|
||||
test "GET /issue_categories/:id.xml should return the issue category" do
|
||||
get '/issue_categories/2.xml', :headers => credentials('jsmith')
|
||||
assert_response :success
|
||||
assert_equal 'application/xml', @response.content_type
|
||||
assert_select 'issue_category id', :text => '2'
|
||||
end
|
||||
|
||||
test "POST /projects/:project_id/issue_categories.xml should return create issue category" do
|
||||
assert_difference 'IssueCategory.count' do
|
||||
post '/projects/1/issue_categories.xml',
|
||||
:params => {:issue_category => {:name => 'API'}},
|
||||
:headers => credentials('jsmith')
|
||||
end
|
||||
assert_response :created
|
||||
assert_equal 'application/xml', @response.content_type
|
||||
|
||||
category = IssueCategory.order('id DESC').first
|
||||
assert_equal 'API', category.name
|
||||
assert_equal 1, category.project_id
|
||||
end
|
||||
|
||||
test "POST /projects/:project_id/issue_categories.xml with invalid parameters should return errors" do
|
||||
assert_no_difference 'IssueCategory.count' do
|
||||
post '/projects/1/issue_categories.xml',
|
||||
:params => {:issue_category => {:name => ''}},
|
||||
:headers => credentials('jsmith')
|
||||
end
|
||||
assert_response :unprocessable_entity
|
||||
assert_equal 'application/xml', @response.content_type
|
||||
|
||||
assert_select 'errors error', :text => "Name cannot be blank"
|
||||
end
|
||||
|
||||
test "PUT /issue_categories/:id.xml with valid parameters should update the issue category" do
|
||||
assert_no_difference 'IssueCategory.count' do
|
||||
put '/issue_categories/2.xml',
|
||||
:params => {:issue_category => {:name => 'API Update'}},
|
||||
:headers => credentials('jsmith')
|
||||
end
|
||||
assert_response :ok
|
||||
assert_equal '', @response.body
|
||||
assert_equal 'API Update', IssueCategory.find(2).name
|
||||
end
|
||||
|
||||
test "PUT /issue_categories/:id.xml with invalid parameters should return errors" do
|
||||
assert_no_difference 'IssueCategory.count' do
|
||||
put '/issue_categories/2.xml',
|
||||
:params => {:issue_category => {:name => ''}},
|
||||
:headers => credentials('jsmith')
|
||||
end
|
||||
assert_response :unprocessable_entity
|
||||
assert_equal 'application/xml', @response.content_type
|
||||
|
||||
assert_select 'errors error', :text => "Name cannot be blank"
|
||||
end
|
||||
|
||||
test "DELETE /issue_categories/:id.xml should destroy the issue category" do
|
||||
assert_difference 'IssueCategory.count', -1 do
|
||||
delete '/issue_categories/1.xml', :headers => credentials('jsmith')
|
||||
end
|
||||
assert_response :ok
|
||||
assert_equal '', @response.body
|
||||
assert_nil IssueCategory.find_by_id(1)
|
||||
end
|
||||
|
||||
test "DELETE /issue_categories/:id.xml should reassign issues with :reassign_to_id param" do
|
||||
issue_count = Issue.where(:category_id => 1).count
|
||||
assert issue_count > 0
|
||||
|
||||
assert_difference 'IssueCategory.count', -1 do
|
||||
assert_difference 'Issue.where(:category_id => 2).count', 3 do
|
||||
delete '/issue_categories/1.xml',
|
||||
:params => {:reassign_to_id => 2},
|
||||
:headers => credentials('jsmith')
|
||||
end
|
||||
end
|
||||
assert_response :ok
|
||||
assert_equal '', @response.body
|
||||
assert_nil IssueCategory.find_by_id(1)
|
||||
end
|
||||
end
|
84
test/integration/api_test/issue_relations_test.rb
Normal file
84
test/integration/api_test/issue_relations_test.rb
Normal file
|
@ -0,0 +1,84 @@
|
|||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2017 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::IssueRelationsTest < Redmine::ApiTest::Base
|
||||
fixtures :projects, :trackers, :issue_statuses, :issues,
|
||||
:enumerations, :users, :issue_categories,
|
||||
:projects_trackers,
|
||||
:roles,
|
||||
:member_roles,
|
||||
:members,
|
||||
:enabled_modules,
|
||||
:issue_relations
|
||||
|
||||
test "GET /issues/:issue_id/relations.xml should return issue relations" do
|
||||
get '/issues/9/relations.xml', :headers => credentials('jsmith')
|
||||
|
||||
assert_response :success
|
||||
assert_equal 'application/xml', @response.content_type
|
||||
|
||||
assert_select 'relations[type=array] relation id', :text => '1'
|
||||
end
|
||||
|
||||
test "POST /issues/:issue_id/relations.xml should create the relation" do
|
||||
assert_difference('IssueRelation.count') do
|
||||
post '/issues/2/relations.xml',
|
||||
:params => {:relation => {:issue_to_id => 7, :relation_type => 'relates'}},
|
||||
:headers => credentials('jsmith')
|
||||
end
|
||||
|
||||
relation = IssueRelation.order('id DESC').first
|
||||
assert_equal 2, relation.issue_from_id
|
||||
assert_equal 7, relation.issue_to_id
|
||||
assert_equal 'relates', relation.relation_type
|
||||
|
||||
assert_response :created
|
||||
assert_equal 'application/xml', @response.content_type
|
||||
assert_select 'relation id', :text => relation.id.to_s
|
||||
end
|
||||
|
||||
test "POST /issues/:issue_id/relations.xml with failure should return errors" do
|
||||
assert_no_difference('IssueRelation.count') do
|
||||
post '/issues/2/relations.xml',
|
||||
:params => {:relation => {:issue_to_id => 7, :relation_type => 'foo'}},
|
||||
:headers => credentials('jsmith')
|
||||
end
|
||||
|
||||
assert_response :unprocessable_entity
|
||||
assert_select 'errors error', :text => /Relation type is not included in the list/
|
||||
end
|
||||
|
||||
test "GET /relations/:id.xml should return the relation" do
|
||||
get '/relations/2.xml', :headers => credentials('jsmith')
|
||||
|
||||
assert_response :success
|
||||
assert_equal 'application/xml', @response.content_type
|
||||
assert_select 'relation id', :text => '2'
|
||||
end
|
||||
|
||||
test "DELETE /relations/:id.xml should delete the relation" do
|
||||
assert_difference('IssueRelation.count', -1) do
|
||||
delete '/relations/2.xml', :headers => credentials('jsmith')
|
||||
end
|
||||
|
||||
assert_response :ok
|
||||
assert_equal '', @response.body
|
||||
assert_nil IssueRelation.find_by_id(2)
|
||||
end
|
||||
end
|
32
test/integration/api_test/issue_statuses_test.rb
Normal file
32
test/integration/api_test/issue_statuses_test.rb
Normal file
|
@ -0,0 +1,32 @@
|
|||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2017 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::IssueStatusesTest < Redmine::ApiTest::Base
|
||||
fixtures :issue_statuses
|
||||
|
||||
test "GET /issue_statuses.xml should return issue statuses" do
|
||||
get '/issue_statuses.xml'
|
||||
|
||||
assert_response :success
|
||||
assert_equal 'application/xml', @response.content_type
|
||||
assert_select 'issue_statuses[type=array] issue_status id', :text => '2' do
|
||||
assert_select '~ name', :text => 'Assigned'
|
||||
end
|
||||
end
|
||||
end
|
978
test/integration/api_test/issues_test.rb
Normal file
978
test/integration/api_test/issues_test.rb
Normal file
|
@ -0,0 +1,978 @@
|
|||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2017 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::IssuesTest < Redmine::ApiTest::Base
|
||||
fixtures :projects,
|
||||
:users,
|
||||
:roles,
|
||||
:members,
|
||||
:member_roles,
|
||||
:issues,
|
||||
:issue_statuses,
|
||||
:issue_relations,
|
||||
:versions,
|
||||
:trackers,
|
||||
:projects_trackers,
|
||||
:issue_categories,
|
||||
:enabled_modules,
|
||||
:enumerations,
|
||||
:attachments,
|
||||
:workflows,
|
||||
:custom_fields,
|
||||
:custom_values,
|
||||
:custom_fields_projects,
|
||||
:custom_fields_trackers,
|
||||
:time_entries,
|
||||
:journals,
|
||||
:journal_details,
|
||||
:queries,
|
||||
:attachments
|
||||
|
||||
test "GET /issues.xml should contain metadata" do
|
||||
get '/issues.xml'
|
||||
assert_select 'issues[type=array][total_count][limit="25"][offset="0"]'
|
||||
end
|
||||
|
||||
test "GET /issues.xml with nometa param should not contain metadata" do
|
||||
get '/issues.xml?nometa=1'
|
||||
assert_select 'issues[type=array]:not([total_count]):not([limit]):not([offset])'
|
||||
end
|
||||
|
||||
test "GET /issues.xml with nometa header should not contain metadata" do
|
||||
get '/issues.xml', :headers => {'X-Redmine-Nometa' => '1'}
|
||||
assert_select 'issues[type=array]:not([total_count]):not([limit]):not([offset])'
|
||||
end
|
||||
|
||||
test "GET /issues.xml with offset and limit" do
|
||||
get '/issues.xml?offset=2&limit=3'
|
||||
assert_select 'issues[type=array][total_count][limit="3"][offset="2"]'
|
||||
assert_select 'issues issue', 3
|
||||
end
|
||||
|
||||
test "GET /issues.xml with relations" do
|
||||
get '/issues.xml?include=relations'
|
||||
|
||||
assert_response :success
|
||||
assert_equal 'application/xml', @response.content_type
|
||||
|
||||
assert_select 'issue id', :text => '3' do
|
||||
assert_select '~ relations relation', 1
|
||||
assert_select '~ relations relation[id="2"][issue_id="2"][issue_to_id="3"][relation_type=relates]'
|
||||
end
|
||||
|
||||
assert_select 'issue id', :text => '1' do
|
||||
assert_select '~ relations'
|
||||
assert_select '~ relations relation', 0
|
||||
end
|
||||
end
|
||||
|
||||
test "GET /issues.xml with attachments" do
|
||||
get '/issues.xml?include=attachments'
|
||||
|
||||
assert_response :success
|
||||
assert_equal 'application/xml', @response.content_type
|
||||
|
||||
assert_select 'issue id', :text => '3' do
|
||||
assert_select '~ attachments attachment', 4
|
||||
end
|
||||
|
||||
assert_select 'issue id', :text => '1' do
|
||||
assert_select '~ attachments'
|
||||
assert_select '~ attachments attachment', 0
|
||||
end
|
||||
end
|
||||
|
||||
test "GET /issues.xml with invalid query params" do
|
||||
get '/issues.xml', :params => {:f => ['start_date'], :op => {:start_date => '='}}
|
||||
|
||||
assert_response :unprocessable_entity
|
||||
assert_equal 'application/xml', @response.content_type
|
||||
assert_select 'errors error', :text => "Start date cannot be blank"
|
||||
end
|
||||
|
||||
test "GET /issues.xml with custom field filter" do
|
||||
get '/issues.xml',
|
||||
:params => {:set_filter => 1, :f => ['cf_1'], :op => {:cf_1 => '='}, :v => {:cf_1 => ['MySQL']}}
|
||||
|
||||
expected_ids = Issue.visible.
|
||||
joins(:custom_values).
|
||||
where(:custom_values => {:custom_field_id => 1, :value => 'MySQL'}).map(&:id)
|
||||
assert expected_ids.any?
|
||||
|
||||
assert_select 'issues > issue > id', :count => expected_ids.count do |ids|
|
||||
ids.each { |id| assert expected_ids.delete(id.children.first.content.to_i) }
|
||||
end
|
||||
end
|
||||
|
||||
test "GET /issues.xml with custom field filter (shorthand method)" do
|
||||
get '/issues.xml', :params => {:cf_1 => 'MySQL'}
|
||||
|
||||
expected_ids = Issue.visible.
|
||||
joins(:custom_values).
|
||||
where(:custom_values => {:custom_field_id => 1, :value => 'MySQL'}).map(&:id)
|
||||
assert expected_ids.any?
|
||||
|
||||
assert_select 'issues > issue > id', :count => expected_ids.count do |ids|
|
||||
ids.each { |id| assert expected_ids.delete(id.children.first.content.to_i) }
|
||||
end
|
||||
end
|
||||
|
||||
def test_index_should_include_issue_attributes
|
||||
get '/issues.xml'
|
||||
assert_select 'issues>issue>is_private', :text => 'false'
|
||||
end
|
||||
|
||||
def test_index_should_allow_timestamp_filtering
|
||||
Issue.delete_all
|
||||
Issue.generate!(:subject => '1').update_column(:updated_on, Time.parse("2014-01-02T10:25:00Z"))
|
||||
Issue.generate!(:subject => '2').update_column(:updated_on, Time.parse("2014-01-02T12:13:00Z"))
|
||||
|
||||
get '/issues.xml', :params => {
|
||||
:set_filter => 1, :f => ['updated_on'], :op => {:updated_on => '<='},
|
||||
:v => {:updated_on => ['2014-01-02T12:00:00Z']}
|
||||
}
|
||||
assert_select 'issues>issue', :count => 1
|
||||
assert_select 'issues>issue>subject', :text => '1'
|
||||
|
||||
get '/issues.xml', :params => {
|
||||
:set_filter => 1, :f => ['updated_on'], :op => {:updated_on => '>='},
|
||||
:v => {:updated_on => ['2014-01-02T12:00:00Z']}
|
||||
}
|
||||
assert_select 'issues>issue', :count => 1
|
||||
assert_select 'issues>issue>subject', :text => '2'
|
||||
|
||||
get '/issues.xml', :params => {
|
||||
:set_filter => 1, :f => ['updated_on'], :op => {:updated_on => '>='},
|
||||
:v => {:updated_on => ['2014-01-02T08:00:00Z']}
|
||||
}
|
||||
assert_select 'issues>issue', :count => 2
|
||||
end
|
||||
|
||||
test "GET /issues.xml with filter" do
|
||||
get '/issues.xml?status_id=5'
|
||||
|
||||
expected_ids = Issue.visible.where(:status_id => 5).map(&:id)
|
||||
assert expected_ids.any?
|
||||
|
||||
assert_select 'issues > issue > id', :count => expected_ids.count do |ids|
|
||||
ids.each { |id| assert expected_ids.delete(id.children.first.content.to_i) }
|
||||
end
|
||||
end
|
||||
|
||||
test "GET /issues.json with filter" do
|
||||
get '/issues.json?status_id=5'
|
||||
|
||||
json = ActiveSupport::JSON.decode(response.body)
|
||||
status_ids_used = json['issues'].collect {|j| j['status']['id'] }
|
||||
assert_equal 3, status_ids_used.length
|
||||
assert status_ids_used.all? {|id| id == 5 }
|
||||
end
|
||||
|
||||
test "GET /issues/:id.xml with journals" do
|
||||
Journal.find(2).update_attribute(:private_notes, true)
|
||||
|
||||
get '/issues/1.xml?include=journals', :headers => credentials('jsmith')
|
||||
|
||||
assert_select 'issue journals[type=array]' do
|
||||
assert_select 'journal[id="1"]' do
|
||||
assert_select 'private_notes', :text => 'false'
|
||||
assert_select 'details[type=array]' do
|
||||
assert_select 'detail[name=status_id]' do
|
||||
assert_select 'old_value', :text => '1'
|
||||
assert_select 'new_value', :text => '2'
|
||||
end
|
||||
end
|
||||
end
|
||||
assert_select 'journal[id="2"]' do
|
||||
assert_select 'private_notes', :text => 'true'
|
||||
assert_select 'details[type=array]'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
test "GET /issues/:id.xml with journals should format timestamps in ISO 8601" do
|
||||
get '/issues/1.xml?include=journals'
|
||||
|
||||
iso_date = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}Z$/
|
||||
assert_select 'issue>created_on', :text => iso_date
|
||||
assert_select 'issue>updated_on', :text => iso_date
|
||||
assert_select 'issue journal>created_on', :text => iso_date
|
||||
end
|
||||
|
||||
test "GET /issues/:id.xml with custom fields" do
|
||||
get '/issues/3.xml'
|
||||
|
||||
assert_select 'issue custom_fields[type=array]' do
|
||||
assert_select 'custom_field[id="1"]' do
|
||||
assert_select 'value', :text => 'MySQL'
|
||||
end
|
||||
end
|
||||
assert_nothing_raised do
|
||||
Hash.from_xml(response.body).to_xml
|
||||
end
|
||||
end
|
||||
|
||||
test "GET /issues/:id.xml with multi custom fields" do
|
||||
field = CustomField.find(1)
|
||||
field.update_attribute :multiple, true
|
||||
issue = Issue.find(3)
|
||||
issue.custom_field_values = {1 => ['MySQL', 'Oracle']}
|
||||
issue.save!
|
||||
|
||||
get '/issues/3.xml'
|
||||
assert_response :success
|
||||
|
||||
assert_select 'issue custom_fields[type=array]' do
|
||||
assert_select 'custom_field[id="1"]' do
|
||||
assert_select 'value[type=array] value', 2
|
||||
end
|
||||
end
|
||||
xml = Hash.from_xml(response.body)
|
||||
custom_fields = xml['issue']['custom_fields']
|
||||
assert_kind_of Array, custom_fields
|
||||
field = custom_fields.detect {|f| f['id'] == '1'}
|
||||
assert_kind_of Hash, field
|
||||
assert_equal ['MySQL', 'Oracle'], field['value'].sort
|
||||
end
|
||||
|
||||
test "GET /issues/:id.json with multi custom fields" do
|
||||
field = CustomField.find(1)
|
||||
field.update_attribute :multiple, true
|
||||
issue = Issue.find(3)
|
||||
issue.custom_field_values = {1 => ['MySQL', 'Oracle']}
|
||||
issue.save!
|
||||
|
||||
get '/issues/3.json'
|
||||
assert_response :success
|
||||
|
||||
json = ActiveSupport::JSON.decode(response.body)
|
||||
custom_fields = json['issue']['custom_fields']
|
||||
assert_kind_of Array, custom_fields
|
||||
field = custom_fields.detect {|f| f['id'] == 1}
|
||||
assert_kind_of Hash, field
|
||||
assert_equal ['MySQL', 'Oracle'], field['value'].sort
|
||||
end
|
||||
|
||||
test "GET /issues/:id.xml with empty value for multi custom field" do
|
||||
field = CustomField.find(1)
|
||||
field.update_attribute :multiple, true
|
||||
issue = Issue.find(3)
|
||||
issue.custom_field_values = {1 => ['']}
|
||||
issue.save!
|
||||
|
||||
get '/issues/3.xml'
|
||||
|
||||
assert_select 'issue custom_fields[type=array]' do
|
||||
assert_select 'custom_field[id="1"]' do
|
||||
assert_select 'value[type=array]:empty'
|
||||
end
|
||||
end
|
||||
xml = Hash.from_xml(response.body)
|
||||
custom_fields = xml['issue']['custom_fields']
|
||||
assert_kind_of Array, custom_fields
|
||||
field = custom_fields.detect {|f| f['id'] == '1'}
|
||||
assert_kind_of Hash, field
|
||||
assert_equal [], field['value']
|
||||
end
|
||||
|
||||
test "GET /issues/:id.json with empty value for multi custom field" do
|
||||
field = CustomField.find(1)
|
||||
field.update_attribute :multiple, true
|
||||
issue = Issue.find(3)
|
||||
issue.custom_field_values = {1 => ['']}
|
||||
issue.save!
|
||||
|
||||
get '/issues/3.json'
|
||||
assert_response :success
|
||||
json = ActiveSupport::JSON.decode(response.body)
|
||||
custom_fields = json['issue']['custom_fields']
|
||||
assert_kind_of Array, custom_fields
|
||||
field = custom_fields.detect {|f| f['id'] == 1}
|
||||
assert_kind_of Hash, field
|
||||
assert_equal [], field['value'].sort
|
||||
end
|
||||
|
||||
test "GET /issues/:id.xml with attachments" do
|
||||
get '/issues/3.xml?include=attachments'
|
||||
|
||||
assert_select 'issue attachments[type=array]' do
|
||||
assert_select 'attachment', 4
|
||||
assert_select 'attachment id', :text => '1' do
|
||||
assert_select '~ filename', :text => 'error281.txt'
|
||||
assert_select '~ content_url', :text => 'http://www.example.com/attachments/download/1/error281.txt'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
test "GET /issues/:id.xml with subtasks" do
|
||||
issue = Issue.generate_with_descendants!(:project_id => 1)
|
||||
get "/issues/#{issue.id}.xml?include=children"
|
||||
|
||||
assert_select 'issue id', :text => issue.id.to_s do
|
||||
assert_select '~ children[type=array] > issue', 2
|
||||
assert_select '~ children[type=array] > issue > children', 1
|
||||
end
|
||||
end
|
||||
|
||||
test "GET /issues/:id.json with subtasks" do
|
||||
issue = Issue.generate_with_descendants!(:project_id => 1)
|
||||
get "/issues/#{issue.id}.json?include=children"
|
||||
|
||||
json = ActiveSupport::JSON.decode(response.body)
|
||||
assert_equal 2, json['issue']['children'].size
|
||||
assert_equal 1, json['issue']['children'].select {|child| child.key?('children')}.size
|
||||
end
|
||||
|
||||
test "GET /issues/:id.json with no spent time should return floats" do
|
||||
issue = Issue.generate!
|
||||
get "/issues/#{issue.id}.json"
|
||||
|
||||
json = ActiveSupport::JSON.decode(response.body)
|
||||
assert_kind_of Float, json['issue']['spent_hours']
|
||||
assert_kind_of Float, json['issue']['total_spent_hours']
|
||||
end
|
||||
|
||||
def test_show_should_include_issue_attributes
|
||||
get '/issues/1.xml'
|
||||
assert_select 'issue>is_private', :text => 'false'
|
||||
end
|
||||
|
||||
test "GET /issues/:id.xml?include=watchers should include watchers" do
|
||||
Watcher.create!(:user_id => 3, :watchable => Issue.find(1))
|
||||
|
||||
get '/issues/1.xml?include=watchers', :headers => credentials('jsmith')
|
||||
|
||||
assert_response :ok
|
||||
assert_equal 'application/xml', response.content_type
|
||||
assert_select 'issue' do
|
||||
assert_select 'watchers', Issue.find(1).watchers.count
|
||||
assert_select 'watchers' do
|
||||
assert_select 'user[id="3"]'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
test "GET /issues/:id.xml should not disclose associated changesets from projects the user has no access to" do
|
||||
project = Project.generate!(:is_public => false)
|
||||
repository = Repository::Subversion.create!(:project => project, :url => "svn://localhost")
|
||||
Issue.find(1).changesets << Changeset.generate!(:repository => repository)
|
||||
assert Issue.find(1).changesets.any?
|
||||
|
||||
get '/issues/1.xml?include=changesets', :headers => credentials('jsmith')
|
||||
|
||||
# the user jsmith has no permission to view the associated changeset
|
||||
assert_select 'issue changesets[type=array]' do
|
||||
assert_select 'changeset', 0
|
||||
end
|
||||
end
|
||||
|
||||
test "GET /issues/:id.xml should contains total_estimated_hours and total_spent_hours" do
|
||||
parent = Issue.find(3)
|
||||
parent.update_columns :estimated_hours => 2.0
|
||||
child = Issue.generate!(:parent_issue_id => parent.id, :estimated_hours => 3.0)
|
||||
TimeEntry.create!(:project => child.project, :issue => child, :user => child.author, :spent_on => child.author.today,
|
||||
:hours => '2.5', :comments => '', :activity_id => TimeEntryActivity.first.id)
|
||||
get '/issues/3.xml'
|
||||
|
||||
assert_equal 'application/xml', response.content_type
|
||||
assert_select 'issue' do
|
||||
assert_select 'estimated_hours', parent.estimated_hours.to_s
|
||||
assert_select 'total_estimated_hours', (parent.estimated_hours.to_f + 3.0).to_s
|
||||
assert_select 'spent_hours', parent.spent_hours.to_s
|
||||
assert_select 'total_spent_hours', (parent.spent_hours.to_f + 2.5).to_s
|
||||
end
|
||||
end
|
||||
|
||||
test "GET /issues/:id.xml should contains total_estimated_hours, and should not contains spent_hours and total_spent_hours when permission does not exists" do
|
||||
parent = Issue.find(3)
|
||||
parent.update_columns :estimated_hours => 2.0
|
||||
child = Issue.generate!(:parent_issue_id => parent.id, :estimated_hours => 3.0)
|
||||
# remove permission!
|
||||
Role.anonymous.remove_permission! :view_time_entries
|
||||
#Role.all.each { |role| role.remove_permission! :view_time_entries }
|
||||
get '/issues/3.xml'
|
||||
|
||||
assert_equal 'application/xml', response.content_type
|
||||
assert_select 'issue' do
|
||||
assert_select 'estimated_hours', parent.estimated_hours.to_s
|
||||
assert_select 'total_estimated_hours', (parent.estimated_hours.to_f + 3.0).to_s
|
||||
assert_select 'spent_hours', false
|
||||
assert_select 'total_spent_hours', false
|
||||
end
|
||||
end
|
||||
|
||||
test "GET /issues/:id.xml should contains visible spent_hours only" do
|
||||
user = User.find_by_login('jsmith')
|
||||
Role.find(1).update(:time_entries_visibility => 'own')
|
||||
parent = Issue.find(3)
|
||||
child = Issue.generate!(:parent_issue_id => parent.id)
|
||||
TimeEntry.generate!(:user => user, :hours => 5.5, :issue_id => parent.id)
|
||||
TimeEntry.generate!(:user => user, :hours => 2, :issue_id => child.id)
|
||||
TimeEntry.generate!(:user => User.find(1), :hours => 100, :issue_id => child.id)
|
||||
get '/issues/3.xml', :headers => credentials(user.login)
|
||||
|
||||
assert_equal 'application/xml', response.content_type
|
||||
assert_select 'issue' do
|
||||
assert_select 'spent_hours', '5.5'
|
||||
assert_select 'total_spent_hours', '7.5'
|
||||
end
|
||||
end
|
||||
|
||||
test "GET /issues/:id.json should contains total_estimated_hours and total_spent_hours" do
|
||||
parent = Issue.find(3)
|
||||
parent.update_columns :estimated_hours => 2.0
|
||||
child = Issue.generate!(:parent_issue_id => parent.id, :estimated_hours => 3.0)
|
||||
TimeEntry.create!(:project => child.project, :issue => child, :user => child.author, :spent_on => child.author.today,
|
||||
:hours => '2.5', :comments => '', :activity_id => TimeEntryActivity.first.id)
|
||||
get '/issues/3.json'
|
||||
|
||||
assert_equal 'application/json', response.content_type
|
||||
json = ActiveSupport::JSON.decode(response.body)
|
||||
assert_equal parent.estimated_hours, json['issue']['estimated_hours']
|
||||
assert_equal (parent.estimated_hours.to_f + 3.0), json['issue']['total_estimated_hours']
|
||||
assert_equal parent.spent_hours, json['issue']['spent_hours']
|
||||
assert_equal (parent.spent_hours.to_f + 2.5), json['issue']['total_spent_hours']
|
||||
end
|
||||
|
||||
test "GET /issues/:id.json should contains total_estimated_hours, and should not contains spent_hours and total_spent_hours when permission does not exists" do
|
||||
parent = Issue.find(3)
|
||||
parent.update_columns :estimated_hours => 2.0
|
||||
child = Issue.generate!(:parent_issue_id => parent.id, :estimated_hours => 3.0)
|
||||
# remove permission!
|
||||
Role.anonymous.remove_permission! :view_time_entries
|
||||
#Role.all.each { |role| role.remove_permission! :view_time_entries }
|
||||
get '/issues/3.json'
|
||||
|
||||
assert_equal 'application/json', response.content_type
|
||||
json = ActiveSupport::JSON.decode(response.body)
|
||||
assert_equal parent.estimated_hours, json['issue']['estimated_hours']
|
||||
assert_equal (parent.estimated_hours.to_f + 3.0), json['issue']['total_estimated_hours']
|
||||
assert_nil json['issue']['spent_hours']
|
||||
assert_nil json['issue']['total_spent_hours']
|
||||
end
|
||||
|
||||
test "GET /issues/:id.json should contains visible spent_hours only" do
|
||||
user = User.find_by_login('jsmith')
|
||||
Role.find(1).update(:time_entries_visibility => 'own')
|
||||
parent = Issue.find(3)
|
||||
child = Issue.generate!(:parent_issue_id => parent.id)
|
||||
TimeEntry.generate!(:user => user, :hours => 5.5, :issue_id => parent.id)
|
||||
TimeEntry.generate!(:user => user, :hours => 2, :issue_id => child.id)
|
||||
TimeEntry.generate!(:user => User.find(1), :hours => 100, :issue_id => child.id)
|
||||
get '/issues/3.json', :headers => credentials(user.login)
|
||||
|
||||
assert_equal 'application/json', response.content_type
|
||||
json = ActiveSupport::JSON.decode(response.body)
|
||||
assert_equal 5.5, json['issue']['spent_hours']
|
||||
assert_equal 7.5, json['issue']['total_spent_hours']
|
||||
end
|
||||
|
||||
test "POST /issues.xml should create an issue with the attributes" do
|
||||
|
||||
payload = <<-XML
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<issue>
|
||||
<project_id>1</project_id>
|
||||
<tracker_id>2</tracker_id>
|
||||
<status_id>3</status_id>
|
||||
<subject>API test</subject>
|
||||
</issue>
|
||||
XML
|
||||
|
||||
assert_difference('Issue.count') do
|
||||
post '/issues.xml',
|
||||
:params => payload,
|
||||
:headers => {"CONTENT_TYPE" => 'application/xml'}.merge(credentials('jsmith'))
|
||||
end
|
||||
issue = Issue.order('id DESC').first
|
||||
assert_equal 1, issue.project_id
|
||||
assert_equal 2, issue.tracker_id
|
||||
assert_equal 3, issue.status_id
|
||||
assert_equal 'API test', issue.subject
|
||||
|
||||
assert_response :created
|
||||
assert_equal 'application/xml', @response.content_type
|
||||
assert_select 'issue > id', :text => issue.id.to_s
|
||||
end
|
||||
|
||||
test "POST /issues.xml with watcher_user_ids should create issue with watchers" do
|
||||
assert_difference('Issue.count') do
|
||||
post '/issues.xml',
|
||||
:params => {
|
||||
:issue => {
|
||||
:project_id => 1, :subject => 'Watchers',
|
||||
:tracker_id => 2, :status_id => 3, :watcher_user_ids => [3, 1]
|
||||
}
|
||||
},
|
||||
:headers => credentials('jsmith')
|
||||
assert_response :created
|
||||
end
|
||||
issue = Issue.order('id desc').first
|
||||
assert_equal 2, issue.watchers.size
|
||||
assert_equal [1, 3], issue.watcher_user_ids.sort
|
||||
end
|
||||
|
||||
test "POST /issues.xml with failure should return errors" do
|
||||
assert_no_difference('Issue.count') do
|
||||
post '/issues.xml',
|
||||
:params => {:issue => {:project_id => 1}},
|
||||
:headers => credentials('jsmith')
|
||||
end
|
||||
|
||||
assert_select 'errors error', :text => "Subject cannot be blank"
|
||||
end
|
||||
|
||||
test "POST /issues.json should create an issue with the attributes" do
|
||||
|
||||
payload = <<-JSON
|
||||
{
|
||||
"issue": {
|
||||
"project_id": "1",
|
||||
"tracker_id": "2",
|
||||
"status_id": "3",
|
||||
"subject": "API test"
|
||||
}
|
||||
}
|
||||
JSON
|
||||
|
||||
assert_difference('Issue.count') do
|
||||
post '/issues.json',
|
||||
:params => payload,
|
||||
:headers => {"CONTENT_TYPE" => 'application/json'}.merge(credentials('jsmith'))
|
||||
end
|
||||
|
||||
issue = Issue.order('id DESC').first
|
||||
assert_equal 1, issue.project_id
|
||||
assert_equal 2, issue.tracker_id
|
||||
assert_equal 3, issue.status_id
|
||||
assert_equal 'API test', issue.subject
|
||||
end
|
||||
|
||||
test "POST /issues.json should accept project identifier as project_id" do
|
||||
assert_difference('Issue.count') do
|
||||
post '/issues.json',
|
||||
:params => {:issue => {:project_id => 'subproject1', :tracker_id => 2, :subject => 'Foo'}},
|
||||
:headers => credentials('jsmith')
|
||||
|
||||
assert_response :created
|
||||
end
|
||||
end
|
||||
|
||||
test "POST /issues.json without tracker_id should accept custom fields" do
|
||||
field = IssueCustomField.generate!(
|
||||
:field_format => 'list',
|
||||
:multiple => true,
|
||||
:possible_values => ["V1", "V2", "V3"],
|
||||
:default_value => "V2",
|
||||
:is_for_all => true,
|
||||
:trackers => Tracker.all.to_a
|
||||
)
|
||||
|
||||
payload = <<-JSON
|
||||
{
|
||||
"issue": {
|
||||
"project_id": "1",
|
||||
"subject": "Multivalued custom field",
|
||||
"custom_field_values":{"#{field.id}":["V1","V3"]}
|
||||
}
|
||||
}
|
||||
JSON
|
||||
|
||||
assert_difference('Issue.count') do
|
||||
post '/issues.json',
|
||||
:params => payload,
|
||||
:headers => {"CONTENT_TYPE" => 'application/json'}.merge(credentials('jsmith'))
|
||||
end
|
||||
|
||||
assert_response :created
|
||||
issue = Issue.order('id DESC').first
|
||||
assert_equal ["V1", "V3"], issue.custom_field_value(field).sort
|
||||
end
|
||||
|
||||
test "POST /issues.json with omitted custom field should set default value" do
|
||||
field = IssueCustomField.generate!(:default_value => "Default")
|
||||
|
||||
issue = new_record(Issue) do
|
||||
post '/issues.json',
|
||||
:params => {:issue => {:project_id => 1, :subject => 'API', :custom_field_values => {}}},
|
||||
:headers => credentials('jsmith')
|
||||
end
|
||||
assert_equal "Default", issue.custom_field_value(field)
|
||||
end
|
||||
|
||||
test "POST /issues.json with custom field set to blank should not set default value" do
|
||||
field = IssueCustomField.generate!(:default_value => "Default")
|
||||
|
||||
issue = new_record(Issue) do
|
||||
post '/issues.json',
|
||||
:params => {:issue => {:project_id => 1, :subject => 'API', :custom_field_values => {field.id.to_s => ""}}},
|
||||
:headers => credentials('jsmith')
|
||||
end
|
||||
assert_equal "", issue.custom_field_value(field)
|
||||
end
|
||||
|
||||
test "POST /issues.json with failure should return errors" do
|
||||
assert_no_difference('Issue.count') do
|
||||
post '/issues.json',
|
||||
:params => {:issue => {:project_id => 1}},
|
||||
:headers => credentials('jsmith')
|
||||
end
|
||||
|
||||
json = ActiveSupport::JSON.decode(response.body)
|
||||
assert json['errors'].include?("Subject cannot be blank")
|
||||
end
|
||||
|
||||
test "POST /issues.json with invalid project_id should respond with 422" do
|
||||
post '/issues.json',
|
||||
:params => {:issue => {:project_id => 999, :subject => "API"}},
|
||||
:headers => credentials('jsmith')
|
||||
assert_response 422
|
||||
end
|
||||
|
||||
test "PUT /issues/:id.xml" do
|
||||
assert_difference('Journal.count') do
|
||||
put '/issues/6.xml',
|
||||
:params => {:issue => {:subject => 'API update', :notes => 'A new note'}},
|
||||
:headers => credentials('jsmith')
|
||||
end
|
||||
|
||||
issue = Issue.find(6)
|
||||
assert_equal "API update", issue.subject
|
||||
journal = Journal.last
|
||||
assert_equal "A new note", journal.notes
|
||||
end
|
||||
|
||||
test "PUT /issues/:id.xml with custom fields" do
|
||||
put '/issues/3.xml',
|
||||
:params => {:issue => {:custom_fields => [
|
||||
{'id' => '1', 'value' => 'PostgreSQL' },
|
||||
{'id' => '2', 'value' => '150'}
|
||||
]}
|
||||
},
|
||||
:headers => credentials('jsmith')
|
||||
|
||||
issue = Issue.find(3)
|
||||
assert_equal '150', issue.custom_value_for(2).value
|
||||
assert_equal 'PostgreSQL', issue.custom_value_for(1).value
|
||||
end
|
||||
|
||||
test "PUT /issues/:id.xml with multi custom fields" do
|
||||
field = CustomField.find(1)
|
||||
field.update_attribute :multiple, true
|
||||
|
||||
put '/issues/3.xml',
|
||||
:params => {:issue => {:custom_fields => [
|
||||
{'id' => '1', 'value' => ['MySQL', 'PostgreSQL'] },
|
||||
{'id' => '2', 'value' => '150'}
|
||||
]}
|
||||
},
|
||||
:headers => credentials('jsmith')
|
||||
|
||||
issue = Issue.find(3)
|
||||
assert_equal '150', issue.custom_value_for(2).value
|
||||
assert_equal ['MySQL', 'PostgreSQL'], issue.custom_field_value(1).sort
|
||||
end
|
||||
|
||||
test "PUT /issues/:id.xml with project change" do
|
||||
put '/issues/3.xml',
|
||||
:params => {:issue => {:project_id => 2, :subject => 'Project changed'}},
|
||||
:headers => credentials('jsmith')
|
||||
|
||||
issue = Issue.find(3)
|
||||
assert_equal 2, issue.project_id
|
||||
assert_equal 'Project changed', issue.subject
|
||||
end
|
||||
|
||||
test "PUT /issues/:id.xml with notes only" do
|
||||
assert_difference('Journal.count') do
|
||||
put '/issues/6.xml',
|
||||
:params => {:issue => {:notes => 'Notes only'}},
|
||||
:headers => credentials('jsmith')
|
||||
end
|
||||
|
||||
journal = Journal.last
|
||||
assert_equal "Notes only", journal.notes
|
||||
end
|
||||
|
||||
test "PUT /issues/:id.json with omitted custom field should not change blank value to default value" do
|
||||
field = IssueCustomField.generate!(:default_value => "Default")
|
||||
issue = Issue.generate!(:project_id => 1, :tracker_id => 1, :custom_field_values => {field.id.to_s => ""})
|
||||
assert_equal "", issue.reload.custom_field_value(field)
|
||||
|
||||
assert_difference('Journal.count') do
|
||||
put "/issues/#{issue.id}.json",
|
||||
:params => {:issue => {:custom_field_values => {}, :notes => 'API'}},
|
||||
:headers => credentials('jsmith')
|
||||
end
|
||||
|
||||
assert_equal "", issue.reload.custom_field_value(field)
|
||||
end
|
||||
|
||||
test "PUT /issues/:id.json with custom field set to blank should not change blank value to default value" do
|
||||
field = IssueCustomField.generate!(:default_value => "Default")
|
||||
issue = Issue.generate!(:project_id => 1, :tracker_id => 1, :custom_field_values => {field.id.to_s => ""})
|
||||
assert_equal "", issue.reload.custom_field_value(field)
|
||||
|
||||
assert_difference('Journal.count') do
|
||||
put "/issues/#{issue.id}.json",
|
||||
:params => {:issue => {:custom_field_values => {field.id.to_s => ""}, :notes => 'API'}},
|
||||
:headers => credentials('jsmith')
|
||||
end
|
||||
|
||||
assert_equal "", issue.reload.custom_field_value(field)
|
||||
end
|
||||
|
||||
test "PUT /issues/:id.json with tracker change and omitted custom field specific to that tracker should set default value" do
|
||||
field = IssueCustomField.generate!(:default_value => "Default", :tracker_ids => [2])
|
||||
issue = Issue.generate!(:project_id => 1, :tracker_id => 1)
|
||||
|
||||
assert_difference('Journal.count') do
|
||||
put "/issues/#{issue.id}.json",
|
||||
:params => {:issue => {:tracker_id => 2, :custom_field_values => {}, :notes => 'API'}},
|
||||
:headers => credentials('jsmith')
|
||||
end
|
||||
|
||||
assert_equal 2, issue.reload.tracker_id
|
||||
assert_equal "Default", issue.reload.custom_field_value(field)
|
||||
end
|
||||
|
||||
test "PUT /issues/:id.json with tracker change and custom field specific to that tracker set to blank should not set default value" do
|
||||
field = IssueCustomField.generate!(:default_value => "Default", :tracker_ids => [2])
|
||||
issue = Issue.generate!(:project_id => 1, :tracker_id => 1)
|
||||
|
||||
assert_difference('Journal.count') do
|
||||
put "/issues/#{issue.id}.json",
|
||||
:params => {:issue => {:tracker_id => 2, :custom_field_values => {field.id.to_s => ""}, :notes => 'API'}},
|
||||
:headers => credentials('jsmith')
|
||||
end
|
||||
|
||||
assert_equal 2, issue.reload.tracker_id
|
||||
assert_equal "", issue.reload.custom_field_value(field)
|
||||
end
|
||||
|
||||
test "PUT /issues/:id.xml with failed update" do
|
||||
put '/issues/6.xml',
|
||||
:params => {:issue => {:subject => ''}},
|
||||
:headers => credentials('jsmith')
|
||||
|
||||
assert_response :unprocessable_entity
|
||||
assert_select 'errors error', :text => "Subject cannot be blank"
|
||||
end
|
||||
|
||||
test "PUT /issues/:id.xml with invalid assignee should return error" do
|
||||
user = User.generate!
|
||||
put '/issues/6.xml',
|
||||
:params => {:issue => {:assigned_to_id => user.id}},
|
||||
:headers => credentials('jsmith')
|
||||
|
||||
assert_response :unprocessable_entity
|
||||
assert_select 'errors error', :text => "Assignee is invalid"
|
||||
end
|
||||
|
||||
test "PUT /issues/:id.json" do
|
||||
assert_difference('Journal.count') do
|
||||
put '/issues/6.json',
|
||||
:params => {:issue => {:subject => 'API update', :notes => 'A new note'}},
|
||||
:headers => credentials('jsmith')
|
||||
|
||||
assert_response :ok
|
||||
assert_equal '', response.body
|
||||
end
|
||||
|
||||
issue = Issue.find(6)
|
||||
assert_equal "API update", issue.subject
|
||||
journal = Journal.last
|
||||
assert_equal "A new note", journal.notes
|
||||
end
|
||||
|
||||
test "PUT /issues/:id.json with failed update" do
|
||||
put '/issues/6.json',
|
||||
:params => {:issue => {:subject => ''}},
|
||||
:headers => credentials('jsmith')
|
||||
|
||||
assert_response :unprocessable_entity
|
||||
json = ActiveSupport::JSON.decode(response.body)
|
||||
assert json['errors'].include?("Subject cannot be blank")
|
||||
end
|
||||
|
||||
test "DELETE /issues/:id.xml" do
|
||||
assert_difference('Issue.count', -1) do
|
||||
delete '/issues/6.xml', :headers => credentials('jsmith')
|
||||
|
||||
assert_response :ok
|
||||
assert_equal '', response.body
|
||||
end
|
||||
assert_nil Issue.find_by_id(6)
|
||||
end
|
||||
|
||||
test "DELETE /issues/:id.json" do
|
||||
assert_difference('Issue.count', -1) do
|
||||
delete '/issues/6.json', :headers => credentials('jsmith')
|
||||
|
||||
assert_response :ok
|
||||
assert_equal '', response.body
|
||||
end
|
||||
assert_nil Issue.find_by_id(6)
|
||||
end
|
||||
|
||||
test "POST /issues/:id/watchers.xml should add watcher" do
|
||||
assert_difference 'Watcher.count' do
|
||||
post '/issues/1/watchers.xml',
|
||||
:params => {:user_id => 3},
|
||||
:headers => credentials('jsmith')
|
||||
|
||||
assert_response :ok
|
||||
assert_equal '', response.body
|
||||
end
|
||||
watcher = Watcher.order('id desc').first
|
||||
assert_equal Issue.find(1), watcher.watchable
|
||||
assert_equal User.find(3), watcher.user
|
||||
end
|
||||
|
||||
test "DELETE /issues/:id/watchers/:user_id.xml should remove watcher" do
|
||||
Watcher.create!(:user_id => 3, :watchable => Issue.find(1))
|
||||
|
||||
assert_difference 'Watcher.count', -1 do
|
||||
delete '/issues/1/watchers/3.xml', :headers => credentials('jsmith')
|
||||
|
||||
assert_response :ok
|
||||
assert_equal '', response.body
|
||||
end
|
||||
assert_equal false, Issue.find(1).watched_by?(User.find(3))
|
||||
end
|
||||
|
||||
def test_create_issue_with_uploaded_file
|
||||
token = xml_upload('test_create_with_upload', credentials('jsmith'))
|
||||
attachment = Attachment.find_by_token(token)
|
||||
|
||||
# create the issue with the upload's token
|
||||
assert_difference 'Issue.count' do
|
||||
post '/issues.xml',
|
||||
:params => {:issue => {:project_id => 1, :subject => 'Uploaded file',
|
||||
:uploads => [{:token => token, :filename => 'test.txt',
|
||||
:content_type => 'text/plain'}]}},
|
||||
:headers => credentials('jsmith')
|
||||
assert_response :created
|
||||
end
|
||||
issue = Issue.order('id DESC').first
|
||||
assert_equal 1, issue.attachments.count
|
||||
assert_equal attachment, issue.attachments.first
|
||||
|
||||
attachment.reload
|
||||
assert_equal 'test.txt', attachment.filename
|
||||
assert_equal 'text/plain', attachment.content_type
|
||||
assert_equal 'test_create_with_upload'.size, attachment.filesize
|
||||
assert_equal 2, attachment.author_id
|
||||
|
||||
# get the issue with its attachments
|
||||
get "/issues/#{issue.id}.xml?include=attachments"
|
||||
assert_response :success
|
||||
xml = Hash.from_xml(response.body)
|
||||
attachments = xml['issue']['attachments']
|
||||
assert_kind_of Array, attachments
|
||||
assert_equal 1, attachments.size
|
||||
url = attachments.first['content_url']
|
||||
assert_not_nil url
|
||||
|
||||
# download the attachment
|
||||
get url
|
||||
assert_response :success
|
||||
assert_equal 'test_create_with_upload', response.body
|
||||
end
|
||||
|
||||
def test_create_issue_with_multiple_uploaded_files_as_xml
|
||||
token1 = xml_upload('File content 1', credentials('jsmith'))
|
||||
token2 = xml_upload('File content 2', credentials('jsmith'))
|
||||
|
||||
payload = <<-XML
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<issue>
|
||||
<project_id>1</project_id>
|
||||
<tracker_id>1</tracker_id>
|
||||
<subject>Issue with multiple attachments</subject>
|
||||
<uploads type="array">
|
||||
<upload>
|
||||
<token>#{token1}</token>
|
||||
<filename>test1.txt</filename>
|
||||
</upload>
|
||||
<upload>
|
||||
<token>#{token2}</token>
|
||||
<filename>test1.txt</filename>
|
||||
</upload>
|
||||
</uploads>
|
||||
</issue>
|
||||
XML
|
||||
|
||||
assert_difference 'Issue.count' do
|
||||
post '/issues.xml',
|
||||
:params => payload,
|
||||
:headers => {"CONTENT_TYPE" => 'application/xml'}.merge(credentials('jsmith'))
|
||||
assert_response :created
|
||||
end
|
||||
issue = Issue.order('id DESC').first
|
||||
assert_equal 2, issue.attachments.count
|
||||
end
|
||||
|
||||
def test_create_issue_with_multiple_uploaded_files_as_json
|
||||
token1 = json_upload('File content 1', credentials('jsmith'))
|
||||
token2 = json_upload('File content 2', credentials('jsmith'))
|
||||
|
||||
payload = <<-JSON
|
||||
{
|
||||
"issue": {
|
||||
"project_id": "1",
|
||||
"tracker_id": "1",
|
||||
"subject": "Issue with multiple attachments",
|
||||
"uploads": [
|
||||
{"token": "#{token1}", "filename": "test1.txt"},
|
||||
{"token": "#{token2}", "filename": "test2.txt"}
|
||||
]
|
||||
}
|
||||
}
|
||||
JSON
|
||||
|
||||
assert_difference 'Issue.count' do
|
||||
post '/issues.json',
|
||||
:params => payload,
|
||||
:headers => {"CONTENT_TYPE" => 'application/json'}.merge(credentials('jsmith'))
|
||||
assert_response :created
|
||||
end
|
||||
issue = Issue.order('id DESC').first
|
||||
assert_equal 2, issue.attachments.count
|
||||
end
|
||||
|
||||
def test_update_issue_with_uploaded_file
|
||||
token = xml_upload('test_upload_with_upload', credentials('jsmith'))
|
||||
attachment = Attachment.find_by_token(token)
|
||||
|
||||
# update the issue with the upload's token
|
||||
assert_difference 'Journal.count' do
|
||||
put '/issues/1.xml',
|
||||
:params => {:issue => {:notes => 'Attachment added',
|
||||
:uploads => [{:token => token, :filename => 'test.txt',
|
||||
:content_type => 'text/plain'}]}},
|
||||
:headers => credentials('jsmith')
|
||||
assert_response :ok
|
||||
assert_equal '', @response.body
|
||||
end
|
||||
|
||||
issue = Issue.find(1)
|
||||
assert_include attachment, issue.attachments
|
||||
end
|
||||
end
|
72
test/integration/api_test/jsonp_test.rb
Normal file
72
test/integration/api_test/jsonp_test.rb
Normal file
|
@ -0,0 +1,72 @@
|
|||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2017 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::JsonpTest < Redmine::ApiTest::Base
|
||||
fixtures :trackers
|
||||
|
||||
def test_should_ignore_jsonp_callback_with_jsonp_disabled
|
||||
with_settings :jsonp_enabled => '0' do
|
||||
get '/trackers.json?jsonp=handler'
|
||||
end
|
||||
|
||||
assert_response :success
|
||||
assert_match %r{^\{"trackers":.+\}$}, response.body
|
||||
assert_equal 'application/json; charset=utf-8', response.headers['Content-Type']
|
||||
end
|
||||
|
||||
def test_jsonp_should_accept_callback_param
|
||||
with_settings :jsonp_enabled => '1' do
|
||||
get '/trackers.json?callback=handler'
|
||||
end
|
||||
|
||||
assert_response :success
|
||||
assert_match %r{^handler\(\{"trackers":.+\}\)$}, response.body
|
||||
assert_equal 'application/javascript; charset=utf-8', response.headers['Content-Type']
|
||||
end
|
||||
|
||||
def test_jsonp_should_accept_jsonp_param
|
||||
with_settings :jsonp_enabled => '1' do
|
||||
get '/trackers.json?jsonp=handler'
|
||||
end
|
||||
|
||||
assert_response :success
|
||||
assert_match %r{^handler\(\{"trackers":.+\}\)$}, response.body
|
||||
assert_equal 'application/javascript; charset=utf-8', response.headers['Content-Type']
|
||||
end
|
||||
|
||||
def test_jsonp_should_strip_invalid_characters_from_callback
|
||||
with_settings :jsonp_enabled => '1' do
|
||||
get '/trackers.json?callback=+-aA$1_.'
|
||||
end
|
||||
|
||||
assert_response :success
|
||||
assert_match %r{^aA1_.\(\{"trackers":.+\}\)$}, response.body
|
||||
assert_equal 'application/javascript; charset=utf-8', response.headers['Content-Type']
|
||||
end
|
||||
|
||||
def test_jsonp_without_callback_should_return_json
|
||||
with_settings :jsonp_enabled => '1' do
|
||||
get '/trackers.json?callback='
|
||||
end
|
||||
|
||||
assert_response :success
|
||||
assert_match %r{^\{"trackers":.+\}$}, response.body
|
||||
assert_equal 'application/json; charset=utf-8', response.headers['Content-Type']
|
||||
end
|
||||
end
|
174
test/integration/api_test/memberships_test.rb
Normal file
174
test/integration/api_test/memberships_test.rb
Normal file
|
@ -0,0 +1,174 @@
|
|||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2017 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::MembershipsTest < Redmine::ApiTest::Base
|
||||
fixtures :projects, :users, :roles, :members, :member_roles
|
||||
|
||||
test "GET /projects/:project_id/memberships.xml should return memberships" do
|
||||
get '/projects/1/memberships.xml', :headers => credentials('jsmith')
|
||||
|
||||
assert_response :success
|
||||
assert_equal 'application/xml', @response.content_type
|
||||
assert_select 'memberships[type=array] membership id', :text => '2' do
|
||||
assert_select '~ user[id="3"][name="Dave Lopper"]'
|
||||
assert_select '~ roles role[id="2"][name=Developer]'
|
||||
end
|
||||
end
|
||||
|
||||
test "GET /projects/:project_id/memberships.json should return memberships" do
|
||||
get '/projects/1/memberships.json', :headers => credentials('jsmith')
|
||||
|
||||
assert_response :success
|
||||
assert_equal 'application/json', @response.content_type
|
||||
json = ActiveSupport::JSON.decode(response.body)
|
||||
assert_equal 3, json["total_count"]
|
||||
assert_equal 25, json["limit"]
|
||||
assert_equal 0, json["offset"]
|
||||
assert_include({
|
||||
"id"=>1,
|
||||
"project" => {"name"=>"eCookbook", "id"=>1},
|
||||
"roles" => [{"name"=>"Manager", "id"=>1}],
|
||||
"user" => {"name"=>"John Smith", "id"=>2}
|
||||
},
|
||||
json["memberships"]
|
||||
)
|
||||
end
|
||||
|
||||
test "GET /projects/:project_id/memberships.xml should succeed for closed project" do
|
||||
project = Project.find(1)
|
||||
project.close
|
||||
assert !project.reload.active?
|
||||
get '/projects/1/memberships.json', :headers => credentials('jsmith')
|
||||
assert_response :success
|
||||
end
|
||||
|
||||
test "GET /projects/:project_id/memberships.xml should include locked users" do
|
||||
assert User.find(3).lock!
|
||||
get '/projects/ecookbook/memberships.xml', :headers => credentials('jsmith')
|
||||
assert_response :success
|
||||
assert_select 'memberships[type=array] membership id', :text => '2' do
|
||||
assert_select '~ user[id="3"][name="Dave Lopper"]'
|
||||
end
|
||||
end
|
||||
|
||||
test "POST /projects/:project_id/memberships.xml should create the membership" do
|
||||
assert_difference 'Member.count' do
|
||||
post '/projects/1/memberships.xml',
|
||||
:params => {:membership => {:user_id => 7, :role_ids => [2,3]}},
|
||||
:headers => credentials('jsmith')
|
||||
|
||||
assert_response :created
|
||||
end
|
||||
end
|
||||
|
||||
test "POST /projects/:project_id/memberships.xml should create the group membership" do
|
||||
group = Group.find(11)
|
||||
|
||||
assert_difference 'Member.count', 1 + group.users.count do
|
||||
post '/projects/1/memberships.xml',
|
||||
:params => {:membership => {:user_id => 11, :role_ids => [2,3]}},
|
||||
:headers => credentials('jsmith')
|
||||
|
||||
assert_response :created
|
||||
end
|
||||
end
|
||||
|
||||
test "POST /projects/:project_id/memberships.xml with invalid parameters should return errors" do
|
||||
assert_no_difference 'Member.count' do
|
||||
post '/projects/1/memberships.xml',
|
||||
:params => {:membership => {:role_ids => [2,3]}},
|
||||
:headers => credentials('jsmith')
|
||||
|
||||
assert_response :unprocessable_entity
|
||||
assert_equal 'application/xml', @response.content_type
|
||||
assert_select 'errors error', :text => "Principal cannot be blank"
|
||||
end
|
||||
end
|
||||
|
||||
test "GET /memberships/:id.xml should return the membership" do
|
||||
get '/memberships/2.xml', :headers => credentials('jsmith')
|
||||
|
||||
assert_response :success
|
||||
assert_equal 'application/xml', @response.content_type
|
||||
assert_select 'membership id', :text => '2' do
|
||||
assert_select '~ user[id="3"][name="Dave Lopper"]'
|
||||
assert_select '~ roles role[id="2"][name=Developer]'
|
||||
end
|
||||
end
|
||||
|
||||
test "GET /memberships/:id.json should return the membership" do
|
||||
get '/memberships/2.json', :headers => credentials('jsmith')
|
||||
|
||||
assert_response :success
|
||||
assert_equal 'application/json', @response.content_type
|
||||
json = ActiveSupport::JSON.decode(response.body)
|
||||
assert_equal(
|
||||
{"membership" => {
|
||||
"id" => 2,
|
||||
"project" => {"name"=>"eCookbook", "id"=>1},
|
||||
"roles" => [{"name"=>"Developer", "id"=>2}],
|
||||
"user" => {"name"=>"Dave Lopper", "id"=>3}}
|
||||
},
|
||||
json)
|
||||
end
|
||||
|
||||
test "PUT /memberships/:id.xml should update the membership" do
|
||||
assert_not_equal [1,2], Member.find(2).role_ids.sort
|
||||
assert_no_difference 'Member.count' do
|
||||
put '/memberships/2.xml',
|
||||
:params => {:membership => {:user_id => 3, :role_ids => [1,2]}},
|
||||
:headers => credentials('jsmith')
|
||||
|
||||
assert_response :ok
|
||||
assert_equal '', @response.body
|
||||
end
|
||||
member = Member.find(2)
|
||||
assert_equal [1,2], member.role_ids.sort
|
||||
end
|
||||
|
||||
test "PUT /memberships/:id.xml with invalid parameters should return errors" do
|
||||
put '/memberships/2.xml',
|
||||
:params => {:membership => {:user_id => 3, :role_ids => [99]}},
|
||||
:headers => credentials('jsmith')
|
||||
|
||||
assert_response :unprocessable_entity
|
||||
assert_equal 'application/xml', @response.content_type
|
||||
assert_select 'errors error', :text => "Role cannot be empty"
|
||||
end
|
||||
|
||||
test "DELETE /memberships/:id.xml should destroy the membership" do
|
||||
assert_difference 'Member.count', -1 do
|
||||
delete '/memberships/2.xml', :headers => credentials('jsmith')
|
||||
|
||||
assert_response :ok
|
||||
assert_equal '', @response.body
|
||||
end
|
||||
assert_nil Member.find_by_id(2)
|
||||
end
|
||||
|
||||
test "DELETE /memberships/:id.xml should respond with 422 on failure" do
|
||||
assert_no_difference 'Member.count' do
|
||||
# A membership with an inherited role cannot be deleted
|
||||
Member.find(2).member_roles.first.update_attribute :inherited_from, 99
|
||||
delete '/memberships/2.xml', :headers => credentials('jsmith')
|
||||
|
||||
assert_response :unprocessable_entity
|
||||
end
|
||||
end
|
||||
end
|
61
test/integration/api_test/news_test.rb
Normal file
61
test/integration/api_test/news_test.rb
Normal file
|
@ -0,0 +1,61 @@
|
|||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2017 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::NewsTest < Redmine::ApiTest::Base
|
||||
fixtures :projects, :trackers, :issue_statuses, :issues,
|
||||
:enumerations, :users, :issue_categories,
|
||||
:projects_trackers,
|
||||
:roles,
|
||||
:member_roles,
|
||||
:members,
|
||||
:enabled_modules,
|
||||
:news
|
||||
|
||||
test "GET /news.xml should return news" do
|
||||
get '/news.xml'
|
||||
|
||||
assert_select 'news[type=array] news id', :text => '2'
|
||||
end
|
||||
|
||||
test "GET /news.json should return news" do
|
||||
get '/news.json'
|
||||
|
||||
json = ActiveSupport::JSON.decode(response.body)
|
||||
assert_kind_of Hash, json
|
||||
assert_kind_of Array, json['news']
|
||||
assert_kind_of Hash, json['news'].first
|
||||
assert_equal 2, json['news'].first['id']
|
||||
end
|
||||
|
||||
test "GET /projects/:project_id/news.xml should return news" do
|
||||
get '/projects/ecookbook/news.xml'
|
||||
|
||||
assert_select 'news[type=array] news id', :text => '2'
|
||||
end
|
||||
|
||||
test "GET /projects/:project_id/news.json should return news" do
|
||||
get '/projects/ecookbook/news.json'
|
||||
|
||||
json = ActiveSupport::JSON.decode(response.body)
|
||||
assert_kind_of Hash, json
|
||||
assert_kind_of Array, json['news']
|
||||
assert_kind_of Hash, json['news'].first
|
||||
assert_equal 2, json['news'].first['id']
|
||||
end
|
||||
end
|
252
test/integration/api_test/projects_test.rb
Normal file
252
test/integration/api_test/projects_test.rb
Normal file
|
@ -0,0 +1,252 @@
|
|||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2017 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::ProjectsTest < Redmine::ApiTest::Base
|
||||
fixtures :projects, :versions, :users, :roles, :members, :member_roles, :issues, :journals, :journal_details,
|
||||
:trackers, :projects_trackers, :issue_statuses, :enabled_modules, :enumerations, :boards, :messages,
|
||||
:attachments, :custom_fields, :custom_values, :time_entries, :issue_categories
|
||||
|
||||
def setup
|
||||
super
|
||||
set_tmp_attachments_directory
|
||||
end
|
||||
|
||||
test "GET /projects.xml should return projects" do
|
||||
get '/projects.xml'
|
||||
assert_response :success
|
||||
assert_equal 'application/xml', @response.content_type
|
||||
|
||||
assert_select 'projects>project>id', :text => '1'
|
||||
assert_select 'projects>project>status', :text => '1'
|
||||
assert_select 'projects>project>is_public', :text => 'true'
|
||||
end
|
||||
|
||||
test "GET /projects.json should return projects" do
|
||||
get '/projects.json'
|
||||
assert_response :success
|
||||
assert_equal 'application/json', @response.content_type
|
||||
|
||||
json = ActiveSupport::JSON.decode(response.body)
|
||||
assert_kind_of Hash, json
|
||||
assert_kind_of Array, json['projects']
|
||||
assert_kind_of Hash, json['projects'].first
|
||||
assert json['projects'].first.has_key?('id')
|
||||
end
|
||||
|
||||
test "GET /projects.xml with include=issue_categories should return categories" do
|
||||
get '/projects.xml?include=issue_categories'
|
||||
assert_response :success
|
||||
assert_equal 'application/xml', @response.content_type
|
||||
|
||||
assert_select 'issue_categories[type=array] issue_category[id="2"][name=Recipes]'
|
||||
end
|
||||
|
||||
test "GET /projects.xml with include=trackers should return trackers" do
|
||||
get '/projects.xml?include=trackers'
|
||||
assert_response :success
|
||||
assert_equal 'application/xml', @response.content_type
|
||||
|
||||
assert_select 'trackers[type=array] tracker[id="2"][name="Feature request"]'
|
||||
end
|
||||
|
||||
test "GET /projects.xml with include=enabled_modules should return enabled modules" do
|
||||
get '/projects.xml?include=enabled_modules'
|
||||
assert_response :success
|
||||
assert_equal 'application/xml', @response.content_type
|
||||
|
||||
assert_select 'enabled_modules[type=array] enabled_module[name=issue_tracking]'
|
||||
end
|
||||
|
||||
test "GET /projects/:id.xml should return the project" do
|
||||
get '/projects/1.xml'
|
||||
assert_response :success
|
||||
assert_equal 'application/xml', @response.content_type
|
||||
|
||||
assert_select 'project>id', :text => '1'
|
||||
assert_select 'project>status', :text => '1'
|
||||
assert_select 'project>is_public', :text => 'true'
|
||||
assert_select 'custom_field[name="Development status"]', :text => 'Stable'
|
||||
|
||||
assert_select 'trackers', 0
|
||||
assert_select 'issue_categories', 0
|
||||
end
|
||||
|
||||
test "GET /projects/:id.json should return the project" do
|
||||
get '/projects/1.json'
|
||||
|
||||
json = ActiveSupport::JSON.decode(response.body)
|
||||
assert_kind_of Hash, json
|
||||
assert_kind_of Hash, json['project']
|
||||
assert_equal 1, json['project']['id']
|
||||
end
|
||||
|
||||
test "GET /projects/:id.xml with hidden custom fields should not display hidden custom fields" do
|
||||
ProjectCustomField.find_by_name('Development status').update_attribute :visible, false
|
||||
|
||||
get '/projects/1.xml'
|
||||
assert_response :success
|
||||
assert_equal 'application/xml', @response.content_type
|
||||
|
||||
assert_select 'custom_field[name=?]', 'Development status', 0
|
||||
end
|
||||
|
||||
test "GET /projects/:id.xml with include=issue_categories should return categories" do
|
||||
get '/projects/1.xml?include=issue_categories'
|
||||
assert_response :success
|
||||
assert_equal 'application/xml', @response.content_type
|
||||
|
||||
assert_select 'issue_categories[type=array] issue_category[id="2"][name=Recipes]'
|
||||
end
|
||||
|
||||
test "GET /projects/:id.xml with include=time_entry_activities should return activities" do
|
||||
get '/projects/1.xml?include=time_entry_activities'
|
||||
assert_response :success
|
||||
assert_equal 'application/xml', @response.content_type
|
||||
|
||||
assert_select 'time_entry_activities[type=array] time_entry_activity[id="10"][name=Development]'
|
||||
end
|
||||
|
||||
test "GET /projects/:id.xml with include=trackers should return trackers" do
|
||||
get '/projects/1.xml?include=trackers'
|
||||
assert_response :success
|
||||
assert_equal 'application/xml', @response.content_type
|
||||
|
||||
assert_select 'trackers[type=array] tracker[id="2"][name="Feature request"]'
|
||||
end
|
||||
|
||||
test "GET /projects/:id.xml with include=enabled_modules should return enabled modules" do
|
||||
get '/projects/1.xml?include=enabled_modules'
|
||||
assert_response :success
|
||||
assert_equal 'application/xml', @response.content_type
|
||||
|
||||
assert_select 'enabled_modules[type=array] enabled_module[name=issue_tracking]'
|
||||
end
|
||||
|
||||
test "POST /projects.xml with valid parameters should create the project" do
|
||||
with_settings :default_projects_modules => ['issue_tracking', 'repository'] do
|
||||
assert_difference('Project.count') do
|
||||
post '/projects.xml',
|
||||
:params => {:project => {:name => 'API test', :identifier => 'api-test'}},
|
||||
:headers => credentials('admin')
|
||||
end
|
||||
end
|
||||
|
||||
project = Project.order('id DESC').first
|
||||
assert_equal 'API test', project.name
|
||||
assert_equal 'api-test', project.identifier
|
||||
assert_equal ['issue_tracking', 'repository'], project.enabled_module_names.sort
|
||||
assert_equal Tracker.all.size, project.trackers.size
|
||||
|
||||
assert_response :created
|
||||
assert_equal 'application/xml', @response.content_type
|
||||
assert_select 'project id', :text => project.id.to_s
|
||||
end
|
||||
|
||||
test "POST /projects.xml should accept enabled_module_names attribute" do
|
||||
assert_difference('Project.count') do
|
||||
post '/projects.xml',
|
||||
:params => {:project => {:name => 'API test', :identifier => 'api-test', :enabled_module_names => ['issue_tracking', 'news', 'time_tracking']}},
|
||||
:headers => credentials('admin')
|
||||
end
|
||||
|
||||
project = Project.order('id DESC').first
|
||||
assert_equal ['issue_tracking', 'news', 'time_tracking'], project.enabled_module_names.sort
|
||||
end
|
||||
|
||||
test "POST /projects.xml should accept tracker_ids attribute" do
|
||||
assert_difference('Project.count') do
|
||||
post '/projects.xml',
|
||||
:params => {:project => {:name => 'API test', :identifier => 'api-test', :tracker_ids => [1, 3]}},
|
||||
:headers => credentials('admin')
|
||||
end
|
||||
|
||||
project = Project.order('id DESC').first
|
||||
assert_equal [1, 3], project.trackers.map(&:id).sort
|
||||
end
|
||||
|
||||
test "POST /projects.xml with invalid parameters should return errors" do
|
||||
assert_no_difference('Project.count') do
|
||||
post '/projects.xml',
|
||||
:params => {:project => {:name => 'API test'}},
|
||||
:headers => credentials('admin')
|
||||
end
|
||||
|
||||
assert_response :unprocessable_entity
|
||||
assert_equal 'application/xml', @response.content_type
|
||||
assert_select 'errors error', :text => "Identifier cannot be blank"
|
||||
end
|
||||
|
||||
test "PUT /projects/:id.xml with valid parameters should update the project" do
|
||||
assert_no_difference 'Project.count' do
|
||||
put '/projects/2.xml',
|
||||
:params => {:project => {:name => 'API update'}},
|
||||
:headers => credentials('jsmith')
|
||||
end
|
||||
assert_response :ok
|
||||
assert_equal '', @response.body
|
||||
assert_equal 'application/xml', @response.content_type
|
||||
project = Project.find(2)
|
||||
assert_equal 'API update', project.name
|
||||
end
|
||||
|
||||
test "PUT /projects/:id.xml should accept enabled_module_names attribute" do
|
||||
assert_no_difference 'Project.count' do
|
||||
put '/projects/2.xml',
|
||||
:params => {:project => {:name => 'API update', :enabled_module_names => ['issue_tracking', 'news', 'time_tracking']}},
|
||||
:headers => credentials('admin')
|
||||
end
|
||||
assert_response :ok
|
||||
assert_equal '', @response.body
|
||||
project = Project.find(2)
|
||||
assert_equal ['issue_tracking', 'news', 'time_tracking'], project.enabled_module_names.sort
|
||||
end
|
||||
|
||||
test "PUT /projects/:id.xml should accept tracker_ids attribute" do
|
||||
assert_no_difference 'Project.count' do
|
||||
put '/projects/2.xml',
|
||||
:params => {:project => {:name => 'API update', :tracker_ids => [1, 3]}},
|
||||
:headers => credentials('admin')
|
||||
end
|
||||
assert_response :ok
|
||||
assert_equal '', @response.body
|
||||
project = Project.find(2)
|
||||
assert_equal [1, 3], project.trackers.map(&:id).sort
|
||||
end
|
||||
|
||||
test "PUT /projects/:id.xml with invalid parameters should return errors" do
|
||||
assert_no_difference('Project.count') do
|
||||
put '/projects/2.xml',
|
||||
:params => {:project => {:name => ''}},
|
||||
:headers => credentials('admin')
|
||||
end
|
||||
|
||||
assert_response :unprocessable_entity
|
||||
assert_equal 'application/xml', @response.content_type
|
||||
assert_select 'errors error', :text => "Name cannot be blank"
|
||||
end
|
||||
|
||||
test "DELETE /projects/:id.xml should delete the project" do
|
||||
assert_difference('Project.count',-1) do
|
||||
delete '/projects/2.xml', :headers => credentials('admin')
|
||||
end
|
||||
assert_response :ok
|
||||
assert_equal '', @response.body
|
||||
assert_nil Project.find_by_id(2)
|
||||
end
|
||||
end
|
39
test/integration/api_test/queries_test.rb
Normal file
39
test/integration/api_test/queries_test.rb
Normal file
|
@ -0,0 +1,39 @@
|
|||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2017 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::QueriesTest < Redmine::ApiTest::Base
|
||||
fixtures :projects, :trackers, :issue_statuses, :issues,
|
||||
:enumerations, :users, :issue_categories,
|
||||
:projects_trackers,
|
||||
:roles,
|
||||
:member_roles,
|
||||
:members,
|
||||
:enabled_modules,
|
||||
:queries
|
||||
|
||||
test "GET /queries.xml should return queries" do
|
||||
get '/queries.xml'
|
||||
|
||||
assert_response :success
|
||||
assert_equal 'application/xml', @response.content_type
|
||||
assert_select 'queries[type=array] query id', :text => '4' do
|
||||
assert_select '~ name', :text => 'Public query for all projects'
|
||||
end
|
||||
end
|
||||
end
|
62
test/integration/api_test/roles_test.rb
Normal file
62
test/integration/api_test/roles_test.rb
Normal file
|
@ -0,0 +1,62 @@
|
|||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2017 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::RolesTest < Redmine::ApiTest::Base
|
||||
fixtures :roles
|
||||
|
||||
test "GET /roles.xml should return the roles" do
|
||||
get '/roles.xml'
|
||||
|
||||
assert_response :success
|
||||
assert_equal 'application/xml', @response.content_type
|
||||
|
||||
assert_select 'roles role', 3
|
||||
assert_select 'roles[type=array] role id', :text => '2' do
|
||||
assert_select '~ name', :text => 'Developer'
|
||||
end
|
||||
end
|
||||
|
||||
test "GET /roles.json should return the roles" do
|
||||
get '/roles.json'
|
||||
|
||||
assert_response :success
|
||||
assert_equal 'application/json', @response.content_type
|
||||
|
||||
json = ActiveSupport::JSON.decode(response.body)
|
||||
assert_kind_of Hash, json
|
||||
assert_kind_of Array, json['roles']
|
||||
assert_equal 3, json['roles'].size
|
||||
assert_include({'id' => 2, 'name' => 'Developer'}, json['roles'])
|
||||
end
|
||||
|
||||
test "GET /roles/:id.xml should return the role" do
|
||||
get '/roles/1.xml'
|
||||
|
||||
assert_response :success
|
||||
assert_equal 'application/xml', @response.content_type
|
||||
|
||||
assert_select 'role' do
|
||||
assert_select 'name', :text => 'Manager'
|
||||
assert_select 'role permissions[type=array]' do
|
||||
assert_select 'permission', Role.find(1).permissions.size
|
||||
assert_select 'permission', :text => 'view_issues'
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
92
test/integration/api_test/search_test.rb
Normal file
92
test/integration/api_test/search_test.rb
Normal file
|
@ -0,0 +1,92 @@
|
|||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2017 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::SearchTest < Redmine::ApiTest::Base
|
||||
fixtures :projects, :projects_trackers,
|
||||
:enabled_modules, :roles, :users, :members, :member_roles,
|
||||
:issues, :trackers, :issue_statuses, :enumerations,
|
||||
:workflows,
|
||||
:custom_fields, :custom_values,
|
||||
:custom_fields_projects, :custom_fields_trackers,
|
||||
:repositories, :changesets
|
||||
|
||||
test "GET /search.xml should return xml content" do
|
||||
get '/search.xml'
|
||||
|
||||
assert_response :success
|
||||
assert_equal 'application/xml', @response.content_type
|
||||
end
|
||||
|
||||
test "GET /search.json should return json content" do
|
||||
get '/search.json'
|
||||
|
||||
assert_response :success
|
||||
assert_equal 'application/json', @response.content_type
|
||||
|
||||
json = ActiveSupport::JSON.decode(response.body)
|
||||
assert_kind_of Hash, json
|
||||
assert_kind_of Array, json['results']
|
||||
end
|
||||
|
||||
test "GET /search.xml without query strings should return empty results" do
|
||||
get '/search.xml', :params => {:q => '', :all_words => ''}
|
||||
|
||||
assert_response :success
|
||||
assert_select 'result', 0
|
||||
end
|
||||
|
||||
test "GET /search.xml with query strings should return results" do
|
||||
issue = Issue.generate!(:subject => 'searchapi')
|
||||
|
||||
get '/search.xml', :params => {:q => 'searchapi', :all_words => ''}
|
||||
|
||||
assert_response :success
|
||||
|
||||
assert_select 'results[type=array]' do
|
||||
assert_select 'result', 1
|
||||
|
||||
assert_select 'result' do
|
||||
assert_select 'id', :text => issue.id.to_s
|
||||
assert_select 'title', :text => "Bug ##{issue.id} (New): searchapi"
|
||||
assert_select 'type', :text => 'issue'
|
||||
assert_select 'url', :text => "http://www.example.com/issues/#{issue.id}"
|
||||
assert_select 'description', :text => ''
|
||||
assert_select 'datetime'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
test "GET /search.xml should paginate" do
|
||||
issue = (0..10).map {Issue.generate! :subject => 'search_with_limited_results'}.reverse.map(&:id)
|
||||
|
||||
get '/search.json', :params => {:q => 'search_with_limited_results', :limit => 4}
|
||||
json = ActiveSupport::JSON.decode(response.body)
|
||||
assert_equal 11, json['total_count']
|
||||
assert_equal 0, json['offset']
|
||||
assert_equal 4, json['limit']
|
||||
assert_equal issue[0..3], json['results'].map {|r| r['id']}
|
||||
|
||||
get '/search.json', :params => {:q => 'search_with_limited_results', :offset => 8, :limit => 4}
|
||||
json = ActiveSupport::JSON.decode(response.body)
|
||||
assert_equal 11, json['total_count']
|
||||
assert_equal 8, json['offset']
|
||||
assert_equal 4, json['limit']
|
||||
assert_equal issue[8..10], json['results'].map {|r| r['id']}
|
||||
end
|
||||
end
|
158
test/integration/api_test/time_entries_test.rb
Normal file
158
test/integration/api_test/time_entries_test.rb
Normal file
|
@ -0,0 +1,158 @@
|
|||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2017 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::TimeEntriesTest < Redmine::ApiTest::Base
|
||||
fixtures :projects, :trackers, :issue_statuses, :issues,
|
||||
:enumerations, :users, :issue_categories,
|
||||
:projects_trackers,
|
||||
:roles,
|
||||
:member_roles,
|
||||
:members,
|
||||
:enabled_modules,
|
||||
:time_entries
|
||||
|
||||
test "GET /time_entries.xml should return time entries" do
|
||||
get '/time_entries.xml', :headers => credentials('jsmith')
|
||||
assert_response :success
|
||||
assert_equal 'application/xml', @response.content_type
|
||||
assert_select 'time_entries[type=array] time_entry id', :text => '2'
|
||||
end
|
||||
|
||||
test "GET /time_entries.xml with limit should return limited results" do
|
||||
get '/time_entries.xml?limit=2', :headers => credentials('jsmith')
|
||||
assert_response :success
|
||||
assert_equal 'application/xml', @response.content_type
|
||||
assert_select 'time_entries[type=array] time_entry', 2
|
||||
end
|
||||
|
||||
test "GET /time_entries/:id.xml should return the time entry" do
|
||||
get '/time_entries/2.xml', :headers => credentials('jsmith')
|
||||
assert_response :success
|
||||
assert_equal 'application/xml', @response.content_type
|
||||
assert_select 'time_entry id', :text => '2'
|
||||
end
|
||||
|
||||
test "GET /time_entries/:id.xml on closed project should return the time entry" do
|
||||
project = TimeEntry.find(2).project
|
||||
project.close
|
||||
project.save!
|
||||
|
||||
get '/time_entries/2.xml', :headers => credentials('jsmith')
|
||||
assert_response :success
|
||||
assert_equal 'application/xml', @response.content_type
|
||||
assert_select 'time_entry id', :text => '2'
|
||||
end
|
||||
|
||||
test "POST /time_entries.xml with issue_id should create time entry" do
|
||||
assert_difference 'TimeEntry.count' do
|
||||
post '/time_entries.xml',
|
||||
:params => {:time_entry => {:issue_id => '1', :spent_on => '2010-12-02', :hours => '3.5', :activity_id => '11'}},
|
||||
:headers => credentials('jsmith')
|
||||
end
|
||||
assert_response :created
|
||||
assert_equal 'application/xml', @response.content_type
|
||||
|
||||
entry = TimeEntry.order('id DESC').first
|
||||
assert_equal 'jsmith', entry.user.login
|
||||
assert_equal Issue.find(1), entry.issue
|
||||
assert_equal Project.find(1), entry.project
|
||||
assert_equal Date.parse('2010-12-02'), entry.spent_on
|
||||
assert_equal 3.5, entry.hours
|
||||
assert_equal TimeEntryActivity.find(11), entry.activity
|
||||
end
|
||||
|
||||
test "POST /time_entries.xml with issue_id should accept custom fields" do
|
||||
field = TimeEntryCustomField.create!(:name => 'Test', :field_format => 'string')
|
||||
|
||||
assert_difference 'TimeEntry.count' do
|
||||
post '/time_entries.xml',
|
||||
:params => {:time_entry => {
|
||||
:issue_id => '1', :spent_on => '2010-12-02', :hours => '3.5', :activity_id => '11', :custom_fields => [{:id => field.id.to_s, :value => 'accepted'}]
|
||||
}},
|
||||
:headers => credentials('jsmith')
|
||||
end
|
||||
assert_response :created
|
||||
assert_equal 'application/xml', @response.content_type
|
||||
|
||||
entry = TimeEntry.order('id DESC').first
|
||||
assert_equal 'accepted', entry.custom_field_value(field)
|
||||
end
|
||||
|
||||
test "POST /time_entries.xml with project_id should create time entry" do
|
||||
assert_difference 'TimeEntry.count' do
|
||||
post '/time_entries.xml',
|
||||
:params => {:time_entry => {:project_id => '1', :spent_on => '2010-12-02', :hours => '3.5', :activity_id => '11'}},
|
||||
:headers => credentials('jsmith')
|
||||
end
|
||||
assert_response :created
|
||||
assert_equal 'application/xml', @response.content_type
|
||||
|
||||
entry = TimeEntry.order('id DESC').first
|
||||
assert_equal 'jsmith', entry.user.login
|
||||
assert_nil entry.issue
|
||||
assert_equal Project.find(1), entry.project
|
||||
assert_equal Date.parse('2010-12-02'), entry.spent_on
|
||||
assert_equal 3.5, entry.hours
|
||||
assert_equal TimeEntryActivity.find(11), entry.activity
|
||||
end
|
||||
|
||||
test "POST /time_entries.xml with invalid parameters should return errors" do
|
||||
assert_no_difference 'TimeEntry.count' do
|
||||
post '/time_entries.xml',
|
||||
:params => {:time_entry => {:project_id => '1', :spent_on => '2010-12-02', :activity_id => '11'}},
|
||||
:headers => credentials('jsmith')
|
||||
end
|
||||
assert_response :unprocessable_entity
|
||||
assert_equal 'application/xml', @response.content_type
|
||||
|
||||
assert_select 'errors error', :text => "Hours cannot be blank"
|
||||
end
|
||||
|
||||
test "PUT /time_entries/:id.xml with valid parameters should update time entry" do
|
||||
assert_no_difference 'TimeEntry.count' do
|
||||
put '/time_entries/2.xml',
|
||||
:params => {:time_entry => {:comments => 'API Update'}},
|
||||
:headers => credentials('jsmith')
|
||||
end
|
||||
assert_response :ok
|
||||
assert_equal '', @response.body
|
||||
assert_equal 'API Update', TimeEntry.find(2).comments
|
||||
end
|
||||
|
||||
test "PUT /time_entries/:id.xml with invalid parameters should return errors" do
|
||||
assert_no_difference 'TimeEntry.count' do
|
||||
put '/time_entries/2.xml',
|
||||
:params => {:time_entry => {:hours => '', :comments => 'API Update'}},
|
||||
:headers => credentials('jsmith')
|
||||
end
|
||||
assert_response :unprocessable_entity
|
||||
assert_equal 'application/xml', @response.content_type
|
||||
|
||||
assert_select 'errors error', :text => "Hours cannot be blank"
|
||||
end
|
||||
|
||||
test "DELETE /time_entries/:id.xml should destroy time entry" do
|
||||
assert_difference 'TimeEntry.count', -1 do
|
||||
delete '/time_entries/2.xml', :headers => credentials('jsmith')
|
||||
end
|
||||
assert_response :ok
|
||||
assert_equal '', @response.body
|
||||
assert_nil TimeEntry.find_by_id(2)
|
||||
end
|
||||
end
|
33
test/integration/api_test/trackers_test.rb
Normal file
33
test/integration/api_test/trackers_test.rb
Normal file
|
@ -0,0 +1,33 @@
|
|||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2017 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::TrackersTest < Redmine::ApiTest::Base
|
||||
fixtures :trackers
|
||||
|
||||
test "GET /trackers.xml should return trackers" do
|
||||
get '/trackers.xml'
|
||||
|
||||
assert_response :success
|
||||
assert_equal 'application/xml', @response.content_type
|
||||
|
||||
assert_select 'trackers[type=array] tracker id', :text => '2' do
|
||||
assert_select '~ name', :text => 'Feature request'
|
||||
end
|
||||
end
|
||||
end
|
318
test/integration/api_test/users_test.rb
Normal file
318
test/integration/api_test/users_test.rb
Normal file
|
@ -0,0 +1,318 @@
|
|||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2017 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::UsersTest < Redmine::ApiTest::Base
|
||||
fixtures :users, :email_addresses, :members, :member_roles, :roles, :projects
|
||||
|
||||
test "GET /users.xml should return users" do
|
||||
get '/users.xml', :headers => credentials('admin')
|
||||
|
||||
assert_response :success
|
||||
assert_equal 'application/xml', response.content_type
|
||||
assert_select 'users' do
|
||||
assert_select 'user', User.active.count
|
||||
end
|
||||
end
|
||||
|
||||
test "GET /users.json should return users" do
|
||||
get '/users.json', :headers => credentials('admin')
|
||||
|
||||
assert_response :success
|
||||
assert_equal 'application/json', response.content_type
|
||||
json = ActiveSupport::JSON.decode(response.body)
|
||||
assert json.key?('users')
|
||||
assert_equal User.active.count, json['users'].size
|
||||
end
|
||||
|
||||
test "GET /users/:id.xml should return the user" do
|
||||
get '/users/2.xml'
|
||||
|
||||
assert_response :success
|
||||
assert_select 'user id', :text => '2'
|
||||
end
|
||||
|
||||
test "GET /users/:id.json should return the user" do
|
||||
get '/users/2.json'
|
||||
|
||||
assert_response :success
|
||||
json = ActiveSupport::JSON.decode(response.body)
|
||||
assert_kind_of Hash, json
|
||||
assert_kind_of Hash, json['user']
|
||||
assert_equal 2, json['user']['id']
|
||||
end
|
||||
|
||||
test "GET /users/:id.xml with include=memberships should include memberships" do
|
||||
get '/users/2.xml?include=memberships'
|
||||
|
||||
assert_response :success
|
||||
assert_select 'user memberships', 1
|
||||
end
|
||||
|
||||
test "GET /users/:id.json with include=memberships should include memberships" do
|
||||
get '/users/2.json?include=memberships'
|
||||
|
||||
assert_response :success
|
||||
json = ActiveSupport::JSON.decode(response.body)
|
||||
assert_kind_of Array, json['user']['memberships']
|
||||
assert_equal [{
|
||||
"id"=>1,
|
||||
"project"=>{"name"=>"eCookbook", "id"=>1},
|
||||
"roles"=>[{"name"=>"Manager", "id"=>1}]
|
||||
}], json['user']['memberships']
|
||||
end
|
||||
|
||||
test "GET /users/current.xml should require authentication" do
|
||||
get '/users/current.xml'
|
||||
|
||||
assert_response 401
|
||||
end
|
||||
|
||||
test "GET /users/current.xml should return current user" do
|
||||
get '/users/current.xml', :headers => credentials('jsmith')
|
||||
|
||||
assert_select 'user id', :text => '2'
|
||||
end
|
||||
|
||||
test "GET /users/:id should not return login for other user" do
|
||||
get '/users/3.xml', :headers => credentials('jsmith')
|
||||
assert_response :success
|
||||
assert_select 'user login', 0
|
||||
end
|
||||
|
||||
test "GET /users/:id should return login for current user" do
|
||||
get '/users/2.xml', :headers => credentials('jsmith')
|
||||
assert_response :success
|
||||
assert_select 'user login', :text => 'jsmith'
|
||||
end
|
||||
|
||||
test "GET /users/:id should not return api_key for other user" do
|
||||
get '/users/3.xml', :headers => credentials('jsmith')
|
||||
assert_response :success
|
||||
assert_select 'user api_key', 0
|
||||
end
|
||||
|
||||
test "GET /users/:id should return api_key for current user" do
|
||||
get '/users/2.xml', :headers => credentials('jsmith')
|
||||
assert_response :success
|
||||
assert_select 'user api_key', :text => User.find(2).api_key
|
||||
end
|
||||
|
||||
test "GET /users/:id should not return status for standard user" do
|
||||
get '/users/3.xml', :headers => credentials('jsmith')
|
||||
assert_response :success
|
||||
assert_select 'user status', 0
|
||||
end
|
||||
|
||||
test "GET /users/:id should return status for administrators" do
|
||||
get '/users/2.xml', :headers => credentials('admin')
|
||||
assert_response :success
|
||||
assert_select 'user status', :text => User.find(1).status.to_s
|
||||
end
|
||||
|
||||
test "POST /users.xml with valid parameters should create the user" do
|
||||
assert_difference('User.count') do
|
||||
post '/users.xml',
|
||||
:params => {
|
||||
:user => {
|
||||
:login => 'foo', :firstname => 'Firstname', :lastname => 'Lastname',
|
||||
:mail => 'foo@example.net', :password => 'secret123',
|
||||
:mail_notification => 'only_assigned'
|
||||
}
|
||||
},
|
||||
:headers => credentials('admin')
|
||||
end
|
||||
|
||||
user = User.order('id DESC').first
|
||||
assert_equal 'foo', user.login
|
||||
assert_equal 'Firstname', user.firstname
|
||||
assert_equal 'Lastname', user.lastname
|
||||
assert_equal 'foo@example.net', user.mail
|
||||
assert_equal 'only_assigned', user.mail_notification
|
||||
assert !user.admin?
|
||||
assert user.check_password?('secret123')
|
||||
|
||||
assert_response :created
|
||||
assert_equal 'application/xml', @response.content_type
|
||||
assert_select 'user id', :text => user.id.to_s
|
||||
end
|
||||
|
||||
test "POST /users.json with valid parameters should create the user" do
|
||||
assert_difference('User.count') do
|
||||
post '/users.json',
|
||||
:params => {
|
||||
:user => {
|
||||
:login => 'foo', :firstname => 'Firstname', :lastname => 'Lastname',
|
||||
:mail => 'foo@example.net', :password => 'secret123',
|
||||
:mail_notification => 'only_assigned'
|
||||
}
|
||||
},
|
||||
:headers => credentials('admin')
|
||||
end
|
||||
|
||||
user = User.order('id DESC').first
|
||||
assert_equal 'foo', user.login
|
||||
assert_equal 'Firstname', user.firstname
|
||||
assert_equal 'Lastname', user.lastname
|
||||
assert_equal 'foo@example.net', user.mail
|
||||
assert !user.admin?
|
||||
|
||||
assert_response :created
|
||||
assert_equal 'application/json', @response.content_type
|
||||
json = ActiveSupport::JSON.decode(response.body)
|
||||
assert_kind_of Hash, json
|
||||
assert_kind_of Hash, json['user']
|
||||
assert_equal user.id, json['user']['id']
|
||||
end
|
||||
|
||||
test "POST /users.xml with with invalid parameters should return errors" do
|
||||
assert_no_difference('User.count') do
|
||||
post '/users.xml',
|
||||
:params => {
|
||||
:user =>{
|
||||
:login => 'foo', :lastname => 'Lastname', :mail => 'foo'
|
||||
}
|
||||
},
|
||||
:headers => credentials('admin')
|
||||
end
|
||||
|
||||
assert_response :unprocessable_entity
|
||||
assert_equal 'application/xml', @response.content_type
|
||||
assert_select 'errors error', :text => "First name cannot be blank"
|
||||
end
|
||||
|
||||
test "POST /users.json with with invalid parameters should return errors" do
|
||||
assert_no_difference('User.count') do
|
||||
post '/users.json',
|
||||
:params => {
|
||||
:user => {
|
||||
:login => 'foo', :lastname => 'Lastname', :mail => 'foo'
|
||||
}
|
||||
},
|
||||
:headers => credentials('admin')
|
||||
end
|
||||
|
||||
assert_response :unprocessable_entity
|
||||
assert_equal 'application/json', @response.content_type
|
||||
json = ActiveSupport::JSON.decode(response.body)
|
||||
assert_kind_of Hash, json
|
||||
assert json.has_key?('errors')
|
||||
assert_kind_of Array, json['errors']
|
||||
end
|
||||
|
||||
test "PUT /users/:id.xml with valid parameters should update the user" do
|
||||
assert_no_difference('User.count') do
|
||||
put '/users/2.xml',
|
||||
:params => {
|
||||
:user => {
|
||||
:login => 'jsmith', :firstname => 'John', :lastname => 'Renamed',
|
||||
:mail => 'jsmith@somenet.foo'
|
||||
}
|
||||
},
|
||||
:headers => credentials('admin')
|
||||
end
|
||||
|
||||
user = User.find(2)
|
||||
assert_equal 'jsmith', user.login
|
||||
assert_equal 'John', user.firstname
|
||||
assert_equal 'Renamed', user.lastname
|
||||
assert_equal 'jsmith@somenet.foo', user.mail
|
||||
assert !user.admin?
|
||||
|
||||
assert_response :ok
|
||||
assert_equal '', @response.body
|
||||
end
|
||||
|
||||
test "PUT /users/:id.json with valid parameters should update the user" do
|
||||
assert_no_difference('User.count') do
|
||||
put '/users/2.json',
|
||||
:params => {
|
||||
:user => {
|
||||
:login => 'jsmith', :firstname => 'John', :lastname => 'Renamed',
|
||||
:mail => 'jsmith@somenet.foo'
|
||||
}
|
||||
},
|
||||
:headers => credentials('admin')
|
||||
end
|
||||
|
||||
user = User.find(2)
|
||||
assert_equal 'jsmith', user.login
|
||||
assert_equal 'John', user.firstname
|
||||
assert_equal 'Renamed', user.lastname
|
||||
assert_equal 'jsmith@somenet.foo', user.mail
|
||||
assert !user.admin?
|
||||
|
||||
assert_response :ok
|
||||
assert_equal '', @response.body
|
||||
end
|
||||
|
||||
test "PUT /users/:id.xml with invalid parameters" do
|
||||
assert_no_difference('User.count') do
|
||||
put '/users/2.xml',
|
||||
:params => {
|
||||
:user => {
|
||||
:login => 'jsmith', :firstname => '', :lastname => 'Lastname',
|
||||
:mail => 'foo'
|
||||
}
|
||||
},
|
||||
:headers => credentials('admin')
|
||||
end
|
||||
|
||||
assert_response :unprocessable_entity
|
||||
assert_equal 'application/xml', @response.content_type
|
||||
assert_select 'errors error', :text => "First name cannot be blank"
|
||||
end
|
||||
|
||||
test "PUT /users/:id.json with invalid parameters" do
|
||||
assert_no_difference('User.count') do
|
||||
put '/users/2.json',
|
||||
:params => {
|
||||
:user => {
|
||||
:login => 'jsmith', :firstname => '', :lastname => 'Lastname',
|
||||
:mail => 'foo'
|
||||
}
|
||||
},
|
||||
:headers => credentials('admin')
|
||||
end
|
||||
|
||||
assert_response :unprocessable_entity
|
||||
assert_equal 'application/json', @response.content_type
|
||||
json = ActiveSupport::JSON.decode(response.body)
|
||||
assert_kind_of Hash, json
|
||||
assert json.has_key?('errors')
|
||||
assert_kind_of Array, json['errors']
|
||||
end
|
||||
|
||||
test "DELETE /users/:id.xml should delete the user" do
|
||||
assert_difference('User.count', -1) do
|
||||
delete '/users/2.xml', :headers => credentials('admin')
|
||||
end
|
||||
|
||||
assert_response :ok
|
||||
assert_equal '', @response.body
|
||||
end
|
||||
|
||||
test "DELETE /users/:id.json should delete the user" do
|
||||
assert_difference('User.count', -1) do
|
||||
delete '/users/2.json', :headers => credentials('admin')
|
||||
end
|
||||
|
||||
assert_response :ok
|
||||
assert_equal '', @response.body
|
||||
end
|
||||
end
|
139
test/integration/api_test/versions_test.rb
Normal file
139
test/integration/api_test/versions_test.rb
Normal file
|
@ -0,0 +1,139 @@
|
|||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2017 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::VersionsTest < Redmine::ApiTest::Base
|
||||
fixtures :projects, :trackers, :issue_statuses, :issues,
|
||||
:enumerations, :users, :issue_categories,
|
||||
:projects_trackers,
|
||||
:roles,
|
||||
:member_roles,
|
||||
:members,
|
||||
:enabled_modules,
|
||||
:versions
|
||||
|
||||
test "GET /projects/:project_id/versions.xml should return project versions" do
|
||||
get '/projects/1/versions.xml'
|
||||
|
||||
assert_response :success
|
||||
assert_equal 'application/xml', @response.content_type
|
||||
|
||||
assert_select 'versions[type=array] version id', :text => '2' do
|
||||
assert_select '~ name', :text => '1.0'
|
||||
end
|
||||
end
|
||||
|
||||
test "POST /projects/:project_id/versions.xml should create the version" do
|
||||
assert_difference 'Version.count' do
|
||||
post '/projects/1/versions.xml',
|
||||
:params => {:version => {:name => 'API test'}},
|
||||
:headers => credentials('jsmith')
|
||||
end
|
||||
|
||||
version = Version.order('id DESC').first
|
||||
assert_equal 'API test', version.name
|
||||
|
||||
assert_response :created
|
||||
assert_equal 'application/xml', @response.content_type
|
||||
assert_select 'version id', :text => version.id.to_s
|
||||
end
|
||||
|
||||
test "POST /projects/:project_id/versions.xml should create the version with due date" do
|
||||
assert_difference 'Version.count' do
|
||||
post '/projects/1/versions.xml',
|
||||
:params => {:version => {:name => 'API test', :due_date => '2012-01-24'}},
|
||||
:headers => credentials('jsmith')
|
||||
end
|
||||
|
||||
version = Version.order('id DESC').first
|
||||
assert_equal 'API test', version.name
|
||||
assert_equal Date.parse('2012-01-24'), version.due_date
|
||||
|
||||
assert_response :created
|
||||
assert_equal 'application/xml', @response.content_type
|
||||
assert_select 'version id', :text => version.id.to_s
|
||||
end
|
||||
|
||||
test "POST /projects/:project_id/versions.xml should create the version with custom fields" do
|
||||
field = VersionCustomField.generate!
|
||||
|
||||
assert_difference 'Version.count' do
|
||||
post '/projects/1/versions.xml',
|
||||
:params => {
|
||||
:version => {
|
||||
:name => 'API test',
|
||||
:custom_fields => [
|
||||
{'id' => field.id.to_s, 'value' => 'Some value'}
|
||||
]
|
||||
}
|
||||
},
|
||||
:headers => credentials('jsmith')
|
||||
end
|
||||
|
||||
version = Version.order('id DESC').first
|
||||
assert_equal 'API test', version.name
|
||||
assert_equal 'Some value', version.custom_field_value(field)
|
||||
|
||||
assert_response :created
|
||||
assert_equal 'application/xml', @response.content_type
|
||||
assert_select 'version>custom_fields>custom_field[id=?]>value', field.id.to_s, 'Some value'
|
||||
end
|
||||
|
||||
test "POST /projects/:project_id/versions.xml with failure should return the errors" do
|
||||
assert_no_difference('Version.count') do
|
||||
post '/projects/1/versions.xml',
|
||||
:params => {:version => {:name => ''}},
|
||||
:headers => credentials('jsmith')
|
||||
end
|
||||
|
||||
assert_response :unprocessable_entity
|
||||
assert_select 'errors error', :text => "Name cannot be blank"
|
||||
end
|
||||
|
||||
test "GET /versions/:id.xml should return the version" do
|
||||
get '/versions/2.xml'
|
||||
|
||||
assert_response :success
|
||||
assert_equal 'application/xml', @response.content_type
|
||||
assert_select 'version' do
|
||||
assert_select 'id', :text => '2'
|
||||
assert_select 'name', :text => '1.0'
|
||||
assert_select 'sharing', :text => 'none'
|
||||
end
|
||||
end
|
||||
|
||||
test "PUT /versions/:id.xml should update the version" do
|
||||
put '/versions/2.xml',
|
||||
:params => {:version => {:name => 'API update'}},
|
||||
:headers => credentials('jsmith')
|
||||
|
||||
assert_response :ok
|
||||
assert_equal '', @response.body
|
||||
assert_equal 'API update', Version.find(2).name
|
||||
end
|
||||
|
||||
test "DELETE /versions/:id.xml should destroy the version" do
|
||||
assert_difference 'Version.count', -1 do
|
||||
delete '/versions/3.xml', :headers => credentials('jsmith')
|
||||
end
|
||||
|
||||
assert_response :ok
|
||||
assert_equal '', @response.body
|
||||
assert_nil Version.find_by_id(3)
|
||||
end
|
||||
end
|
209
test/integration/api_test/wiki_pages_test.rb
Normal file
209
test/integration/api_test/wiki_pages_test.rb
Normal file
|
@ -0,0 +1,209 @@
|
|||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2017 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::WikiPagesTest < Redmine::ApiTest::Base
|
||||
fixtures :projects, :users, :roles, :members, :member_roles,
|
||||
:enabled_modules, :wikis, :wiki_pages, :wiki_contents,
|
||||
:wiki_content_versions, :attachments
|
||||
|
||||
test "GET /projects/:project_id/wiki/index.xml should return wiki pages" do
|
||||
get '/projects/ecookbook/wiki/index.xml'
|
||||
assert_response 200
|
||||
assert_equal 'application/xml', response.content_type
|
||||
assert_select 'wiki_pages[type=array]' do
|
||||
assert_select 'wiki_page', :count => Wiki.find(1).pages.count
|
||||
assert_select 'wiki_page' do
|
||||
assert_select 'title', :text => 'CookBook_documentation'
|
||||
assert_select 'version', :text => '3'
|
||||
assert_select 'created_on'
|
||||
assert_select 'updated_on'
|
||||
end
|
||||
assert_select 'wiki_page' do
|
||||
assert_select 'title', :text => 'Page_with_an_inline_image'
|
||||
assert_select 'parent[title=?]', 'CookBook_documentation'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
test "GET /projects/:project_id/wiki/:title.xml should return wiki page" do
|
||||
get '/projects/ecookbook/wiki/CookBook_documentation.xml'
|
||||
assert_response 200
|
||||
assert_equal 'application/xml', response.content_type
|
||||
assert_select 'wiki_page' do
|
||||
assert_select 'title', :text => 'CookBook_documentation'
|
||||
assert_select 'version', :text => '3'
|
||||
assert_select 'text'
|
||||
assert_select 'author'
|
||||
assert_select 'comments'
|
||||
assert_select 'created_on'
|
||||
assert_select 'updated_on'
|
||||
end
|
||||
end
|
||||
|
||||
test "GET /projects/:project_id/wiki/:title.xml?include=attachments should include attachments" do
|
||||
get '/projects/ecookbook/wiki/Page_with_an_inline_image.xml?include=attachments'
|
||||
assert_response 200
|
||||
assert_equal 'application/xml', response.content_type
|
||||
assert_select 'wiki_page' do
|
||||
assert_select 'title', :text => 'Page_with_an_inline_image'
|
||||
assert_select 'attachments[type=array]' do
|
||||
assert_select 'attachment' do
|
||||
assert_select 'id', :text => '3'
|
||||
assert_select 'filename', :text => 'logo.gif'
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
test "GET /projects/:project_id/wiki/:title.xml with unknown title and edit permission should respond with 404" do
|
||||
get '/projects/ecookbook/wiki/Invalid_Page.xml', :headers => credentials('jsmith')
|
||||
assert_response 404
|
||||
assert_equal 'application/xml', response.content_type
|
||||
end
|
||||
|
||||
test "GET /projects/:project_id/wiki/:title/:version.xml should return wiki page version" do
|
||||
get '/projects/ecookbook/wiki/CookBook_documentation/2.xml'
|
||||
assert_response 200
|
||||
assert_equal 'application/xml', response.content_type
|
||||
assert_select 'wiki_page' do
|
||||
assert_select 'title', :text => 'CookBook_documentation'
|
||||
assert_select 'version', :text => '2'
|
||||
assert_select 'text'
|
||||
assert_select 'author'
|
||||
assert_select 'comments', :text => 'Small update'
|
||||
assert_select 'created_on'
|
||||
assert_select 'updated_on'
|
||||
end
|
||||
end
|
||||
|
||||
test "GET /projects/:project_id/wiki/:title/:version.xml without permission should be denied" do
|
||||
Role.anonymous.remove_permission! :view_wiki_edits
|
||||
|
||||
get '/projects/ecookbook/wiki/CookBook_documentation/2.xml'
|
||||
assert_response 401
|
||||
assert_equal 'application/xml', response.content_type
|
||||
end
|
||||
|
||||
test "PUT /projects/:project_id/wiki/:title.xml should update wiki page" do
|
||||
assert_no_difference 'WikiPage.count' do
|
||||
assert_difference 'WikiContent::Version.count' do
|
||||
put '/projects/ecookbook/wiki/CookBook_documentation.xml',
|
||||
:params => {:wiki_page => {:text => 'New content from API', :comments => 'API update'}},
|
||||
:headers => credentials('jsmith')
|
||||
assert_response 200
|
||||
end
|
||||
end
|
||||
|
||||
page = WikiPage.find(1)
|
||||
assert_equal 'New content from API', page.content.text
|
||||
assert_equal 4, page.content.version
|
||||
assert_equal 'API update', page.content.comments
|
||||
assert_equal 'jsmith', page.content.author.login
|
||||
end
|
||||
|
||||
test "PUT /projects/:project_id/wiki/:title.xml with current versino should update wiki page" do
|
||||
assert_no_difference 'WikiPage.count' do
|
||||
assert_difference 'WikiContent::Version.count' do
|
||||
put '/projects/ecookbook/wiki/CookBook_documentation.xml',
|
||||
:params => {:wiki_page => {:text => 'New content from API', :comments => 'API update', :version => '3'}},
|
||||
:headers => credentials('jsmith')
|
||||
assert_response 200
|
||||
end
|
||||
end
|
||||
|
||||
page = WikiPage.find(1)
|
||||
assert_equal 'New content from API', page.content.text
|
||||
assert_equal 4, page.content.version
|
||||
assert_equal 'API update', page.content.comments
|
||||
assert_equal 'jsmith', page.content.author.login
|
||||
end
|
||||
|
||||
test "PUT /projects/:project_id/wiki/:title.xml with stale version should respond with 409" do
|
||||
assert_no_difference 'WikiPage.count' do
|
||||
assert_no_difference 'WikiContent::Version.count' do
|
||||
put '/projects/ecookbook/wiki/CookBook_documentation.xml',
|
||||
:params => {:wiki_page => {:text => 'New content from API', :comments => 'API update', :version => '2'}},
|
||||
:headers => credentials('jsmith')
|
||||
assert_response 409
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
test "PUT /projects/:project_id/wiki/:title.xml should create the page if it does not exist" do
|
||||
assert_difference 'WikiPage.count' do
|
||||
assert_difference 'WikiContent::Version.count' do
|
||||
put '/projects/ecookbook/wiki/New_page_from_API.xml',
|
||||
:params => {:wiki_page => {:text => 'New content from API', :comments => 'API create'}},
|
||||
:headers => credentials('jsmith')
|
||||
assert_response 201
|
||||
end
|
||||
end
|
||||
|
||||
page = WikiPage.order('id DESC').first
|
||||
assert_equal 'New_page_from_API', page.title
|
||||
assert_equal 'New content from API', page.content.text
|
||||
assert_equal 1, page.content.version
|
||||
assert_equal 'API create', page.content.comments
|
||||
assert_equal 'jsmith', page.content.author.login
|
||||
assert_nil page.parent
|
||||
end
|
||||
|
||||
test "PUT /projects/:project_id/wiki/:title.xml with attachment" do
|
||||
set_tmp_attachments_directory
|
||||
attachment = Attachment.create!(:file => uploaded_test_file("testfile.txt", "text/plain"), :author_id => 2)
|
||||
assert_difference 'WikiPage.count' do
|
||||
assert_difference 'WikiContent::Version.count' do
|
||||
put '/projects/ecookbook/wiki/New_page_from_API.xml',
|
||||
:params => {:wiki_page => {:text => 'New content from API with Attachments', :comments => 'API create with Attachments',
|
||||
:uploads => [:token => attachment.token, :filename => 'testfile.txt', :content_type => "text/plain"]}},
|
||||
:headers => credentials('jsmith')
|
||||
assert_response 201
|
||||
end
|
||||
end
|
||||
|
||||
page = WikiPage.order('id DESC').first
|
||||
assert_equal 'New_page_from_API', page.title
|
||||
assert_include attachment, page.attachments
|
||||
assert_equal attachment.filename, page.attachments.first.filename
|
||||
end
|
||||
|
||||
test "PUT /projects/:project_id/wiki/:title.xml with parent" do
|
||||
assert_difference 'WikiPage.count' do
|
||||
assert_difference 'WikiContent::Version.count' do
|
||||
put '/projects/ecookbook/wiki/New_subpage_from_API.xml',
|
||||
:params => {:wiki_page => {:parent_title => 'CookBook_documentation', :text => 'New content from API', :comments => 'API create'}},
|
||||
:headers => credentials('jsmith')
|
||||
assert_response 201
|
||||
end
|
||||
end
|
||||
|
||||
page = WikiPage.order('id DESC').first
|
||||
assert_equal 'New_subpage_from_API', page.title
|
||||
assert_equal WikiPage.find(1), page.parent
|
||||
end
|
||||
|
||||
test "DELETE /projects/:project_id/wiki/:title.xml should destroy the page" do
|
||||
assert_difference 'WikiPage.count', -1 do
|
||||
delete '/projects/ecookbook/wiki/CookBook_documentation.xml', :headers => credentials('jsmith')
|
||||
assert_response 200
|
||||
end
|
||||
|
||||
assert_nil WikiPage.find_by_id(1)
|
||||
end
|
||||
end
|
97
test/integration/application_test.rb
Normal file
97
test/integration/application_test.rb
Normal file
|
@ -0,0 +1,97 @@
|
|||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2017 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 ApplicationTest < Redmine::IntegrationTest
|
||||
include Redmine::I18n
|
||||
|
||||
fixtures :projects, :trackers, :issue_statuses, :issues,
|
||||
:enumerations, :users, :issue_categories,
|
||||
:projects_trackers,
|
||||
:roles,
|
||||
:member_roles,
|
||||
:members,
|
||||
:enabled_modules
|
||||
|
||||
def test_set_localization
|
||||
Setting.default_language = 'en'
|
||||
|
||||
# a french user
|
||||
get '/projects', :headers => {'HTTP_ACCEPT_LANGUAGE' => 'fr,fr-fr;q=0.8,en-us;q=0.5,en;q=0.3'}
|
||||
assert_response :success
|
||||
assert_select 'h2', :text => 'Projets'
|
||||
assert_equal :fr, current_language
|
||||
assert_select "html[lang=?]", "fr"
|
||||
|
||||
# then an italien user
|
||||
get '/projects', :headers => {'HTTP_ACCEPT_LANGUAGE' => 'it;q=0.8,en-us;q=0.5,en;q=0.3'}
|
||||
assert_response :success
|
||||
assert_select 'h2', :text => 'Progetti'
|
||||
assert_equal :it, current_language
|
||||
assert_select "html[lang=?]", "it"
|
||||
|
||||
# not a supported language: default language should be used
|
||||
get '/projects', :headers => {'HTTP_ACCEPT_LANGUAGE' => 'zz'}
|
||||
assert_response :success
|
||||
assert_select 'h2', :text => 'Projects'
|
||||
assert_select "html[lang=?]", "en"
|
||||
end
|
||||
|
||||
def test_token_based_access_should_not_start_session
|
||||
# issue of a private project
|
||||
get '/issues/4.atom'
|
||||
assert_response 302
|
||||
|
||||
rss_key = User.find(2).rss_key
|
||||
get "/issues/4.atom?key=#{rss_key}"
|
||||
assert_response 200
|
||||
assert_nil session[:user_id]
|
||||
end
|
||||
|
||||
def test_missing_template_should_respond_with_404
|
||||
get '/login.png'
|
||||
assert_response 404
|
||||
end
|
||||
|
||||
def test_invalid_token_should_call_custom_handler
|
||||
ActionController::Base.allow_forgery_protection = true
|
||||
post '/issues'
|
||||
assert_response 422
|
||||
assert_include "Invalid form authenticity token.", response.body
|
||||
ensure
|
||||
ActionController::Base.allow_forgery_protection = false
|
||||
end
|
||||
|
||||
def test_localization_should_be_set_correctly_on_invalid_token
|
||||
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 422
|
||||
assert_equal :fr, current_language
|
||||
assert_select "html[lang=?]", "fr"
|
||||
ensure
|
||||
ActionController::Base.allow_forgery_protection = false
|
||||
end
|
||||
|
||||
def test_require_login_with_pdf_format_should_not_error
|
||||
with_settings :login_required => '1' do
|
||||
get '/issues/1.pdf'
|
||||
assert_response 302
|
||||
end
|
||||
end
|
||||
end
|
172
test/integration/attachments_test.rb
Normal file
172
test/integration/attachments_test.rb
Normal file
|
@ -0,0 +1,172 @@
|
|||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2017 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 AttachmentsTest < Redmine::IntegrationTest
|
||||
fixtures :projects, :enabled_modules,
|
||||
:users, :email_addresses,
|
||||
:roles, :members, :member_roles,
|
||||
:trackers, :projects_trackers,
|
||||
:issues, :issue_statuses, :enumerations,
|
||||
:attachments
|
||||
|
||||
def test_upload_should_set_default_content_type
|
||||
log_user('jsmith', 'jsmith')
|
||||
assert_difference 'Attachment.count' do
|
||||
post "/uploads.js?attachment_id=1&filename=foo.txt",
|
||||
:params => "File content",
|
||||
:headers => {"CONTENT_TYPE" => 'application/octet-stream'}
|
||||
assert_response :success
|
||||
end
|
||||
attachment = Attachment.order(:id => :desc).first
|
||||
assert_equal 'text/plain', attachment.content_type
|
||||
end
|
||||
|
||||
def test_upload_should_accept_content_type_param
|
||||
log_user('jsmith', 'jsmith')
|
||||
assert_difference 'Attachment.count' do
|
||||
post "/uploads.js?attachment_id=1&filename=foo&content_type=image/jpeg",
|
||||
:params => "File content",
|
||||
:headers => {"CONTENT_TYPE" => 'application/octet-stream'}
|
||||
assert_response :success
|
||||
end
|
||||
attachment = Attachment.order(:id => :desc).first
|
||||
assert_equal 'image/jpeg', attachment.content_type
|
||||
end
|
||||
|
||||
def test_upload_as_js_and_attach_to_an_issue
|
||||
log_user('jsmith', 'jsmith')
|
||||
|
||||
token = ajax_upload('myupload.txt', 'File content')
|
||||
|
||||
assert_difference 'Issue.count' do
|
||||
post '/projects/ecookbook/issues', :params => {
|
||||
:issue => {:tracker_id => 1, :subject => 'Issue with upload'},
|
||||
:attachments => {'1' => {:filename => 'myupload.txt', :description => 'My uploaded file', :token => token}}
|
||||
}
|
||||
assert_response 302
|
||||
end
|
||||
|
||||
issue = Issue.order('id DESC').first
|
||||
assert_equal 'Issue with upload', issue.subject
|
||||
assert_equal 1, issue.attachments.count
|
||||
|
||||
attachment = issue.attachments.first
|
||||
assert_equal 'myupload.txt', attachment.filename
|
||||
assert_equal 'My uploaded file', attachment.description
|
||||
assert_equal 'File content'.length, attachment.filesize
|
||||
end
|
||||
|
||||
def test_upload_as_js_and_preview_as_inline_attachment
|
||||
log_user('jsmith', 'jsmith')
|
||||
|
||||
token = ajax_upload('myupload.jpg', 'JPEG content')
|
||||
|
||||
post '/issues/preview/new/ecookbook', :params => {
|
||||
:issue => {:tracker_id => 1, :description => 'Inline upload: !myupload.jpg!'},
|
||||
:attachments => {'1' => {:filename => 'myupload.jpg', :description => 'My uploaded file', :token => token}}
|
||||
}
|
||||
assert_response :success
|
||||
|
||||
attachment_path = response.body.match(%r{<img src="(/attachments/download/\d+/myupload.jpg)"})[1]
|
||||
assert_not_nil token, "No attachment path found in response:\n#{response.body}"
|
||||
|
||||
get attachment_path
|
||||
assert_response :success
|
||||
assert_equal 'JPEG content', response.body
|
||||
end
|
||||
|
||||
def test_upload_and_resubmit_after_validation_failure
|
||||
log_user('jsmith', 'jsmith')
|
||||
|
||||
token = ajax_upload('myupload.txt', 'File content')
|
||||
|
||||
assert_no_difference 'Issue.count' do
|
||||
post '/projects/ecookbook/issues', :params => {
|
||||
:issue => {:tracker_id => 1, :subject => ''},
|
||||
:attachments => {'1' => {:filename => 'myupload.txt', :description => 'My uploaded file', :token => token}}
|
||||
}
|
||||
assert_response :success
|
||||
end
|
||||
assert_select 'input[type=hidden][name=?][value=?]', 'attachments[p0][token]', token
|
||||
assert_select 'input[name=?][value=?]', 'attachments[p0][filename]', 'myupload.txt'
|
||||
assert_select 'input[name=?][value=?]', 'attachments[p0][description]', 'My uploaded file'
|
||||
|
||||
assert_difference 'Issue.count' do
|
||||
post '/projects/ecookbook/issues', :params => {
|
||||
:issue => {:tracker_id => 1, :subject => 'Issue with upload'},
|
||||
:attachments => {'p0' => {:filename => 'myupload.txt', :description => 'My uploaded file', :token => token}}
|
||||
}
|
||||
assert_response 302
|
||||
end
|
||||
|
||||
issue = Issue.order('id DESC').first
|
||||
assert_equal 'Issue with upload', issue.subject
|
||||
assert_equal 1, issue.attachments.count
|
||||
|
||||
attachment = issue.attachments.first
|
||||
assert_equal 'myupload.txt', attachment.filename
|
||||
assert_equal 'My uploaded file', attachment.description
|
||||
assert_equal 'File content'.length, attachment.filesize
|
||||
end
|
||||
|
||||
def test_upload_as_js_and_destroy
|
||||
log_user('jsmith', 'jsmith')
|
||||
|
||||
token = ajax_upload('myupload.txt', 'File content')
|
||||
|
||||
attachment = Attachment.order('id DESC').first
|
||||
attachment_path = "/attachments/#{attachment.id}.js?attachment_id=1"
|
||||
assert_include "href: '#{attachment_path}'", response.body, "Path to attachment: #{attachment_path} not found in response:\n#{response.body}"
|
||||
|
||||
assert_difference 'Attachment.count', -1 do
|
||||
delete attachment_path
|
||||
assert_response :success
|
||||
end
|
||||
|
||||
assert_include "$('#attachments_1').remove();", response.body
|
||||
end
|
||||
|
||||
def test_download_should_set_sendfile_header
|
||||
set_fixtures_attachments_directory
|
||||
Rack::Sendfile.any_instance.stubs(:variation).returns("X-Sendfile")
|
||||
|
||||
get "/attachments/download/4"
|
||||
assert_response :success
|
||||
assert_not_nil response.headers["X-Sendfile"]
|
||||
|
||||
ensure
|
||||
set_tmp_attachments_directory
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def ajax_upload(filename, content, attachment_id=1)
|
||||
assert_difference 'Attachment.count' do
|
||||
post "/uploads.js?attachment_id=#{attachment_id}&filename=#{filename}",
|
||||
:params => content,
|
||||
:headers => {"CONTENT_TYPE" => 'application/octet-stream'}
|
||||
assert_response :success
|
||||
assert_equal 'text/javascript', response.content_type
|
||||
end
|
||||
|
||||
token = response.body.match(/\.val\('(\d+\.[0-9a-f]+)'\)/)[1]
|
||||
assert_not_nil token, "No upload token found in response:\n#{response.body}"
|
||||
token
|
||||
end
|
||||
end
|
31
test/integration/feeds_test.rb
Normal file
31
test/integration/feeds_test.rb
Normal file
|
@ -0,0 +1,31 @@
|
|||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2017 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 FeedsTest < Redmine::IntegrationTest
|
||||
fixtures :projects, :trackers, :issue_statuses, :issues,
|
||||
:enumerations, :users, :issue_categories,
|
||||
:projects_trackers, :enabled_modules,
|
||||
:roles, :member_roles, :members
|
||||
|
||||
def test_feeds_should_include_icon_tag
|
||||
get '/projects.atom'
|
||||
assert_response :success
|
||||
assert_select 'feed>icon', :text => %r{^http://www.example.com/favicon.ico}
|
||||
end
|
||||
end
|
305
test/integration/issues_test.rb
Normal file
305
test/integration/issues_test.rb
Normal file
|
@ -0,0 +1,305 @@
|
|||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2017 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 IssuesTest < Redmine::IntegrationTest
|
||||
fixtures :projects,
|
||||
:users, :email_addresses,
|
||||
:roles,
|
||||
:members,
|
||||
:member_roles,
|
||||
:trackers,
|
||||
:projects_trackers,
|
||||
:enabled_modules,
|
||||
:issue_statuses,
|
||||
:issues,
|
||||
:enumerations,
|
||||
:custom_fields,
|
||||
:custom_values,
|
||||
:custom_fields_trackers,
|
||||
:attachments
|
||||
|
||||
# create an issue
|
||||
def test_add_issue
|
||||
log_user('jsmith', 'jsmith')
|
||||
|
||||
get '/projects/ecookbook/issues/new'
|
||||
assert_response :success
|
||||
|
||||
issue = new_record(Issue) do
|
||||
post '/projects/ecookbook/issues', :params => {
|
||||
:issue => {
|
||||
:tracker_id => "1",
|
||||
:start_date => "2006-12-26",
|
||||
:priority_id => "4",
|
||||
:subject => "new test issue",
|
||||
:category_id => "",
|
||||
:description => "new issue",
|
||||
:done_ratio => "0",
|
||||
:due_date => "",
|
||||
:assigned_to_id => "",
|
||||
:custom_field_values => {'2' => 'Value for field 2'}
|
||||
}
|
||||
}
|
||||
end
|
||||
# check redirection
|
||||
assert_redirected_to :controller => 'issues', :action => 'show', :id => issue
|
||||
follow_redirect!
|
||||
|
||||
# check issue attributes
|
||||
assert_equal 'jsmith', issue.author.login
|
||||
assert_equal 1, issue.project.id
|
||||
assert_equal 1, issue.status.id
|
||||
end
|
||||
|
||||
def test_create_issue_by_anonymous_without_permission_should_fail
|
||||
Role.anonymous.remove_permission! :add_issues
|
||||
|
||||
assert_no_difference 'Issue.count' do
|
||||
post '/projects/1/issues', :params => {
|
||||
:issue => {
|
||||
:tracker_id => "1",
|
||||
:subject => "new test issue"
|
||||
}
|
||||
}
|
||||
end
|
||||
assert_response 302
|
||||
end
|
||||
|
||||
def test_create_issue_by_anonymous_with_custom_permission_should_succeed
|
||||
Role.anonymous.remove_permission! :add_issues
|
||||
Member.create!(:project_id => 1, :principal => Group.anonymous, :role_ids => [3])
|
||||
|
||||
issue = new_record(Issue) do
|
||||
post '/projects/1/issues', :params => {
|
||||
:issue => {
|
||||
:tracker_id => "1",
|
||||
:subject => "new test issue"
|
||||
}
|
||||
}
|
||||
assert_response 302
|
||||
end
|
||||
assert_equal User.anonymous, issue.author
|
||||
end
|
||||
|
||||
# add then remove 2 attachments to an issue
|
||||
def test_issue_attachments
|
||||
log_user('jsmith', 'jsmith')
|
||||
set_tmp_attachments_directory
|
||||
|
||||
attachment = new_record(Attachment) do
|
||||
put '/issues/1', :params => {
|
||||
:issue => {:notes => 'Some notes'},
|
||||
:attachments => {'1' => {'file' => uploaded_test_file('testfile.txt', 'text/plain'), 'description' => 'This is an attachment'}}
|
||||
}
|
||||
assert_redirected_to "/issues/1"
|
||||
end
|
||||
|
||||
assert_equal Issue.find(1), attachment.container
|
||||
assert_equal 'testfile.txt', attachment.filename
|
||||
assert_equal 'This is an attachment', attachment.description
|
||||
# verify the size of the attachment stored in db
|
||||
#assert_equal file_data_1.length, attachment.filesize
|
||||
# verify that the attachment was written to disk
|
||||
assert File.exist?(attachment.diskfile)
|
||||
|
||||
# remove the attachments
|
||||
Issue.find(1).attachments.each(&:destroy)
|
||||
assert_equal 0, Issue.find(1).attachments.length
|
||||
end
|
||||
|
||||
def test_next_and_previous_links_should_be_displayed_after_query_grouped_and_sorted_by_version
|
||||
with_settings :default_language => 'en' do
|
||||
get '/projects/ecookbook/issues?set_filter=1&group_by=fixed_version&sort=priority:desc,fixed_version,id'
|
||||
assert_response :success
|
||||
assert_select 'td.id', :text => '5'
|
||||
|
||||
get '/issues/5'
|
||||
assert_response :success
|
||||
assert_select '.next-prev-links .position', :text => '5 of 6'
|
||||
end
|
||||
end
|
||||
|
||||
def test_next_and_previous_links_should_be_displayed_after_filter
|
||||
with_settings :default_language => 'en' do
|
||||
get '/projects/ecookbook/issues?set_filter=1&tracker_id=1'
|
||||
assert_response :success
|
||||
assert_select 'td.id', :text => '5'
|
||||
|
||||
get '/issues/5'
|
||||
assert_response :success
|
||||
assert_select '.next-prev-links .position', :text => '3 of 5'
|
||||
assert_select '.next-prev-links .position a[href^=?]', '/projects/ecookbook/issues?'
|
||||
end
|
||||
end
|
||||
|
||||
def test_next_and_previous_links_should_be_displayed_after_saved_query
|
||||
query = IssueQuery.create!(:name => 'Calendar Query',
|
||||
:visibility => IssueQuery::VISIBILITY_PUBLIC,
|
||||
:filters => {'tracker_id' => {:operator => '=', :values => ['1']}}
|
||||
)
|
||||
|
||||
with_settings :default_language => 'en' do
|
||||
get "/projects/ecookbook/issues?set_filter=1&query_id=#{query.id}"
|
||||
assert_response :success
|
||||
assert_select 'td.id', :text => '5'
|
||||
|
||||
get '/issues/5'
|
||||
assert_response :success
|
||||
assert_select '.next-prev-links .position', :text => '6 of 8'
|
||||
end
|
||||
end
|
||||
|
||||
def test_other_formats_links_on_index
|
||||
get '/projects/ecookbook/issues'
|
||||
|
||||
%w(Atom PDF CSV).each do |format|
|
||||
assert_select 'a[rel=nofollow][href=?]', "/projects/ecookbook/issues.#{format.downcase}", :text => format
|
||||
end
|
||||
end
|
||||
|
||||
def test_other_formats_links_on_index_without_project_id_in_url
|
||||
get '/issues', :params => {
|
||||
:project_id => 'ecookbook'
|
||||
}
|
||||
|
||||
%w(Atom PDF CSV).each do |format|
|
||||
assert_select 'a[rel=nofollow][href=?]', "/issues.#{format.downcase}?project_id=ecookbook", :text => format
|
||||
end
|
||||
end
|
||||
|
||||
def test_pagination_links_on_index
|
||||
with_settings :per_page_options => '2' do
|
||||
get '/projects/ecookbook/issues'
|
||||
|
||||
assert_select 'a[href=?]', '/projects/ecookbook/issues?page=2', :text => '2'
|
||||
end
|
||||
end
|
||||
|
||||
def test_pagination_links_should_preserve_query_parameters
|
||||
with_settings :per_page_options => '2' do
|
||||
get '/projects/ecookbook/issues?foo=bar'
|
||||
|
||||
assert_select 'a[href=?]', '/projects/ecookbook/issues?foo=bar&page=2', :text => '2'
|
||||
end
|
||||
end
|
||||
|
||||
def test_pagination_links_should_not_use_params_as_url_options
|
||||
with_settings :per_page_options => '2' do
|
||||
get '/projects/ecookbook/issues?host=foo'
|
||||
|
||||
assert_select 'a[href=?]', '/projects/ecookbook/issues?host=foo&page=2', :text => '2'
|
||||
end
|
||||
end
|
||||
|
||||
def test_sort_links_on_index
|
||||
get '/projects/ecookbook/issues'
|
||||
|
||||
assert_select 'a[href=?]', '/projects/ecookbook/issues?sort=subject%2Cid%3Adesc', :text => 'Subject'
|
||||
end
|
||||
|
||||
def test_sort_links_should_preserve_query_parameters
|
||||
get '/projects/ecookbook/issues?foo=bar'
|
||||
|
||||
assert_select 'a[href=?]', '/projects/ecookbook/issues?foo=bar&sort=subject%2Cid%3Adesc', :text => 'Subject'
|
||||
end
|
||||
|
||||
def test_sort_links_should_not_use_params_as_url_options
|
||||
get '/projects/ecookbook/issues?host=foo'
|
||||
|
||||
assert_select 'a[href=?]', '/projects/ecookbook/issues?host=foo&sort=subject%2Cid%3Adesc', :text => 'Subject'
|
||||
end
|
||||
|
||||
def test_issue_with_user_custom_field
|
||||
@field = IssueCustomField.create!(:name => 'Tester', :field_format => 'user', :is_for_all => true, :trackers => Tracker.all)
|
||||
Role.anonymous.add_permission! :add_issues, :edit_issues
|
||||
users = Project.find(1).users.sort
|
||||
tester = users.first
|
||||
|
||||
# Issue form
|
||||
get '/projects/ecookbook/issues/new'
|
||||
assert_response :success
|
||||
assert_select 'select[name=?]', "issue[custom_field_values][#{@field.id}]" do
|
||||
assert_select 'option', users.size + 1 # +1 for blank value
|
||||
assert_select 'option[value=?]', tester.id.to_s, :text => tester.name
|
||||
end
|
||||
|
||||
# Create issue
|
||||
issue = new_record(Issue) do
|
||||
post '/projects/ecookbook/issues', :params => {
|
||||
:issue => {
|
||||
:tracker_id => '1',
|
||||
:priority_id => '4',
|
||||
:subject => 'Issue with user custom field',
|
||||
:custom_field_values => {@field.id.to_s => users.first.id.to_s}
|
||||
}
|
||||
}
|
||||
assert_response 302
|
||||
end
|
||||
|
||||
# Issue view
|
||||
follow_redirect!
|
||||
assert_select ".cf_#{@field.id}" do
|
||||
assert_select '.label', :text => 'Tester:'
|
||||
assert_select '.value', :text => tester.name
|
||||
end
|
||||
assert_select 'select[name=?]', "issue[custom_field_values][#{@field.id}]" do
|
||||
assert_select 'option', users.size + 1 # +1 for blank value
|
||||
assert_select 'option[value=?][selected=selected]', tester.id.to_s, :text => tester.name
|
||||
end
|
||||
|
||||
new_tester = users[1]
|
||||
with_settings :default_language => 'en' do
|
||||
# Update issue
|
||||
assert_difference 'Journal.count' do
|
||||
put "/issues/#{issue.id}", :params => {
|
||||
:issue => {
|
||||
:notes => 'Updating custom field',
|
||||
:custom_field_values => {@field.id.to_s => new_tester.id.to_s}
|
||||
}
|
||||
}
|
||||
assert_redirected_to "/issues/#{issue.id}"
|
||||
end
|
||||
# Issue view
|
||||
follow_redirect!
|
||||
assert_select 'ul.details li', :text => "Tester changed from #{tester} to #{new_tester}"
|
||||
end
|
||||
end
|
||||
|
||||
def test_update_using_invalid_http_verbs
|
||||
log_user('jsmith', 'jsmith')
|
||||
subject = 'Updated by an invalid http verb'
|
||||
|
||||
get '/issues/update/1', :params => {:issue => {:subject => subject}}
|
||||
assert_response 404
|
||||
assert_not_equal subject, Issue.find(1).subject
|
||||
|
||||
post '/issues/1', :params => {:issue => {:subject => subject}}
|
||||
assert_response 404
|
||||
assert_not_equal subject, Issue.find(1).subject
|
||||
end
|
||||
|
||||
def test_get_watch_should_be_invalid
|
||||
log_user('jsmith', 'jsmith')
|
||||
|
||||
assert_no_difference 'Watcher.count' do
|
||||
get '/watchers/watch?object_type=issue&object_id=1'
|
||||
assert_response 404
|
||||
end
|
||||
end
|
||||
end
|
127
test/integration/layout_test.rb
Normal file
127
test/integration/layout_test.rb
Normal file
|
@ -0,0 +1,127 @@
|
|||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2017 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 LayoutTest < Redmine::IntegrationTest
|
||||
fixtures :projects, :trackers, :issue_statuses, :issues,
|
||||
:enumerations, :users, :issue_categories,
|
||||
:projects_trackers,
|
||||
:roles,
|
||||
:member_roles,
|
||||
:members,
|
||||
:enabled_modules
|
||||
|
||||
test "browsing to a missing page should render the base layout" do
|
||||
get "/users/100000000"
|
||||
|
||||
assert_response :not_found
|
||||
|
||||
# UsersController uses the admin layout by default
|
||||
assert_select "#admin-menu", :count => 0
|
||||
end
|
||||
|
||||
test "browsing to an unauthorized page should render the base layout" do
|
||||
log_user('jsmith','jsmith')
|
||||
|
||||
get "/admin"
|
||||
assert_response :forbidden
|
||||
assert_select "#admin-menu", :count => 0
|
||||
end
|
||||
|
||||
def test_top_menu_and_search_not_visible_when_login_required
|
||||
with_settings :login_required => '1' do
|
||||
get '/'
|
||||
assert_select "#top-menu > ul", 0
|
||||
assert_select "#quick-search", 0
|
||||
end
|
||||
end
|
||||
|
||||
def test_top_menu_and_search_visible_when_login_not_required
|
||||
with_settings :login_required => '0' do
|
||||
get '/'
|
||||
assert_select "#top-menu > ul"
|
||||
assert_select "#quick-search"
|
||||
end
|
||||
end
|
||||
|
||||
def test_wiki_formatter_header_tags
|
||||
Role.anonymous.add_permission! :add_issues
|
||||
|
||||
get '/projects/ecookbook/issues/new'
|
||||
assert_select 'head script[src^=?]', '/javascripts/jstoolbar/jstoolbar-textile.min.js?'
|
||||
end
|
||||
|
||||
def test_calendar_header_tags
|
||||
with_settings :default_language => 'fr' do
|
||||
get '/issues'
|
||||
assert_include "/javascripts/i18n/datepicker-fr.js", response.body
|
||||
end
|
||||
|
||||
with_settings :default_language => 'en-GB' do
|
||||
get '/issues'
|
||||
assert_include "/javascripts/i18n/datepicker-en-GB.js", response.body
|
||||
end
|
||||
|
||||
with_settings :default_language => 'en' do
|
||||
get '/issues'
|
||||
assert_not_include "/javascripts/i18n/datepicker", response.body
|
||||
end
|
||||
|
||||
with_settings :default_language => 'es' do
|
||||
get '/issues'
|
||||
assert_include "/javascripts/i18n/datepicker-es.js", response.body
|
||||
end
|
||||
|
||||
with_settings :default_language => 'es-PA' do
|
||||
get '/issues'
|
||||
# There is not datepicker-es-PA.js
|
||||
# https://github.com/jquery/jquery-ui/tree/1.11.4/ui/i18n
|
||||
assert_not_include "/javascripts/i18n/datepicker-es.js", response.body
|
||||
end
|
||||
|
||||
with_settings :default_language => 'zh' do
|
||||
get '/issues'
|
||||
assert_include "/javascripts/i18n/datepicker-zh-CN.js", response.body
|
||||
end
|
||||
|
||||
with_settings :default_language => 'zh-TW' do
|
||||
get '/issues'
|
||||
assert_include "/javascripts/i18n/datepicker-zh-TW.js", response.body
|
||||
end
|
||||
|
||||
with_settings :default_language => 'pt' do
|
||||
get '/issues'
|
||||
assert_include "/javascripts/i18n/datepicker-pt.js", response.body
|
||||
end
|
||||
|
||||
with_settings :default_language => 'pt-BR' do
|
||||
get '/issues'
|
||||
assert_include "/javascripts/i18n/datepicker-pt-BR.js", response.body
|
||||
end
|
||||
end
|
||||
|
||||
def test_search_field_outside_project_should_link_to_global_search
|
||||
get '/'
|
||||
assert_select 'div#quick-search form[action="/search"]'
|
||||
end
|
||||
|
||||
def test_search_field_inside_project_should_link_to_project_search
|
||||
get '/projects/ecookbook'
|
||||
assert_select 'div#quick-search form[action="/projects/ecookbook/search"]'
|
||||
end
|
||||
end
|
|
@ -0,0 +1,194 @@
|
|||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2017 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 AttachmentFieldFormatTest < Redmine::IntegrationTest
|
||||
fixtures :projects,
|
||||
:users, :email_addresses,
|
||||
:roles,
|
||||
:members,
|
||||
:member_roles,
|
||||
:trackers,
|
||||
:projects_trackers,
|
||||
:enabled_modules,
|
||||
:issue_statuses,
|
||||
:issues,
|
||||
:enumerations,
|
||||
:custom_fields,
|
||||
:custom_values,
|
||||
:custom_fields_trackers,
|
||||
:attachments
|
||||
|
||||
def setup
|
||||
set_tmp_attachments_directory
|
||||
@field = IssueCustomField.generate!(:name => "File", :field_format => "attachment")
|
||||
log_user "jsmith", "jsmith"
|
||||
end
|
||||
|
||||
def test_new_should_include_inputs
|
||||
get '/projects/ecookbook/issues/new'
|
||||
assert_response :success
|
||||
|
||||
assert_select '[name^=?]', "issue[custom_field_values][#{@field.id}]", 2
|
||||
assert_select 'input[name=?][type=hidden][value=""]', "issue[custom_field_values][#{@field.id}][blank]"
|
||||
end
|
||||
|
||||
def test_create_with_attachment
|
||||
issue = new_record(Issue) do
|
||||
assert_difference 'Attachment.count' do
|
||||
post '/projects/ecookbook/issues', :params => {
|
||||
:issue => {
|
||||
:subject => "Subject",
|
||||
:custom_field_values => {
|
||||
@field.id => {
|
||||
'blank' => '',
|
||||
'1' => {:file => uploaded_test_file("testfile.txt", "text/plain")}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
assert_response 302
|
||||
end
|
||||
end
|
||||
|
||||
custom_value = issue.custom_value_for(@field)
|
||||
assert custom_value
|
||||
assert custom_value.value.present?
|
||||
|
||||
attachment = Attachment.find_by_id(custom_value.value)
|
||||
assert attachment
|
||||
assert_equal custom_value, attachment.container
|
||||
|
||||
follow_redirect!
|
||||
assert_response :success
|
||||
|
||||
# link to the attachment
|
||||
link = css_select(".cf_#{@field.id} .value a")
|
||||
assert_equal 1, link.size
|
||||
assert_equal "testfile.txt", link.text
|
||||
|
||||
# preview the attachment
|
||||
get link.attr('href')
|
||||
assert_response :success
|
||||
assert_template :file
|
||||
end
|
||||
|
||||
def test_create_without_attachment
|
||||
issue = new_record(Issue) do
|
||||
assert_no_difference 'Attachment.count' do
|
||||
post '/projects/ecookbook/issues', :params => {
|
||||
:issue => {
|
||||
:subject => "Subject",
|
||||
:custom_field_values => {
|
||||
@field.id => {:blank => ''}
|
||||
}
|
||||
}
|
||||
}
|
||||
assert_response 302
|
||||
end
|
||||
end
|
||||
|
||||
custom_value = issue.custom_value_for(@field)
|
||||
assert custom_value
|
||||
assert custom_value.value.blank?
|
||||
|
||||
follow_redirect!
|
||||
assert_response :success
|
||||
|
||||
# no links to the attachment
|
||||
assert_select ".cf_#{@field.id} .value a", 0
|
||||
end
|
||||
|
||||
def test_failure_on_create_should_preserve_attachment
|
||||
attachment = new_record(Attachment) do
|
||||
assert_no_difference 'Issue.count' do
|
||||
post '/projects/ecookbook/issues', :params => {
|
||||
:issue => {
|
||||
:subject => "",
|
||||
:custom_field_values => {
|
||||
@field.id => {:file => uploaded_test_file("testfile.txt", "text/plain")}
|
||||
}
|
||||
}
|
||||
}
|
||||
assert_response :success
|
||||
assert_select_error /Subject cannot be blank/
|
||||
end
|
||||
end
|
||||
|
||||
assert_nil attachment.container_id
|
||||
assert_select 'input[name=?][value=?][type=hidden]', "issue[custom_field_values][#{@field.id}][p0][token]", attachment.token
|
||||
assert_select 'input[name=?][value=?]', "issue[custom_field_values][#{@field.id}][p0][filename]", 'testfile.txt'
|
||||
|
||||
issue = new_record(Issue) do
|
||||
assert_no_difference 'Attachment.count' do
|
||||
post '/projects/ecookbook/issues', :params => {
|
||||
:issue => {
|
||||
:subject => "Subject",
|
||||
:custom_field_values => {
|
||||
@field.id => {:token => attachment.token}
|
||||
}
|
||||
}
|
||||
}
|
||||
assert_response 302
|
||||
end
|
||||
end
|
||||
|
||||
custom_value = issue.custom_value_for(@field)
|
||||
assert custom_value
|
||||
assert_equal attachment.id.to_s, custom_value.value
|
||||
assert_equal custom_value, attachment.reload.container
|
||||
end
|
||||
|
||||
def test_create_with_valid_extension
|
||||
@field.extensions_allowed = "txt, log"
|
||||
@field.save!
|
||||
|
||||
attachment = new_record(Attachment) do
|
||||
assert_difference 'Issue.count' do
|
||||
post '/projects/ecookbook/issues', :params => {
|
||||
:issue => {
|
||||
:subject => "Blank",
|
||||
:custom_field_values => {
|
||||
@field.id => {:file => uploaded_test_file("testfile.txt", "text/plain")}
|
||||
}
|
||||
}
|
||||
}
|
||||
assert_response 302
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def test_create_with_invalid_extension_should_fail
|
||||
@field.extensions_allowed = "png, jpeg"
|
||||
@field.save!
|
||||
|
||||
attachment = new_record(Attachment) do
|
||||
assert_no_difference 'Issue.count' do
|
||||
post '/projects/ecookbook/issues', :params => {
|
||||
:issue => {
|
||||
:subject => "Blank",
|
||||
:custom_field_values => {
|
||||
@field.id => {:file => uploaded_test_file("testfile.txt", "text/plain")}
|
||||
}
|
||||
}
|
||||
}
|
||||
assert_response :success
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
124
test/integration/lib/redmine/hook_test.rb
Normal file
124
test/integration/lib/redmine/hook_test.rb
Normal file
|
@ -0,0 +1,124 @@
|
|||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2017 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 HookTest < Redmine::IntegrationTest
|
||||
fixtures :users, :roles, :projects, :members, :member_roles
|
||||
|
||||
# Hooks that are manually registered later
|
||||
class ProjectBasedTemplate < Redmine::Hook::ViewListener
|
||||
def view_layouts_base_html_head(context)
|
||||
# Adds a project stylesheet
|
||||
stylesheet_link_tag(context[:project].identifier) if context[:project]
|
||||
end
|
||||
end
|
||||
|
||||
class SidebarContent < Redmine::Hook::ViewListener
|
||||
def view_layouts_base_sidebar(context)
|
||||
content_tag('p', 'Sidebar hook')
|
||||
end
|
||||
end
|
||||
|
||||
Redmine::Hook.clear_listeners
|
||||
|
||||
class ContentForInsideHook < Redmine::Hook::ViewListener
|
||||
render_on :view_welcome_index_left, :inline => <<-VIEW
|
||||
<% content_for :header_tags do %>
|
||||
<%= javascript_include_tag 'test_plugin.js', :plugin => 'test_plugin' %>
|
||||
<%= stylesheet_link_tag 'test_plugin.css', :plugin => 'test_plugin' %>
|
||||
<% end %>
|
||||
|
||||
<p>ContentForInsideHook content</p>
|
||||
VIEW
|
||||
end
|
||||
|
||||
class SingleRenderOn < Redmine::Hook::ViewListener
|
||||
render_on :view_welcome_index_left, :inline => 'SingleRenderOn 1'
|
||||
end
|
||||
|
||||
class MultipleRenderOn < Redmine::Hook::ViewListener
|
||||
render_on :view_welcome_index_left, {:inline => 'MultipleRenderOn 1'}, {:inline => 'MultipleRenderOn 2'}
|
||||
end
|
||||
|
||||
# Hooks that stores the call context
|
||||
class ContextTestHook < Redmine::Hook::ViewListener
|
||||
cattr_accessor :context
|
||||
|
||||
def controller_account_success_authentication_after(context)
|
||||
self.class.context = context
|
||||
end
|
||||
end
|
||||
|
||||
def setup
|
||||
Redmine::Hook.clear_listeners
|
||||
end
|
||||
|
||||
def teardown
|
||||
Redmine::Hook.clear_listeners
|
||||
end
|
||||
|
||||
def test_html_head_hook_response
|
||||
Redmine::Hook.add_listener(ProjectBasedTemplate)
|
||||
|
||||
get '/projects/ecookbook'
|
||||
assert_select 'head link[href=?]', '/stylesheets/ecookbook.css'
|
||||
end
|
||||
|
||||
def test_empty_sidebar_should_be_hidden
|
||||
get '/'
|
||||
assert_select 'div#main.nosidebar'
|
||||
end
|
||||
|
||||
def test_sidebar_with_hook_content_should_not_be_hidden
|
||||
Redmine::Hook.add_listener(SidebarContent)
|
||||
|
||||
get '/'
|
||||
assert_select 'div#sidebar p', :text => 'Sidebar hook'
|
||||
assert_select 'div#main'
|
||||
assert_select 'div#main.nosidebar', 0
|
||||
end
|
||||
|
||||
def test_hook_with_content_for_should_append_content
|
||||
Redmine::Hook.add_listener(ContentForInsideHook)
|
||||
|
||||
get '/'
|
||||
assert_response :success
|
||||
assert_select 'p', :text => 'ContentForInsideHook content'
|
||||
assert_select 'head' do
|
||||
assert_select 'script[src="/plugin_assets/test_plugin/javascripts/test_plugin.js"]'
|
||||
assert_select 'link[href="/plugin_assets/test_plugin/stylesheets/test_plugin.css"]'
|
||||
end
|
||||
end
|
||||
|
||||
def test_controller_hook_context_should_include_request
|
||||
Redmine::Hook.add_listener(ContextTestHook)
|
||||
post '/login', :params => {:username => 'admin', :password => 'admin'}
|
||||
assert_not_nil ContextTestHook.context
|
||||
context = ContextTestHook.context
|
||||
assert_kind_of ActionDispatch::Request, context[:request]
|
||||
assert_kind_of Hash, context[:request].params
|
||||
assert_kind_of AccountController, context[:hook_caller]
|
||||
end
|
||||
|
||||
def test_multiple_hooks
|
||||
Redmine::Hook.add_listener(SingleRenderOn)
|
||||
Redmine::Hook.add_listener(MultipleRenderOn)
|
||||
get '/'
|
||||
assert_equal 1, response.body.scan("SingleRenderOn 1 MultipleRenderOn 1 MultipleRenderOn 2").size
|
||||
end
|
||||
end
|
80
test/integration/lib/redmine/menu_manager_test.rb
Normal file
80
test/integration/lib/redmine/menu_manager_test.rb
Normal file
|
@ -0,0 +1,80 @@
|
|||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2017 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 MenuManagerTest < Redmine::IntegrationTest
|
||||
include Redmine::I18n
|
||||
|
||||
fixtures :projects, :trackers, :issue_statuses, :issues,
|
||||
:enumerations, :users, :issue_categories,
|
||||
:projects_trackers,
|
||||
:roles,
|
||||
:member_roles,
|
||||
:members,
|
||||
:enabled_modules
|
||||
|
||||
def test_project_menu_with_specific_locale
|
||||
get '/projects/ecookbook/issues',
|
||||
:headers => {'HTTP_ACCEPT_LANGUAGE' => 'fr,fr-fr;q=0.8,en-us;q=0.5,en;q=0.3'}
|
||||
|
||||
assert_select 'div#main-menu' do
|
||||
assert_select 'li a.activity[href=?]', '/projects/ecookbook/activity', :text => ll('fr', :label_activity)
|
||||
assert_select 'li a.issues.selected[href=?]', '/projects/ecookbook/issues', :text => ll('fr', :label_issue_plural)
|
||||
end
|
||||
end
|
||||
|
||||
def test_project_menu_with_additional_menu_items
|
||||
Setting.default_language = 'en'
|
||||
assert_no_difference 'Redmine::MenuManager.items(:project_menu).size' do
|
||||
Redmine::MenuManager.map :project_menu do |menu|
|
||||
menu.push :foo, { :controller => 'projects', :action => 'show' }, :caption => 'Foo'
|
||||
menu.push :bar, { :controller => 'projects', :action => 'show' }, :before => :activity
|
||||
menu.push :hello, { :controller => 'projects', :action => 'show' }, :caption => Proc.new {|p| p.name.upcase }, :after => :bar
|
||||
end
|
||||
|
||||
get '/projects/ecookbook'
|
||||
|
||||
assert_select 'div#main-menu ul' do
|
||||
assert_select 'li:last-child a.foo[href=?]', '/projects/ecookbook', :text => 'Foo'
|
||||
assert_select 'li:nth-child(2) a.bar[href=?]', '/projects/ecookbook', :text => 'Bar'
|
||||
assert_select 'li:nth-child(3) a.hello[href=?]', '/projects/ecookbook', :text => 'ECOOKBOOK'
|
||||
assert_select 'li:nth-child(4) a', :text => 'Activity'
|
||||
end
|
||||
|
||||
# Remove the menu items
|
||||
Redmine::MenuManager.map :project_menu do |menu|
|
||||
menu.delete :foo
|
||||
menu.delete :bar
|
||||
menu.delete :hello
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def test_main_menu_should_select_projects_tab_on_project_list
|
||||
get '/projects'
|
||||
assert_select '#main-menu' do
|
||||
assert_select 'a.projects'
|
||||
assert_select 'a.projects.selected'
|
||||
end
|
||||
end
|
||||
|
||||
def test_main_menu_should_not_show_up_on_account
|
||||
get '/login'
|
||||
assert_select '#main-menu', 0
|
||||
end
|
||||
end
|
102
test/integration/lib/redmine/themes_test.rb
Normal file
102
test/integration/lib/redmine/themes_test.rb
Normal file
|
@ -0,0 +1,102 @@
|
|||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2017 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 ThemesTest < Redmine::IntegrationTest
|
||||
|
||||
def setup
|
||||
Redmine::Themes.rescan
|
||||
@theme = Redmine::Themes.themes.last
|
||||
Setting.ui_theme = @theme.id
|
||||
end
|
||||
|
||||
def teardown
|
||||
Setting.ui_theme = ''
|
||||
end
|
||||
|
||||
def test_application_css
|
||||
get '/'
|
||||
|
||||
assert_response :success
|
||||
assert_select "link[rel=stylesheet][href^=?]", "/themes/#{@theme.dir}/stylesheets/application.css"
|
||||
end
|
||||
|
||||
def test_without_theme_js
|
||||
# simulate a state theme.js does not exists
|
||||
@theme.javascripts.clear
|
||||
get '/'
|
||||
|
||||
assert_response :success
|
||||
assert_select "script[src^=?]", "/themes/#{@theme.dir}/javascripts/theme.js", 0
|
||||
end
|
||||
|
||||
def test_with_theme_js
|
||||
# Simulates a theme.js
|
||||
@theme.javascripts << 'theme'
|
||||
get '/'
|
||||
|
||||
assert_response :success
|
||||
assert_select "script[src^=?]", "/themes/#{@theme.dir}/javascripts/theme.js", 1
|
||||
ensure
|
||||
@theme.javascripts.delete 'theme'
|
||||
end
|
||||
|
||||
def test_use_default_favicon_if_theme_provides_none
|
||||
get '/'
|
||||
|
||||
assert_response :success
|
||||
assert_select 'link[rel="shortcut icon"][href^="/favicon.ico"]'
|
||||
end
|
||||
|
||||
def test_use_theme_favicon_if_theme_provides_one
|
||||
# Simulate a theme favicon
|
||||
@theme.favicons << 'a.ico'
|
||||
get '/'
|
||||
|
||||
assert_response :success
|
||||
assert_select 'link[rel="shortcut icon"][href^=?]', "/themes/#{@theme.dir}/favicon/a.ico"
|
||||
ensure
|
||||
@theme.favicons.delete 'a.ico'
|
||||
end
|
||||
|
||||
def test_use_only_one_theme_favicon_if_theme_provides_many
|
||||
@theme.favicons.concat %w{b.ico a.png}
|
||||
get '/'
|
||||
|
||||
assert_response :success
|
||||
assert_select 'link[rel="shortcut icon"]', 1
|
||||
assert_select 'link[rel="shortcut icon"][href^=?]', "/themes/#{@theme.dir}/favicon/b.ico"
|
||||
ensure
|
||||
@theme.favicons.delete("b.ico")
|
||||
@theme.favicons.delete("a.png")
|
||||
end
|
||||
|
||||
def test_with_sub_uri
|
||||
Redmine::Utils.relative_url_root = '/foo'
|
||||
@theme.javascripts << 'theme'
|
||||
@theme.favicons << 'a.ico'
|
||||
get '/'
|
||||
|
||||
assert_response :success
|
||||
assert_select "link[rel=stylesheet][href^=?]", "/foo/themes/#{@theme.dir}/stylesheets/application.css"
|
||||
assert_select "script[src^=?]", "/foo/themes/#{@theme.dir}/javascripts/theme.js"
|
||||
assert_select 'link[rel="shortcut icon"][href^=?]', "/foo/themes/#{@theme.dir}/favicon/a.ico"
|
||||
ensure
|
||||
Redmine::Utils.relative_url_root = ''
|
||||
end
|
||||
end
|
53
test/integration/projects_test.rb
Normal file
53
test/integration/projects_test.rb
Normal file
|
@ -0,0 +1,53 @@
|
|||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2017 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 ProjectsTest < Redmine::IntegrationTest
|
||||
fixtures :projects, :users, :members, :enabled_modules
|
||||
|
||||
def test_archive_project
|
||||
subproject = Project.find(1).children.first
|
||||
log_user("admin", "admin")
|
||||
get "/admin/projects"
|
||||
assert_response :success
|
||||
|
||||
post "/projects/1/archive"
|
||||
assert_redirected_to "/admin/projects"
|
||||
assert !Project.find(1).active?
|
||||
|
||||
get '/projects/1'
|
||||
assert_response 403
|
||||
get "/projects/#{subproject.id}"
|
||||
assert_response 403
|
||||
|
||||
post "/projects/1/unarchive"
|
||||
assert_redirected_to "/admin/projects"
|
||||
assert Project.find(1).active?
|
||||
get "/projects/1"
|
||||
assert_response :success
|
||||
end
|
||||
|
||||
def test_modules_should_not_allow_get
|
||||
log_user("admin", "admin")
|
||||
|
||||
assert_no_difference 'EnabledModule.count' do
|
||||
get '/projects/1/modules', :params => {:enabled_module_names => ['']}
|
||||
assert_response 404
|
||||
end
|
||||
end
|
||||
end
|
50
test/integration/repositories_git_test.rb
Normal file
50
test/integration/repositories_git_test.rb
Normal file
|
@ -0,0 +1,50 @@
|
|||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2017 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 RepositoriesGitTest < Redmine::IntegrationTest
|
||||
fixtures :projects, :users, :roles, :members, :member_roles,
|
||||
:repositories, :enabled_modules
|
||||
|
||||
REPOSITORY_PATH = Rails.root.join('tmp/test/git_repository').to_s
|
||||
REPOSITORY_PATH.gsub!(/\//, "\\") if Redmine::Platform.mswin?
|
||||
PRJ_ID = 3
|
||||
|
||||
def setup
|
||||
User.current = nil
|
||||
@project = Project.find(PRJ_ID)
|
||||
@repository = Repository::Git.create(
|
||||
:project => @project,
|
||||
:url => REPOSITORY_PATH,
|
||||
:path_encoding => 'ISO-8859-1'
|
||||
)
|
||||
assert @repository
|
||||
end
|
||||
|
||||
if File.directory?(REPOSITORY_PATH)
|
||||
def test_index
|
||||
get '/projects/subproject1/repository/'
|
||||
assert_response :success
|
||||
end
|
||||
|
||||
def test_diff_two_revs
|
||||
get '/projects/subproject1/repository/diff?rev=61b685fbe&rev_to=2f9c0091'
|
||||
assert_response :success
|
||||
end
|
||||
end
|
||||
end
|
36
test/integration/routing/account_test.rb
Normal file
36
test/integration/routing/account_test.rb
Normal file
|
@ -0,0 +1,36 @@
|
|||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2017 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 RoutingAccountTest < Redmine::RoutingTest
|
||||
def test_account
|
||||
should_route 'GET /login' => 'account#login'
|
||||
should_route 'POST /login' => 'account#login'
|
||||
|
||||
should_route 'GET /logout' => 'account#logout'
|
||||
should_route 'POST /logout' => 'account#logout'
|
||||
|
||||
should_route 'GET /account/register' => 'account#register'
|
||||
should_route 'POST /account/register' => 'account#register'
|
||||
|
||||
should_route 'GET /account/lost_password' => 'account#lost_password'
|
||||
should_route 'POST /account/lost_password' => 'account#lost_password'
|
||||
|
||||
should_route 'GET /account/activate' => 'account#activate'
|
||||
end
|
||||
end
|
31
test/integration/routing/activities_test.rb
Normal file
31
test/integration/routing/activities_test.rb
Normal file
|
@ -0,0 +1,31 @@
|
|||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2017 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 RoutingActivitiesTest < Redmine::RoutingTest
|
||||
|
||||
def test_activity
|
||||
should_route 'GET /activity' => 'activities#index'
|
||||
should_route 'GET /activity.atom' => 'activities#index', :format => 'atom'
|
||||
end
|
||||
|
||||
def test_project_activity
|
||||
should_route 'GET /projects/33/activity' => 'activities#index', :id => '33'
|
||||
should_route 'GET /projects/33/activity.atom' => 'activities#index', :id => '33', :format => 'atom'
|
||||
end
|
||||
end
|
29
test/integration/routing/admin_test.rb
Normal file
29
test/integration/routing/admin_test.rb
Normal file
|
@ -0,0 +1,29 @@
|
|||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2017 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 RoutingAdminTest < Redmine::RoutingTest
|
||||
def test_administration_panel
|
||||
should_route 'GET /admin' => 'admin#index'
|
||||
should_route 'GET /admin/projects' => 'admin#projects'
|
||||
should_route 'GET /admin/plugins' => 'admin#plugins'
|
||||
should_route 'GET /admin/info' => 'admin#info'
|
||||
should_route 'POST /admin/test_email' => 'admin#test_email'
|
||||
should_route 'POST /admin/default_configuration' => 'admin#default_configuration'
|
||||
end
|
||||
end
|
36
test/integration/routing/attachments_test.rb
Normal file
36
test/integration/routing/attachments_test.rb
Normal file
|
@ -0,0 +1,36 @@
|
|||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2017 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 RoutingAttachmentsTest < Redmine::RoutingTest
|
||||
def test_attachments
|
||||
should_route 'GET /attachments/1' => 'attachments#show', :id => '1'
|
||||
should_route 'GET /attachments/1/filename.ext' => 'attachments#show', :id => '1', :filename => 'filename.ext'
|
||||
|
||||
should_route 'GET /attachments/download/1' => 'attachments#download', :id => '1'
|
||||
should_route 'GET /attachments/download/1/filename.ext' => 'attachments#download', :id => '1', :filename => 'filename.ext'
|
||||
|
||||
should_route 'GET /attachments/thumbnail/1' => 'attachments#thumbnail', :id => '1'
|
||||
should_route 'GET /attachments/thumbnail/1/200' => 'attachments#thumbnail', :id => '1', :size => '200'
|
||||
|
||||
should_route 'DELETE /attachments/1' => 'attachments#destroy', :id => '1'
|
||||
|
||||
should_route 'GET /attachments/issues/1/edit' => 'attachments#edit_all', :object_type => 'issues', :object_id => '1'
|
||||
should_route 'PATCH /attachments/issues/1' => 'attachments#update_all', :object_type => 'issues', :object_id => '1'
|
||||
end
|
||||
end
|
32
test/integration/routing/auth_sources_test.rb
Normal file
32
test/integration/routing/auth_sources_test.rb
Normal file
|
@ -0,0 +1,32 @@
|
|||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2017 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 RoutingAuthSourcesTest < Redmine::RoutingTest
|
||||
def test_auth_sources
|
||||
should_route 'GET /auth_sources' => 'auth_sources#index'
|
||||
should_route 'GET /auth_sources/new' => 'auth_sources#new'
|
||||
should_route 'POST /auth_sources' => 'auth_sources#create'
|
||||
should_route 'GET /auth_sources/autocomplete_for_new_user' => 'auth_sources#autocomplete_for_new_user'
|
||||
|
||||
should_route 'GET /auth_sources/1234/edit' => 'auth_sources#edit', :id => '1234'
|
||||
should_route 'PUT /auth_sources/1234' => 'auth_sources#update', :id => '1234'
|
||||
should_route 'DELETE /auth_sources/1234' => 'auth_sources#destroy', :id => '1234'
|
||||
should_route 'GET /auth_sources/1234/test_connection' => 'auth_sources#test_connection', :id => '1234'
|
||||
end
|
||||
end
|
24
test/integration/routing/auto_completes_test.rb
Normal file
24
test/integration/routing/auto_completes_test.rb
Normal file
|
@ -0,0 +1,24 @@
|
|||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2017 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 RoutingAutoCompletesTest < Redmine::RoutingTest
|
||||
def test_auto_completes
|
||||
should_route 'GET /issues/auto_complete' => 'auto_completes#issues'
|
||||
end
|
||||
end
|
32
test/integration/routing/boards_test.rb
Normal file
32
test/integration/routing/boards_test.rb
Normal file
|
@ -0,0 +1,32 @@
|
|||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2017 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 RoutingBoardsTest < Redmine::RoutingTest
|
||||
def test_boards
|
||||
should_route 'GET /projects/foo/boards' => 'boards#index', :project_id => 'foo'
|
||||
should_route 'GET /projects/foo/boards/new' => 'boards#new', :project_id => 'foo'
|
||||
should_route 'POST /projects/foo/boards' => 'boards#create', :project_id => 'foo'
|
||||
|
||||
should_route 'GET /projects/foo/boards/44' => 'boards#show', :project_id => 'foo', :id => '44'
|
||||
should_route 'GET /projects/foo/boards/44.atom' => 'boards#show', :project_id => 'foo', :id => '44', :format => 'atom'
|
||||
should_route 'GET /projects/foo/boards/44/edit' => 'boards#edit', :project_id => 'foo', :id => '44'
|
||||
should_route 'PUT /projects/foo/boards/44' => 'boards#update', :project_id => 'foo', :id => '44'
|
||||
should_route 'DELETE /projects/foo/boards/44' => 'boards#destroy', :project_id => 'foo', :id => '44'
|
||||
end
|
||||
end
|
25
test/integration/routing/calendars_test.rb
Normal file
25
test/integration/routing/calendars_test.rb
Normal file
|
@ -0,0 +1,25 @@
|
|||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2017 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 RoutingCalendarsTest < Redmine::RoutingTest
|
||||
def test_calendars
|
||||
should_route 'GET /issues/calendar' => 'calendars#show'
|
||||
should_route 'GET /projects/foo/issues/calendar' => 'calendars#show', :project_id => 'foo'
|
||||
end
|
||||
end
|
25
test/integration/routing/comments_test.rb
Normal file
25
test/integration/routing/comments_test.rb
Normal file
|
@ -0,0 +1,25 @@
|
|||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2017 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 RoutingCommentsTest < Redmine::RoutingTest
|
||||
def test_comments
|
||||
should_route 'POST /news/567/comments' => 'comments#create', :id => '567'
|
||||
should_route 'DELETE /news/567/comments/15' => 'comments#destroy', :id => '567', :comment_id => '15'
|
||||
end
|
||||
end
|
30
test/integration/routing/context_menus_test.rb
Normal file
30
test/integration/routing/context_menus_test.rb
Normal file
|
@ -0,0 +1,30 @@
|
|||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2017 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 RoutingContextMenusTest < Redmine::RoutingTest
|
||||
def test_context_menus_time_entries
|
||||
should_route 'GET /time_entries/context_menu' => 'context_menus#time_entries'
|
||||
should_route 'POST /time_entries/context_menu' => 'context_menus#time_entries'
|
||||
end
|
||||
|
||||
def test_context_menus_issues
|
||||
should_route 'GET /issues/context_menu' => 'context_menus#issues'
|
||||
should_route 'POST /issues/context_menu' => 'context_menus#issues'
|
||||
end
|
||||
end
|
37
test/integration/routing/custom_fields_test.rb
Normal file
37
test/integration/routing/custom_fields_test.rb
Normal file
|
@ -0,0 +1,37 @@
|
|||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2017 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 RoutingCustomFieldsTest < Redmine::RoutingTest
|
||||
def test_custom_fields
|
||||
should_route 'GET /custom_fields' => 'custom_fields#index'
|
||||
should_route 'GET /custom_fields/new' => 'custom_fields#new'
|
||||
should_route 'POST /custom_fields' => 'custom_fields#create'
|
||||
|
||||
should_route 'GET /custom_fields/2/edit' => 'custom_fields#edit', :id => '2'
|
||||
should_route 'PUT /custom_fields/2' => 'custom_fields#update', :id => '2'
|
||||
should_route 'DELETE /custom_fields/2' => 'custom_fields#destroy', :id => '2'
|
||||
end
|
||||
|
||||
def test_custom_field_enumerations
|
||||
should_route 'GET /custom_fields/3/enumerations' => 'custom_field_enumerations#index', :custom_field_id => '3'
|
||||
should_route 'POST /custom_fields/3/enumerations' => 'custom_field_enumerations#create', :custom_field_id => '3'
|
||||
should_route 'PUT /custom_fields/3/enumerations' => 'custom_field_enumerations#update_each', :custom_field_id => '3'
|
||||
should_route 'DELETE /custom_fields/3/enumerations/6' => 'custom_field_enumerations#destroy', :custom_field_id => '3', :id => '6'
|
||||
end
|
||||
end
|
37
test/integration/routing/documents_test.rb
Normal file
37
test/integration/routing/documents_test.rb
Normal file
|
@ -0,0 +1,37 @@
|
|||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2017 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 RoutingDocumentsTest < Redmine::RoutingTest
|
||||
def test_documents_scoped_under_project
|
||||
should_route 'GET /projects/567/documents' => 'documents#index', :project_id => '567'
|
||||
should_route 'GET /projects/567/documents/new' => 'documents#new', :project_id => '567'
|
||||
should_route 'POST /projects/567/documents' => 'documents#create', :project_id => '567'
|
||||
end
|
||||
|
||||
def test_documents
|
||||
should_route 'GET /documents/22' => 'documents#show', :id => '22'
|
||||
should_route 'GET /documents/22/edit' => 'documents#edit', :id => '22'
|
||||
should_route 'PUT /documents/22' => 'documents#update', :id => '22'
|
||||
should_route 'DELETE /documents/22' => 'documents#destroy', :id => '22'
|
||||
end
|
||||
|
||||
def test_document_attachments
|
||||
should_route 'POST /documents/22/add_attachment' => 'documents#add_attachment', :id => '22'
|
||||
end
|
||||
end
|
30
test/integration/routing/enumerations_test.rb
Normal file
30
test/integration/routing/enumerations_test.rb
Normal file
|
@ -0,0 +1,30 @@
|
|||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2017 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 RoutingEnumerationsTest < Redmine::RoutingTest
|
||||
def test_enumerations
|
||||
should_route 'GET /enumerations' => 'enumerations#index'
|
||||
should_route 'GET /enumerations/new' => 'enumerations#new'
|
||||
should_route 'POST /enumerations' => 'enumerations#create'
|
||||
|
||||
should_route 'GET /enumerations/2/edit' => 'enumerations#edit', :id => '2'
|
||||
should_route 'PUT /enumerations/2' => 'enumerations#update', :id => '2'
|
||||
should_route 'DELETE /enumerations/2' => 'enumerations#destroy', :id => '2'
|
||||
end
|
||||
end
|
26
test/integration/routing/files_test.rb
Normal file
26
test/integration/routing/files_test.rb
Normal file
|
@ -0,0 +1,26 @@
|
|||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2017 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 RoutingFilesTest < Redmine::RoutingTest
|
||||
def test_files
|
||||
should_route 'GET /projects/foo/files' => 'files#index', :project_id => 'foo'
|
||||
should_route 'GET /projects/foo/files/new' => 'files#new', :project_id => 'foo'
|
||||
should_route 'POST /projects/foo/files' => 'files#create', :project_id => 'foo'
|
||||
end
|
||||
end
|
28
test/integration/routing/gantts_test.rb
Normal file
28
test/integration/routing/gantts_test.rb
Normal file
|
@ -0,0 +1,28 @@
|
|||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2017 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 RoutingGanttsTest < Redmine::RoutingTest
|
||||
def test_gantts
|
||||
should_route 'GET /issues/gantt' => 'gantts#show'
|
||||
should_route 'GET /issues/gantt.pdf' => 'gantts#show', :format => 'pdf'
|
||||
|
||||
should_route 'GET /projects/foo/issues/gantt' => 'gantts#show', :project_id => 'foo'
|
||||
should_route 'GET /projects/foo/issues/gantt.pdf' => 'gantts#show', :project_id => 'foo', :format => 'pdf'
|
||||
end
|
||||
end
|
40
test/integration/routing/groups_test.rb
Normal file
40
test/integration/routing/groups_test.rb
Normal file
|
@ -0,0 +1,40 @@
|
|||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2017 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 RoutingGroupsTest < Redmine::RoutingTest
|
||||
def test_groups
|
||||
should_route 'GET /groups' => 'groups#index'
|
||||
should_route 'GET /groups/new' => 'groups#new'
|
||||
should_route 'POST /groups' => 'groups#create'
|
||||
|
||||
should_route 'GET /groups/1' => 'groups#show', :id => '1'
|
||||
should_route 'GET /groups/1/edit' => 'groups#edit', :id => '1'
|
||||
should_route 'PUT /groups/1' => 'groups#update', :id => '1'
|
||||
should_route 'DELETE /groups/1' => 'groups#destroy', :id => '1'
|
||||
|
||||
should_route 'GET /groups/1/autocomplete_for_user' => 'groups#autocomplete_for_user', :id => '1'
|
||||
should_route 'GET /groups/1/autocomplete_for_user.js' => 'groups#autocomplete_for_user', :id => '1', :format => 'js'
|
||||
end
|
||||
|
||||
def test_group_users
|
||||
should_route 'GET /groups/567/users/new' => 'groups#new_users', :id => '567'
|
||||
should_route 'POST /groups/567/users' => 'groups#add_users', :id => '567'
|
||||
should_route 'DELETE /groups/567/users/12' => 'groups#remove_user', :id => '567', :user_id => '12'
|
||||
end
|
||||
end
|
36
test/integration/routing/imports_test.rb
Normal file
36
test/integration/routing/imports_test.rb
Normal file
|
@ -0,0 +1,36 @@
|
|||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2017 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 RoutingImportsTest < Redmine::RoutingTest
|
||||
def test_imports
|
||||
should_route 'GET /issues/imports/new' => 'imports#new'
|
||||
should_route 'POST /imports' => 'imports#create'
|
||||
|
||||
should_route 'GET /imports/4ae6bc' => 'imports#show', :id => '4ae6bc'
|
||||
|
||||
should_route 'GET /imports/4ae6bc/settings' => 'imports#settings', :id => '4ae6bc'
|
||||
should_route 'POST /imports/4ae6bc/settings' => 'imports#settings', :id => '4ae6bc'
|
||||
|
||||
should_route 'GET /imports/4ae6bc/mapping' => 'imports#mapping', :id => '4ae6bc'
|
||||
should_route 'POST /imports/4ae6bc/mapping' => 'imports#mapping', :id => '4ae6bc'
|
||||
|
||||
should_route 'GET /imports/4ae6bc/run' => 'imports#run', :id => '4ae6bc'
|
||||
should_route 'POST /imports/4ae6bc/run' => 'imports#run', :id => '4ae6bc'
|
||||
end
|
||||
end
|
32
test/integration/routing/issue_categories_test.rb
Normal file
32
test/integration/routing/issue_categories_test.rb
Normal file
|
@ -0,0 +1,32 @@
|
|||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2017 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 RoutingIssueCategoriesTest < Redmine::RoutingTest
|
||||
def test_issue_categories_scoped_under_project
|
||||
should_route 'GET /projects/foo/issue_categories' => 'issue_categories#index', :project_id => 'foo'
|
||||
should_route 'GET /projects/foo/issue_categories/new' => 'issue_categories#new', :project_id => 'foo'
|
||||
should_route 'POST /projects/foo/issue_categories' => 'issue_categories#create', :project_id => 'foo'
|
||||
end
|
||||
|
||||
def test_issue_categories
|
||||
should_route 'GET /issue_categories/1/edit' => 'issue_categories#edit', :id => '1'
|
||||
should_route 'PUT /issue_categories/1' => 'issue_categories#update', :id => '1'
|
||||
should_route 'DELETE /issue_categories/1' => 'issue_categories#destroy', :id => '1'
|
||||
end
|
||||
end
|
27
test/integration/routing/issue_relations_test.rb
Normal file
27
test/integration/routing/issue_relations_test.rb
Normal file
|
@ -0,0 +1,27 @@
|
|||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2017 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 RoutingIssueRelationsTest < Redmine::RoutingTest
|
||||
def test_issue_relations
|
||||
should_route 'GET /issues/1/relations' => 'issue_relations#index', :issue_id => '1'
|
||||
should_route 'POST /issues/1/relations' => 'issue_relations#create', :issue_id => '1'
|
||||
|
||||
should_route 'DELETE /relations/23' => 'issue_relations#destroy', :id => '23'
|
||||
end
|
||||
end
|
32
test/integration/routing/issue_statuses_test.rb
Normal file
32
test/integration/routing/issue_statuses_test.rb
Normal file
|
@ -0,0 +1,32 @@
|
|||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2017 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 RoutingIssueStatusesTest < Redmine::RoutingTest
|
||||
def test_issue_statuses
|
||||
should_route 'GET /issue_statuses' => 'issue_statuses#index'
|
||||
should_route 'POST /issue_statuses' => 'issue_statuses#create'
|
||||
should_route 'GET /issue_statuses/new' => 'issue_statuses#new'
|
||||
|
||||
should_route 'GET /issue_statuses/1/edit' => 'issue_statuses#edit', :id => '1'
|
||||
should_route 'PUT /issue_statuses/1' => 'issue_statuses#update', :id => '1'
|
||||
should_route 'DELETE /issue_statuses/1' => 'issue_statuses#destroy', :id => '1'
|
||||
|
||||
should_route 'POST /issue_statuses/update_issue_done_ratio' => 'issue_statuses#update_issue_done_ratio'
|
||||
end
|
||||
end
|
60
test/integration/routing/issues_test.rb
Normal file
60
test/integration/routing/issues_test.rb
Normal file
|
@ -0,0 +1,60 @@
|
|||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2017 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 RoutingIssuesTest < Redmine::RoutingTest
|
||||
def test_issues
|
||||
should_route 'GET /issues' => 'issues#index'
|
||||
should_route 'GET /issues.pdf' => 'issues#index', :format => 'pdf'
|
||||
should_route 'GET /issues.atom' => 'issues#index', :format => 'atom'
|
||||
|
||||
should_route 'GET /issues/64' => 'issues#show', :id => '64'
|
||||
should_route 'GET /issues/64.pdf' => 'issues#show', :id => '64', :format => 'pdf'
|
||||
should_route 'GET /issues/64.atom' => 'issues#show', :id => '64', :format => 'atom'
|
||||
|
||||
should_route 'GET /issues/new' => 'issues#new'
|
||||
should_route 'POST /issues' => 'issues#create'
|
||||
|
||||
should_route 'GET /issues/64/edit' => 'issues#edit', :id => '64'
|
||||
should_route 'PUT /issues/64' => 'issues#update', :id => '64'
|
||||
should_route 'DELETE /issues/64' => 'issues#destroy', :id => '64'
|
||||
end
|
||||
|
||||
def test_issues_bulk_edit
|
||||
should_route 'GET /issues/bulk_edit' => 'issues#bulk_edit'
|
||||
should_route 'POST /issues/bulk_edit' => 'issues#bulk_edit' # For updating the bulk edit form
|
||||
should_route 'POST /issues/bulk_update' => 'issues#bulk_update'
|
||||
end
|
||||
|
||||
def test_issues_scoped_under_project
|
||||
should_route 'GET /projects/23/issues' => 'issues#index', :project_id => '23'
|
||||
should_route 'GET /projects/23/issues.pdf' => 'issues#index', :project_id => '23', :format => 'pdf'
|
||||
should_route 'GET /projects/23/issues.atom' => 'issues#index', :project_id => '23', :format => 'atom'
|
||||
|
||||
should_route 'GET /projects/23/issues/new' => 'issues#new', :project_id => '23'
|
||||
should_route 'POST /projects/23/issues' => 'issues#create', :project_id => '23'
|
||||
|
||||
should_route 'GET /projects/23/issues/64/copy' => 'issues#new', :project_id => '23', :copy_from => '64'
|
||||
end
|
||||
|
||||
def test_issues_form_update
|
||||
should_route 'POST /issues/new' => 'issues#new'
|
||||
should_route 'POST /projects/23/issues/new' => 'issues#new', :project_id => '23'
|
||||
should_route 'PATCH /issues/23/edit' => 'issues#edit', :id => '23'
|
||||
end
|
||||
end
|
29
test/integration/routing/journals_test.rb
Normal file
29
test/integration/routing/journals_test.rb
Normal file
|
@ -0,0 +1,29 @@
|
|||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2017 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 RoutingJournalsTest < Redmine::RoutingTest
|
||||
def test_journals
|
||||
should_route 'POST /issues/1/quoted' => 'journals#new', :id => '1'
|
||||
should_route 'GET /issues/changes' => 'journals#index'
|
||||
should_route 'GET /journals/1/diff' => 'journals#diff', :id => '1'
|
||||
|
||||
should_route 'GET /journals/1/edit' => 'journals#edit', :id => '1'
|
||||
should_route 'PUT /journals/1' => 'journals#update', :id => '1'
|
||||
end
|
||||
end
|
25
test/integration/routing/mail_handler_test.rb
Normal file
25
test/integration/routing/mail_handler_test.rb
Normal file
|
@ -0,0 +1,25 @@
|
|||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2017 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 RoutingMailHandlerTest < Redmine::RoutingTest
|
||||
def test_mail_handler
|
||||
should_route 'GET /mail_handler' => 'mail_handler#new'
|
||||
should_route 'POST /mail_handler' => 'mail_handler#index'
|
||||
end
|
||||
end
|
32
test/integration/routing/members_test.rb
Normal file
32
test/integration/routing/members_test.rb
Normal file
|
@ -0,0 +1,32 @@
|
|||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2017 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 RoutingMembersTest < Redmine::RoutingTest
|
||||
def test_members
|
||||
should_route 'GET /projects/foo/memberships/new' => 'members#new', :project_id => 'foo'
|
||||
should_route 'POST /projects/foo/memberships' => 'members#create', :project_id => 'foo'
|
||||
|
||||
should_route 'GET /memberships/5234/edit' => 'members#edit', :id => '5234'
|
||||
should_route 'PUT /memberships/5234' => 'members#update', :id => '5234'
|
||||
should_route 'DELETE /memberships/5234' => 'members#destroy', :id => '5234'
|
||||
|
||||
should_route 'GET /projects/foo/memberships/autocomplete' => 'members#autocomplete', :project_id => 'foo'
|
||||
should_route 'GET /projects/foo/memberships/autocomplete.js' => 'members#autocomplete', :project_id => 'foo', :format => 'js'
|
||||
end
|
||||
end
|
33
test/integration/routing/messages_test.rb
Normal file
33
test/integration/routing/messages_test.rb
Normal file
|
@ -0,0 +1,33 @@
|
|||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2017 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 RoutingMessagesTest < Redmine::RoutingTest
|
||||
def test_messages
|
||||
# TODO: refactor routes
|
||||
should_route 'GET /boards/22/topics/new' => 'messages#new', :board_id => '22'
|
||||
should_route 'POST /boards/22/topics/new' => 'messages#new', :board_id => '22'
|
||||
should_route 'POST /boards/22/topics/preview' => 'messages#preview', :board_id => '22'
|
||||
|
||||
should_route 'GET /boards/22/topics/2' => 'messages#show', :id => '2', :board_id => '22'
|
||||
should_route 'GET /boards/22/topics/2/edit' => 'messages#edit', :id => '2', :board_id => '22'
|
||||
should_route 'POST /boards/22/topics/quote/2' => 'messages#quote', :id => '2', :board_id => '22'
|
||||
should_route 'POST /boards/22/topics/2/replies' => 'messages#reply', :id => '2', :board_id => '22'
|
||||
should_route 'POST /boards/22/topics/2/destroy' => 'messages#destroy', :id => '2', :board_id => '22'
|
||||
end
|
||||
end
|
43
test/integration/routing/my_test.rb
Normal file
43
test/integration/routing/my_test.rb
Normal file
|
@ -0,0 +1,43 @@
|
|||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2017 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 RoutingMyTest < Redmine::RoutingTest
|
||||
def test_my
|
||||
should_route 'GET /my/account' => 'my#account'
|
||||
should_route 'POST /my/account' => 'my#account'
|
||||
|
||||
should_route 'GET /my/account/destroy' => 'my#destroy'
|
||||
should_route 'POST /my/account/destroy' => 'my#destroy'
|
||||
|
||||
should_route 'GET /my/page' => 'my#page'
|
||||
should_route 'POST /my/page' => 'my#update_page'
|
||||
should_route 'GET /my' => 'my#index'
|
||||
|
||||
should_route 'GET /my/api_key' => 'my#show_api_key'
|
||||
should_route 'POST /my/api_key' => 'my#reset_api_key'
|
||||
should_route 'POST /my/rss_key' => 'my#reset_rss_key'
|
||||
|
||||
should_route 'GET /my/password' => 'my#password'
|
||||
should_route 'POST /my/password' => 'my#password'
|
||||
|
||||
should_route 'POST /my/add_block' => 'my#add_block'
|
||||
should_route 'POST /my/remove_block' => 'my#remove_block'
|
||||
should_route 'POST /my/order_blocks' => 'my#order_blocks'
|
||||
end
|
||||
end
|
36
test/integration/routing/news_test.rb
Normal file
36
test/integration/routing/news_test.rb
Normal file
|
@ -0,0 +1,36 @@
|
|||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2017 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 RoutingNewsTest < Redmine::RoutingTest
|
||||
def test_news_scoped_under_project
|
||||
should_route 'GET /projects/foo/news' => 'news#index', :project_id => 'foo'
|
||||
should_route 'GET /projects/foo/news.atom' => 'news#index', :project_id => 'foo', :format => 'atom'
|
||||
should_route 'GET /projects/foo/news/new' => 'news#new', :project_id => 'foo'
|
||||
should_route 'POST /projects/foo/news' => 'news#create', :project_id => 'foo'
|
||||
end
|
||||
|
||||
def test_news
|
||||
should_route 'GET /news' => 'news#index'
|
||||
should_route 'GET /news.atom' => 'news#index', :format => 'atom'
|
||||
should_route 'GET /news/2' => 'news#show', :id => '2'
|
||||
should_route 'GET /news/2/edit' => 'news#edit', :id => '2'
|
||||
should_route 'PUT /news/2' => 'news#update', :id => '2'
|
||||
should_route 'DELETE /news/2' => 'news#destroy', :id => '2'
|
||||
end
|
||||
end
|
32
test/integration/routing/previews_test.rb
Normal file
32
test/integration/routing/previews_test.rb
Normal file
|
@ -0,0 +1,32 @@
|
|||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2017 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 RoutingPreviewsTest < Redmine::RoutingTest
|
||||
def test_previews
|
||||
should_route 'GET /issues/preview/new/foo' => 'previews#issue', :project_id => 'foo'
|
||||
should_route 'PUT /issues/preview/new/foo' => 'previews#issue', :project_id => 'foo'
|
||||
should_route 'POST /issues/preview/new/foo' => 'previews#issue', :project_id => 'foo'
|
||||
|
||||
should_route 'GET /issues/preview/edit/321' => 'previews#issue', :id => '321'
|
||||
should_route 'PUT /issues/preview/edit/321' => 'previews#issue', :id => '321'
|
||||
should_route 'POST /issues/preview/edit/321' => 'previews#issue', :id => '321'
|
||||
|
||||
should_route 'GET /news/preview' => 'previews#news'
|
||||
end
|
||||
end
|
36
test/integration/routing/principal_memberships_test.rb
Normal file
36
test/integration/routing/principal_memberships_test.rb
Normal file
|
@ -0,0 +1,36 @@
|
|||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2017 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 RoutingPrincipalMembershipsTest < Redmine::RoutingTest
|
||||
def test_user_memberships
|
||||
should_route 'GET /users/123/memberships/new' => 'principal_memberships#new', :user_id => '123'
|
||||
should_route 'POST /users/123/memberships' => 'principal_memberships#create', :user_id => '123'
|
||||
should_route 'GET /users/123/memberships/55/edit' => 'principal_memberships#edit', :user_id => '123', :id => '55'
|
||||
should_route 'PUT /users/123/memberships/55' => 'principal_memberships#update', :user_id => '123', :id => '55'
|
||||
should_route 'DELETE /users/123/memberships/55' => 'principal_memberships#destroy', :user_id => '123', :id => '55'
|
||||
end
|
||||
|
||||
def test_group_memberships
|
||||
should_route 'GET /groups/123/memberships/new' => 'principal_memberships#new', :group_id => '123'
|
||||
should_route 'POST /groups/123/memberships' => 'principal_memberships#create', :group_id => '123'
|
||||
should_route 'GET /groups/123/memberships/55/edit' => 'principal_memberships#edit', :group_id => '123', :id => '55'
|
||||
should_route 'PUT /groups/123/memberships/55' => 'principal_memberships#update', :group_id => '123', :id => '55'
|
||||
should_route 'DELETE /groups/123/memberships/55' => 'principal_memberships#destroy', :group_id => '123', :id => '55'
|
||||
end
|
||||
end
|
25
test/integration/routing/project_enumerations_test.rb
Normal file
25
test/integration/routing/project_enumerations_test.rb
Normal file
|
@ -0,0 +1,25 @@
|
|||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2017 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 RoutingProjectEnumerationsTest < Redmine::RoutingTest
|
||||
def test_project_enumerations
|
||||
should_route 'PUT /projects/foo/enumerations' => 'project_enumerations#update', :project_id => 'foo'
|
||||
should_route 'DELETE /projects/foo/enumerations' => 'project_enumerations#destroy', :project_id => 'foo'
|
||||
end
|
||||
end
|
41
test/integration/routing/projects_test.rb
Normal file
41
test/integration/routing/projects_test.rb
Normal file
|
@ -0,0 +1,41 @@
|
|||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2017 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 RoutingProjectsTest < Redmine::RoutingTest
|
||||
def test_projects
|
||||
should_route 'GET /projects' => 'projects#index'
|
||||
should_route 'GET /projects.atom' => 'projects#index', :format => 'atom'
|
||||
should_route 'GET /projects/new' => 'projects#new'
|
||||
should_route 'POST /projects' => 'projects#create'
|
||||
|
||||
should_route 'GET /projects/autocomplete.js' => 'projects#autocomplete', :format => 'js'
|
||||
|
||||
should_route 'GET /projects/foo' => 'projects#show', :id => 'foo'
|
||||
should_route 'PUT /projects/foo' => 'projects#update', :id => 'foo'
|
||||
should_route 'DELETE /projects/foo' => 'projects#destroy', :id => 'foo'
|
||||
|
||||
should_route 'GET /projects/foo/settings' => 'projects#settings', :id => 'foo'
|
||||
should_route 'GET /projects/foo/settings/members' => 'projects#settings', :id => 'foo', :tab => 'members'
|
||||
|
||||
should_route 'POST /projects/foo/archive' => 'projects#archive', :id => 'foo'
|
||||
should_route 'POST /projects/foo/unarchive' => 'projects#unarchive', :id => 'foo'
|
||||
should_route 'POST /projects/foo/close' => 'projects#close', :id => 'foo'
|
||||
should_route 'POST /projects/foo/reopen' => 'projects#reopen', :id => 'foo'
|
||||
end
|
||||
end
|
35
test/integration/routing/queries_test.rb
Normal file
35
test/integration/routing/queries_test.rb
Normal file
|
@ -0,0 +1,35 @@
|
|||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2017 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 RoutingQueriesTest < Redmine::RoutingTest
|
||||
def test_queries
|
||||
should_route 'GET /queries/new' => 'queries#new'
|
||||
should_route 'POST /queries' => 'queries#create'
|
||||
should_route 'GET /queries/filter' => 'queries#filter'
|
||||
|
||||
should_route 'GET /queries/1/edit' => 'queries#edit', :id => '1'
|
||||
should_route 'PUT /queries/1' => 'queries#update', :id => '1'
|
||||
should_route 'DELETE /queries/1' => 'queries#destroy', :id => '1'
|
||||
end
|
||||
|
||||
def test_queries_scoped_under_project
|
||||
should_route 'GET /projects/foo/queries/new' => 'queries#new', :project_id => 'foo'
|
||||
should_route 'POST /projects/foo/queries' => 'queries#create', :project_id => 'foo'
|
||||
end
|
||||
end
|
25
test/integration/routing/reports_test.rb
Normal file
25
test/integration/routing/reports_test.rb
Normal file
|
@ -0,0 +1,25 @@
|
|||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2017 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 RoutingReportsTest < Redmine::RoutingTest
|
||||
def test_reports
|
||||
should_route 'GET /projects/foo/issues/report' => 'reports#issue_report', :id => 'foo'
|
||||
should_route 'GET /projects/foo/issues/report/assigned_to' => 'reports#issue_report_details', :id => 'foo', :detail => 'assigned_to'
|
||||
end
|
||||
end
|
139
test/integration/routing/repositories_test.rb
Normal file
139
test/integration/routing/repositories_test.rb
Normal file
|
@ -0,0 +1,139 @@
|
|||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2017 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 RoutingRepositoriesTest < Redmine::RoutingTest
|
||||
def setup
|
||||
@path_hash = repository_path_hash(%w[path to file.c])
|
||||
assert_equal "path/to/file.c", @path_hash[:path]
|
||||
assert_equal "path/to/file.c", @path_hash[:param]
|
||||
end
|
||||
|
||||
def test_repositories_resources
|
||||
should_route 'GET /projects/foo/repositories/new' => 'repositories#new', :project_id => 'foo'
|
||||
should_route 'POST /projects/foo/repositories' => 'repositories#create', :project_id => 'foo'
|
||||
should_route 'GET /repositories/1/edit' => 'repositories#edit', :id => '1'
|
||||
should_route 'PUT /repositories/1' => 'repositories#update', :id => '1'
|
||||
should_route 'DELETE /repositories/1' => 'repositories#destroy', :id => '1'
|
||||
|
||||
should_route 'GET /repositories/1/committers' => 'repositories#committers', :id => '1'
|
||||
should_route 'POST /repositories/1/committers' => 'repositories#committers', :id => '1'
|
||||
end
|
||||
|
||||
def test_repositories
|
||||
should_route 'GET /projects/foo/repository' => 'repositories#show', :id => 'foo'
|
||||
should_route 'GET /projects/foo/repository/statistics' => 'repositories#stats', :id => 'foo'
|
||||
should_route 'GET /projects/foo/repository/graph' => 'repositories#graph', :id => 'foo'
|
||||
end
|
||||
|
||||
def test_repositories_with_repository_id
|
||||
should_route 'GET /projects/foo/repository/svn' => 'repositories#show', :id => 'foo', :repository_id => 'svn'
|
||||
should_route 'GET /projects/foo/repository/svn/statistics' => 'repositories#stats', :id => 'foo', :repository_id => 'svn'
|
||||
should_route 'GET /projects/foo/repository/svn/graph' => 'repositories#graph', :id => 'foo', :repository_id => 'svn'
|
||||
end
|
||||
|
||||
def test_repositories_revisions
|
||||
should_route 'GET /projects/foo/repository/revision' => 'repositories#revision', :id => 'foo'
|
||||
should_route 'GET /projects/foo/repository/revisions' => 'repositories#revisions', :id => 'foo'
|
||||
should_route 'GET /projects/foo/repository/revisions.atom' => 'repositories#revisions', :id => 'foo', :format => 'atom'
|
||||
|
||||
should_route 'GET /projects/foo/repository/revisions/2457' => 'repositories#revision', :id => 'foo', :rev => '2457'
|
||||
should_route 'GET /projects/foo/repository/revisions/2457/show' => 'repositories#show', :id => 'foo', :rev => '2457'
|
||||
should_route 'GET /projects/foo/repository/revisions/2457/diff' => 'repositories#diff', :id => 'foo', :rev => '2457'
|
||||
|
||||
should_route "GET /projects/foo/repository/revisions/2457/show/#{@path_hash[:path]}" => 'repositories#show',
|
||||
:id => 'foo', :rev => '2457', :path => @path_hash[:param]
|
||||
should_route "GET /projects/foo/repository/revisions/2457/diff/#{@path_hash[:path]}" => 'repositories#diff',
|
||||
:id => 'foo', :rev => '2457', :path => @path_hash[:param]
|
||||
should_route "GET /projects/foo/repository/revisions/2457/entry/#{@path_hash[:path]}" => 'repositories#entry',
|
||||
:id => 'foo', :rev => '2457', :path => @path_hash[:param]
|
||||
should_route "GET /projects/foo/repository/revisions/2457/raw/#{@path_hash[:path]}" => 'repositories#raw',
|
||||
:id => 'foo', :rev => '2457', :path => @path_hash[:param]
|
||||
should_route "GET /projects/foo/repository/revisions/2457/annotate/#{@path_hash[:path]}" => 'repositories#annotate',
|
||||
:id => 'foo', :rev => '2457', :path => @path_hash[:param]
|
||||
end
|
||||
|
||||
def test_repositories_revisions_with_repository_id
|
||||
should_route 'GET /projects/foo/repository/foo/revision' => 'repositories#revision', :id => 'foo', :repository_id => 'foo'
|
||||
should_route 'GET /projects/foo/repository/foo/revisions' => 'repositories#revisions', :id => 'foo', :repository_id => 'foo'
|
||||
should_route 'GET /projects/foo/repository/foo/revisions.atom' => 'repositories#revisions', :id => 'foo', :repository_id => 'foo', :format => 'atom'
|
||||
|
||||
should_route 'GET /projects/foo/repository/foo/revisions/2457' => 'repositories#revision', :id => 'foo', :repository_id => 'foo', :rev => '2457'
|
||||
should_route 'GET /projects/foo/repository/foo/revisions/2457/show' => 'repositories#show', :id => 'foo', :repository_id => 'foo', :rev => '2457'
|
||||
should_route 'GET /projects/foo/repository/foo/revisions/2457/diff' => 'repositories#diff', :id => 'foo', :repository_id => 'foo', :rev => '2457'
|
||||
|
||||
should_route "GET /projects/foo/repository/foo/revisions/2457/show/#{@path_hash[:path]}" => 'repositories#show',
|
||||
:id => 'foo', :repository_id => 'foo', :rev => '2457', :path => @path_hash[:param]
|
||||
should_route "GET /projects/foo/repository/foo/revisions/2457/diff/#{@path_hash[:path]}" => 'repositories#diff',
|
||||
:id => 'foo', :repository_id => 'foo', :rev => '2457', :path => @path_hash[:param]
|
||||
should_route "GET /projects/foo/repository/foo/revisions/2457/entry/#{@path_hash[:path]}" => 'repositories#entry',
|
||||
:id => 'foo', :repository_id => 'foo', :rev => '2457', :path => @path_hash[:param]
|
||||
should_route "GET /projects/foo/repository/foo/revisions/2457/raw/#{@path_hash[:path]}" => 'repositories#raw',
|
||||
:id => 'foo', :repository_id => 'foo', :rev => '2457', :path => @path_hash[:param]
|
||||
should_route "GET /projects/foo/repository/foo/revisions/2457/annotate/#{@path_hash[:path]}" => 'repositories#annotate',
|
||||
:id => 'foo', :repository_id => 'foo', :rev => '2457', :path => @path_hash[:param]
|
||||
end
|
||||
|
||||
def test_repositories_non_revisions_path
|
||||
should_route 'GET /projects/foo/repository/changes' => 'repositories#changes', :id => 'foo'
|
||||
|
||||
should_route "GET /projects/foo/repository/changes/#{@path_hash[:path]}" => 'repositories#changes',
|
||||
:id => 'foo', :path => @path_hash[:param]
|
||||
should_route "GET /projects/foo/repository/diff/#{@path_hash[:path]}" => 'repositories#diff',
|
||||
:id => 'foo', :path => @path_hash[:param]
|
||||
should_route "GET /projects/foo/repository/browse/#{@path_hash[:path]}" => 'repositories#browse',
|
||||
:id => 'foo', :path => @path_hash[:param]
|
||||
should_route "GET /projects/foo/repository/entry/#{@path_hash[:path]}" => 'repositories#entry',
|
||||
:id => 'foo', :path => @path_hash[:param]
|
||||
should_route "GET /projects/foo/repository/raw/#{@path_hash[:path]}" => 'repositories#raw',
|
||||
:id => 'foo', :path => @path_hash[:param]
|
||||
should_route "GET /projects/foo/repository/annotate/#{@path_hash[:path]}" => 'repositories#annotate',
|
||||
:id => 'foo', :path => @path_hash[:param]
|
||||
end
|
||||
|
||||
def test_repositories_non_revisions_path_with_repository_id
|
||||
should_route 'GET /projects/foo/repository/svn/changes' => 'repositories#changes', :id => 'foo', :repository_id => 'svn'
|
||||
|
||||
should_route "GET /projects/foo/repository/svn/changes/#{@path_hash[:path]}" => 'repositories#changes',
|
||||
:id => 'foo', :repository_id => 'svn', :path => @path_hash[:param]
|
||||
should_route "GET /projects/foo/repository/svn/diff/#{@path_hash[:path]}" => 'repositories#diff',
|
||||
:id => 'foo', :repository_id => 'svn', :path => @path_hash[:param]
|
||||
should_route "GET /projects/foo/repository/svn/browse/#{@path_hash[:path]}" => 'repositories#browse',
|
||||
:id => 'foo', :repository_id => 'svn', :path => @path_hash[:param]
|
||||
should_route "GET /projects/foo/repository/svn/entry/#{@path_hash[:path]}" => 'repositories#entry',
|
||||
:id => 'foo', :repository_id => 'svn', :path => @path_hash[:param]
|
||||
should_route "GET /projects/foo/repository/svn/raw/#{@path_hash[:path]}" => 'repositories#raw',
|
||||
:id => 'foo', :repository_id => 'svn', :path => @path_hash[:param]
|
||||
should_route "GET /projects/foo/repository/svn/annotate/#{@path_hash[:path]}" => 'repositories#annotate',
|
||||
:id => 'foo', :repository_id => 'svn', :path => @path_hash[:param]
|
||||
end
|
||||
|
||||
def test_repositories_related_issues
|
||||
should_route 'POST /projects/foo/repository/revisions/123/issues' => 'repositories#add_related_issue',
|
||||
:id => 'foo', :rev => '123'
|
||||
should_route 'DELETE /projects/foo/repository/revisions/123/issues/25' => 'repositories#remove_related_issue',
|
||||
:id => 'foo', :rev => '123', :issue_id => '25'
|
||||
end
|
||||
|
||||
def test_repositories_related_issues_with_repository_id
|
||||
should_route 'POST /projects/foo/repository/svn/revisions/123/issues' => 'repositories#add_related_issue',
|
||||
:id => 'foo', :repository_id => 'svn', :rev => '123'
|
||||
should_route 'DELETE /projects/foo/repository/svn/revisions/123/issues/25' => 'repositories#remove_related_issue',
|
||||
:id => 'foo', :repository_id => 'svn', :rev => '123', :issue_id => '25'
|
||||
end
|
||||
end
|
33
test/integration/routing/roles_test.rb
Normal file
33
test/integration/routing/roles_test.rb
Normal file
|
@ -0,0 +1,33 @@
|
|||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2017 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 RoutingRolesTest < Redmine::RoutingTest
|
||||
def test_roles
|
||||
should_route 'GET /roles' => 'roles#index'
|
||||
should_route 'GET /roles/new' => 'roles#new'
|
||||
should_route 'POST /roles' => 'roles#create'
|
||||
|
||||
should_route 'GET /roles/2/edit' => 'roles#edit', :id => '2'
|
||||
should_route 'PUT /roles/2' => 'roles#update', :id => '2'
|
||||
should_route 'DELETE /roles/2' => 'roles#destroy', :id => '2'
|
||||
|
||||
should_route 'GET /roles/permissions' => 'roles#permissions'
|
||||
should_route 'POST /roles/permissions' => 'roles#permissions'
|
||||
end
|
||||
end
|
25
test/integration/routing/search_test.rb
Normal file
25
test/integration/routing/search_test.rb
Normal file
|
@ -0,0 +1,25 @@
|
|||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2017 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 RoutingSearchTest < Redmine::RoutingTest
|
||||
def test_search
|
||||
should_route 'GET /search' => 'search#index'
|
||||
should_route 'GET /projects/foo/search' => 'search#index', :id => 'foo'
|
||||
end
|
||||
end
|
29
test/integration/routing/settings_test.rb
Normal file
29
test/integration/routing/settings_test.rb
Normal file
|
@ -0,0 +1,29 @@
|
|||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2017 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 RoutingSettingsTest < Redmine::RoutingTest
|
||||
def test_settings
|
||||
should_route 'GET /settings' => 'settings#index'
|
||||
should_route 'GET /settings/edit' => 'settings#edit'
|
||||
should_route 'POST /settings/edit' => 'settings#edit'
|
||||
|
||||
should_route 'GET /settings/plugin/testid' => 'settings#plugin', :id => 'testid'
|
||||
should_route 'POST /settings/plugin/testid' => 'settings#plugin', :id => 'testid'
|
||||
end
|
||||
end
|
27
test/integration/routing/sys_test.rb
Normal file
27
test/integration/routing/sys_test.rb
Normal file
|
@ -0,0 +1,27 @@
|
|||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2017 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 RoutingSysTest < Redmine::RoutingTest
|
||||
def test_sys
|
||||
should_route 'GET /sys/projects' => 'sys#projects'
|
||||
should_route 'POST /sys/projects/foo/repository' => 'sys#create_project_repository', :id => 'foo'
|
||||
should_route 'GET /sys/fetch_changesets' => 'sys#fetch_changesets'
|
||||
should_route 'POST /sys/fetch_changesets' => 'sys#fetch_changesets'
|
||||
end
|
||||
end
|
61
test/integration/routing/timelog_test.rb
Normal file
61
test/integration/routing/timelog_test.rb
Normal file
|
@ -0,0 +1,61 @@
|
|||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2017 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 RoutingTimelogsTest < Redmine::RoutingTest
|
||||
def test_timelogs_global
|
||||
should_route 'GET /time_entries' => 'timelog#index'
|
||||
should_route 'GET /time_entries.csv' => 'timelog#index', :format => 'csv'
|
||||
should_route 'GET /time_entries.atom' => 'timelog#index', :format => 'atom'
|
||||
should_route 'GET /time_entries/new' => 'timelog#new'
|
||||
should_route 'POST /time_entries/new' => 'timelog#new'
|
||||
should_route 'POST /time_entries' => 'timelog#create'
|
||||
|
||||
should_route 'GET /time_entries/22/edit' => 'timelog#edit', :id => '22'
|
||||
should_route 'PATCH /time_entries/22/edit' => 'timelog#edit', :id => '22'
|
||||
should_route 'PATCH /time_entries/22' => 'timelog#update', :id => '22'
|
||||
should_route 'DELETE /time_entries/22' => 'timelog#destroy', :id => '22'
|
||||
end
|
||||
|
||||
def test_timelogs_scoped_under_project
|
||||
should_route 'GET /projects/foo/time_entries' => 'timelog#index', :project_id => 'foo'
|
||||
should_route 'GET /projects/foo/time_entries.csv' => 'timelog#index', :project_id => 'foo', :format => 'csv'
|
||||
should_route 'GET /projects/foo/time_entries.atom' => 'timelog#index', :project_id => 'foo', :format => 'atom'
|
||||
should_route 'GET /projects/foo/time_entries/new' => 'timelog#new', :project_id => 'foo'
|
||||
should_route 'POST /projects/foo/time_entries' => 'timelog#create', :project_id => 'foo'
|
||||
end
|
||||
|
||||
def test_timelogs_scoped_under_issues
|
||||
should_route 'GET /issues/234/time_entries/new' => 'timelog#new', :issue_id => '234'
|
||||
should_route 'POST /issues/234/time_entries' => 'timelog#create', :issue_id => '234'
|
||||
end
|
||||
|
||||
def test_timelogs_report
|
||||
should_route 'GET /time_entries/report' => 'timelog#report'
|
||||
should_route 'GET /time_entries/report.csv' => 'timelog#report', :format => 'csv'
|
||||
|
||||
should_route 'GET /projects/foo/time_entries/report' => 'timelog#report', :project_id => 'foo'
|
||||
should_route 'GET /projects/foo/time_entries/report.csv' => 'timelog#report', :project_id => 'foo', :format => 'csv'
|
||||
end
|
||||
|
||||
def test_timelogs_bulk_edit
|
||||
should_route 'GET /time_entries/bulk_edit' => 'timelog#bulk_edit'
|
||||
should_route 'POST /time_entries/bulk_update' => 'timelog#bulk_update'
|
||||
should_route 'DELETE /time_entries/destroy' => 'timelog#destroy'
|
||||
end
|
||||
end
|
33
test/integration/routing/trackers_test.rb
Normal file
33
test/integration/routing/trackers_test.rb
Normal file
|
@ -0,0 +1,33 @@
|
|||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2017 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 RoutingTrackersTest < Redmine::RoutingTest
|
||||
def test_trackers
|
||||
should_route 'GET /trackers' => 'trackers#index'
|
||||
should_route 'GET /trackers/new' => 'trackers#new'
|
||||
should_route 'POST /trackers' => 'trackers#create'
|
||||
|
||||
should_route 'GET /trackers/1/edit' => 'trackers#edit', :id => '1'
|
||||
should_route 'PUT /trackers/1' => 'trackers#update', :id => '1'
|
||||
should_route 'DELETE /trackers/1' => 'trackers#destroy', :id => '1'
|
||||
|
||||
should_route 'GET /trackers/fields' => 'trackers#fields'
|
||||
should_route 'POST /trackers/fields' => 'trackers#fields'
|
||||
end
|
||||
end
|
32
test/integration/routing/users_test.rb
Normal file
32
test/integration/routing/users_test.rb
Normal file
|
@ -0,0 +1,32 @@
|
|||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2017 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 RoutingUsersTest < Redmine::RoutingTest
|
||||
def test_users
|
||||
should_route 'GET /users' => 'users#index'
|
||||
should_route 'GET /users/new' => 'users#new'
|
||||
should_route 'POST /users' => 'users#create'
|
||||
|
||||
should_route 'GET /users/44' => 'users#show', :id => '44'
|
||||
should_route 'GET /users/current' => 'users#show', :id => 'current'
|
||||
should_route 'GET /users/44/edit' => 'users#edit', :id => '44'
|
||||
should_route 'PUT /users/44' => 'users#update', :id => '44'
|
||||
should_route 'DELETE /users/44' => 'users#destroy', :id => '44'
|
||||
end
|
||||
end
|
36
test/integration/routing/versions_test.rb
Normal file
36
test/integration/routing/versions_test.rb
Normal file
|
@ -0,0 +1,36 @@
|
|||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2017 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 RoutingVersionsTest < Redmine::RoutingTest
|
||||
def test_project_versions
|
||||
should_route 'GET /projects/foo/roadmap' => 'versions#index', :project_id => 'foo'
|
||||
should_route 'GET /projects/foo/versions/new' => 'versions#new', :project_id => 'foo'
|
||||
should_route 'POST /projects/foo/versions' => 'versions#create', :project_id => 'foo'
|
||||
should_route 'PUT /projects/foo/versions/close_completed' => 'versions#close_completed', :project_id => 'foo'
|
||||
end
|
||||
|
||||
def test_versions
|
||||
should_route 'GET /versions/1' => 'versions#show', :id => '1'
|
||||
should_route 'GET /versions/1/edit' => 'versions#edit', :id => '1'
|
||||
should_route 'PUT /versions/1' => 'versions#update', :id => '1'
|
||||
should_route 'DELETE /versions/1' => 'versions#destroy', :id => '1'
|
||||
|
||||
should_route 'POST /versions/1/status_by' => 'versions#status_by', :id => '1'
|
||||
end
|
||||
end
|
31
test/integration/routing/watchers_test.rb
Normal file
31
test/integration/routing/watchers_test.rb
Normal file
|
@ -0,0 +1,31 @@
|
|||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2017 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 RoutingWatchersTest < Redmine::RoutingTest
|
||||
def test_watchers
|
||||
should_route 'GET /watchers/new' => 'watchers#new'
|
||||
should_route 'POST /watchers/append' => 'watchers#append'
|
||||
should_route 'POST /watchers' => 'watchers#create'
|
||||
should_route 'DELETE /watchers' => 'watchers#destroy'
|
||||
should_route 'GET /watchers/autocomplete_for_user' => 'watchers#autocomplete_for_user'
|
||||
|
||||
should_route 'POST /watchers/watch' => 'watchers#watch'
|
||||
should_route 'DELETE /watchers/watch' => 'watchers#unwatch'
|
||||
end
|
||||
end
|
25
test/integration/routing/welcome_test.rb
Normal file
25
test/integration/routing/welcome_test.rb
Normal file
|
@ -0,0 +1,25 @@
|
|||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2017 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 RoutingWelcomeTest < Redmine::RoutingTest
|
||||
def test_welcome
|
||||
should_route 'GET /' => 'welcome#index'
|
||||
should_route 'GET /robots.txt' => 'welcome#robots'
|
||||
end
|
||||
end
|
62
test/integration/routing/wiki_test.rb
Normal file
62
test/integration/routing/wiki_test.rb
Normal file
|
@ -0,0 +1,62 @@
|
|||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2017 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 RoutingWikiTest < Redmine::RoutingTest
|
||||
def test_wiki
|
||||
should_route 'GET /projects/foo/wiki' => 'wiki#show', :project_id => 'foo'
|
||||
should_route 'GET /projects/foo/wiki/index' => 'wiki#index', :project_id => 'foo'
|
||||
should_route 'GET /projects/foo/wiki/date_index' => 'wiki#date_index', :project_id => 'foo'
|
||||
should_route 'GET /projects/foo/wiki/export' => 'wiki#export', :project_id => 'foo'
|
||||
should_route 'GET /projects/foo/wiki/export.pdf' => 'wiki#export', :project_id => 'foo', :format => 'pdf'
|
||||
end
|
||||
|
||||
def test_wiki_pages
|
||||
should_route 'GET /projects/foo/wiki/page' => 'wiki#show', :project_id => 'foo', :id => 'page'
|
||||
should_route 'GET /projects/foo/wiki/page.pdf' => 'wiki#show', :project_id => 'foo', :id => 'page', :format => 'pdf'
|
||||
|
||||
should_route 'GET /projects/foo/wiki/new' => 'wiki#new', :project_id => 'foo'
|
||||
should_route 'POST /projects/foo/wiki/new' => 'wiki#new', :project_id => 'foo'
|
||||
|
||||
should_route 'GET /projects/foo/wiki/page/edit' => 'wiki#edit', :project_id => 'foo', :id => 'page'
|
||||
should_route 'PUT /projects/foo/wiki/page' => 'wiki#update', :project_id => 'foo', :id => 'page'
|
||||
should_route 'DELETE /projects/foo/wiki/page' => 'wiki#destroy', :project_id => 'foo', :id => 'page'
|
||||
|
||||
should_route 'GET /projects/foo/wiki/page/history' => 'wiki#history', :project_id => 'foo', :id => 'page'
|
||||
should_route 'GET /projects/foo/wiki/page/diff' => 'wiki#diff', :project_id => 'foo', :id => 'page'
|
||||
should_route 'GET /projects/foo/wiki/page/rename' => 'wiki#rename', :project_id => 'foo', :id => 'page'
|
||||
should_route 'POST /projects/foo/wiki/page/rename' => 'wiki#rename', :project_id => 'foo', :id => 'page'
|
||||
should_route 'POST /projects/foo/wiki/page/protect' => 'wiki#protect', :project_id => 'foo', :id => 'page'
|
||||
should_route 'POST /projects/foo/wiki/page/add_attachment' => 'wiki#add_attachment', :project_id => 'foo', :id => 'page'
|
||||
|
||||
should_route 'POST /projects/foo/wiki/page/preview' => 'wiki#preview', :project_id => 'foo', :id => 'page'
|
||||
should_route 'PUT /projects/foo/wiki/page/preview' => 'wiki#preview', :project_id => 'foo', :id => 'page'
|
||||
|
||||
# Make sure we don't route wiki page sub-uris to let plugins handle them
|
||||
assert_raise(Minitest::Assertion) do
|
||||
assert_recognizes({}, {:method => 'get', :path => "/projects/foo/wiki/page/whatever"})
|
||||
end
|
||||
end
|
||||
|
||||
def test_wiki_page_versions
|
||||
should_route 'GET /projects/foo/wiki/page/2' => 'wiki#show', :project_id => 'foo', :id => 'page', :version => '2'
|
||||
should_route 'GET /projects/foo/wiki/page/2/diff' => 'wiki#diff', :project_id => 'foo', :id => 'page', :version => '2'
|
||||
should_route 'GET /projects/foo/wiki/page/2/annotate' => 'wiki#annotate', :project_id => 'foo', :id => 'page', :version => '2'
|
||||
should_route 'DELETE /projects/foo/wiki/page/2' => 'wiki#destroy_version', :project_id => 'foo', :id => 'page', :version => '2'
|
||||
end
|
||||
end
|
27
test/integration/routing/wikis_test.rb
Normal file
27
test/integration/routing/wikis_test.rb
Normal file
|
@ -0,0 +1,27 @@
|
|||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2017 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 RoutingWikisTest < Redmine::RoutingTest
|
||||
def test_wikis
|
||||
should_route 'POST /projects/foo/wiki' => 'wikis#edit', :id => 'foo'
|
||||
|
||||
should_route 'GET /projects/foo/wiki/destroy' => 'wikis#destroy', :id => 'foo'
|
||||
should_route 'POST /projects/foo/wiki/destroy' => 'wikis#destroy', :id => 'foo'
|
||||
end
|
||||
end
|
32
test/integration/routing/workflows_test.rb
Normal file
32
test/integration/routing/workflows_test.rb
Normal file
|
@ -0,0 +1,32 @@
|
|||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2017 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 RoutingWorkflowsTest < Redmine::RoutingTest
|
||||
def test_workflows
|
||||
should_route 'GET /workflows' => 'workflows#index'
|
||||
should_route 'GET /workflows/edit' => 'workflows#edit'
|
||||
should_route 'POST /workflows/edit' => 'workflows#edit'
|
||||
|
||||
should_route 'GET /workflows/permissions' => 'workflows#permissions'
|
||||
should_route 'POST /workflows/permissions' => 'workflows#permissions'
|
||||
|
||||
should_route 'GET /workflows/copy' => 'workflows#copy'
|
||||
should_route 'POST /workflows/copy' => 'workflows#copy'
|
||||
end
|
||||
end
|
99
test/integration/sessions_test.rb
Normal file
99
test/integration/sessions_test.rb
Normal file
|
@ -0,0 +1,99 @@
|
|||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2017 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 SessionsTest < Redmine::IntegrationTest
|
||||
fixtures :users, :email_addresses, :roles
|
||||
|
||||
def setup
|
||||
Rails.application.config.redmine_verify_sessions = true
|
||||
end
|
||||
|
||||
def teardown
|
||||
Rails.application.config.redmine_verify_sessions = false
|
||||
end
|
||||
|
||||
def test_change_password_kills_sessions
|
||||
log_user('jsmith', 'jsmith')
|
||||
|
||||
jsmith = User.find(2)
|
||||
jsmith.password = "somenewpassword"
|
||||
jsmith.save!
|
||||
|
||||
get '/my/account'
|
||||
assert_response 302
|
||||
assert flash[:error].match(/Your session has expired/)
|
||||
end
|
||||
|
||||
def test_lock_user_kills_sessions
|
||||
log_user('jsmith', 'jsmith')
|
||||
|
||||
jsmith = User.find(2)
|
||||
assert jsmith.lock!
|
||||
assert jsmith.activate!
|
||||
|
||||
get '/my/account'
|
||||
assert_response 302
|
||||
assert flash[:error].match(/Your session has expired/)
|
||||
end
|
||||
|
||||
def test_update_user_does_not_kill_sessions
|
||||
log_user('jsmith', 'jsmith')
|
||||
|
||||
jsmith = User.find(2)
|
||||
jsmith.firstname = 'Robert'
|
||||
jsmith.save!
|
||||
|
||||
get '/my/account'
|
||||
assert_response 200
|
||||
end
|
||||
|
||||
def test_change_password_generates_a_new_token_for_current_session
|
||||
log_user('jsmith', 'jsmith')
|
||||
assert_not_nil token = session[:tk]
|
||||
|
||||
get '/my/password'
|
||||
assert_response 200
|
||||
post '/my/password', :params => {
|
||||
:password => 'jsmith',
|
||||
:new_password => 'secret123',
|
||||
:new_password_confirmation => 'secret123'
|
||||
}
|
||||
assert_response 302
|
||||
assert_not_equal token, session[:tk]
|
||||
|
||||
get '/my/account'
|
||||
assert_response 200
|
||||
end
|
||||
|
||||
def test_simultaneous_sessions_should_be_valid
|
||||
first = open_session do |session|
|
||||
session.post "/login", :params => {:username => 'jsmith', :password => 'jsmith'}
|
||||
end
|
||||
other = open_session do |session|
|
||||
session.post "/login", :params => {:username => 'jsmith', :password => 'jsmith'}
|
||||
end
|
||||
|
||||
first.get '/my/account'
|
||||
assert_equal 200, first.response.response_code
|
||||
first.post '/logout'
|
||||
|
||||
other.get '/my/account'
|
||||
assert_equal 200, other.response.response_code
|
||||
end
|
||||
end
|
199
test/integration/sudo_mode_test.rb
Normal file
199
test/integration/sudo_mode_test.rb
Normal file
|
@ -0,0 +1,199 @@
|
|||
require File.expand_path('../../test_helper', __FILE__)
|
||||
|
||||
class SudoModeTest < Redmine::IntegrationTest
|
||||
fixtures :projects, :members, :member_roles, :roles, :users, :email_addresses
|
||||
|
||||
def setup
|
||||
Redmine::SudoMode.stubs(:enabled?).returns(true)
|
||||
end
|
||||
|
||||
def teardown
|
||||
travel_back
|
||||
end
|
||||
|
||||
def test_sudo_mode_should_be_active_after_login
|
||||
log_user("admin", "admin")
|
||||
get "/users/new"
|
||||
assert_response :success
|
||||
post "/users", :params => {
|
||||
:user => { :login => "psmith", :firstname => "Paul",
|
||||
:lastname => "Smith", :mail => "psmith@somenet.foo",
|
||||
:language => "en", :password => "psmith09",
|
||||
:password_confirmation => "psmith09" }
|
||||
}
|
||||
assert_response 302
|
||||
|
||||
user = User.find_by_login("psmith")
|
||||
assert_kind_of User, user
|
||||
end
|
||||
|
||||
def test_add_user
|
||||
log_user("admin", "admin")
|
||||
expire_sudo_mode!
|
||||
get "/users/new"
|
||||
assert_response :success
|
||||
post "/users", :params => {
|
||||
:user => { :login => "psmith", :firstname => "Paul",
|
||||
:lastname => "Smith", :mail => "psmith@somenet.foo",
|
||||
:language => "en", :password => "psmith09",
|
||||
:password_confirmation => "psmith09" }
|
||||
}
|
||||
assert_response :success
|
||||
assert_nil User.find_by_login("psmith")
|
||||
|
||||
assert_select 'input[name=?][value=?]', 'user[login]', 'psmith'
|
||||
assert_select 'input[name=?][value=?]', 'user[firstname]', 'Paul'
|
||||
|
||||
post "/users", :params => {
|
||||
:user => { :login => "psmith", :firstname => "Paul",
|
||||
:lastname => "Smith", :mail => "psmith@somenet.foo",
|
||||
:language => "en", :password => "psmith09",
|
||||
:password_confirmation => "psmith09" },
|
||||
:sudo_password => 'admin'
|
||||
}
|
||||
assert_response 302
|
||||
|
||||
user = User.find_by_login("psmith")
|
||||
assert_kind_of User, user
|
||||
end
|
||||
|
||||
def test_create_member_xhr
|
||||
log_user 'admin', 'admin'
|
||||
expire_sudo_mode!
|
||||
get '/projects/ecookbook/settings/members'
|
||||
assert_response :success
|
||||
|
||||
assert_no_difference 'Member.count' do
|
||||
post '/projects/ecookbook/memberships', :params => {membership: {role_ids: [1], user_id: 7}}, :xhr => true
|
||||
end
|
||||
|
||||
assert_no_difference 'Member.count' do
|
||||
post '/projects/ecookbook/memberships', :params => {membership: {role_ids: [1], user_id: 7}, sudo_password: ''}, :xhr => true
|
||||
end
|
||||
|
||||
assert_no_difference 'Member.count' do
|
||||
post '/projects/ecookbook/memberships', :params => {membership: {role_ids: [1], user_id: 7}, sudo_password: 'wrong'}, :xhr => true
|
||||
end
|
||||
|
||||
assert_difference 'Member.count' do
|
||||
post '/projects/ecookbook/memberships', :params => {membership: {role_ids: [1], user_id: 7}, sudo_password: 'admin'}, :xhr => true
|
||||
end
|
||||
assert User.find(7).member_of?(Project.find(1))
|
||||
end
|
||||
|
||||
def test_create_member
|
||||
log_user 'admin', 'admin'
|
||||
expire_sudo_mode!
|
||||
get '/projects/ecookbook/settings/members'
|
||||
assert_response :success
|
||||
|
||||
assert_no_difference 'Member.count' do
|
||||
post '/projects/ecookbook/memberships', :params => {membership: {role_ids: [1], user_id: 7}}
|
||||
end
|
||||
|
||||
assert_no_difference 'Member.count' do
|
||||
post '/projects/ecookbook/memberships', :params => {membership: {role_ids: [1], user_id: 7}, sudo_password: ''}
|
||||
end
|
||||
|
||||
assert_no_difference 'Member.count' do
|
||||
post '/projects/ecookbook/memberships', :params => {membership: {role_ids: [1], user_id: 7}, sudo_password: 'wrong'}
|
||||
end
|
||||
|
||||
assert_difference 'Member.count' do
|
||||
post '/projects/ecookbook/memberships', :params => {membership: {role_ids: [1], user_id: 7}, sudo_password: 'admin'}
|
||||
end
|
||||
|
||||
assert_redirected_to '/projects/ecookbook/settings/members'
|
||||
assert User.find(7).member_of?(Project.find(1))
|
||||
end
|
||||
|
||||
def test_create_role
|
||||
log_user 'admin', 'admin'
|
||||
expire_sudo_mode!
|
||||
get '/roles'
|
||||
assert_response :success
|
||||
|
||||
get '/roles/new'
|
||||
assert_response :success
|
||||
|
||||
post '/roles', :params => {role: { }}
|
||||
assert_response :success
|
||||
assert_select 'h2', 'Confirm your password to continue'
|
||||
assert_select 'form[action="/roles"]'
|
||||
assert_select '#flash_error', 0
|
||||
|
||||
post '/roles', :params => {role: { name: 'new role', issues_visibility: 'all' }}
|
||||
assert_response :success
|
||||
assert_select 'h2', 'Confirm your password to continue'
|
||||
assert_select 'form[action="/roles"]'
|
||||
assert_select 'input[type=hidden][name=?][value=?]', 'role[name]', 'new role'
|
||||
assert_select '#flash_error', 0
|
||||
|
||||
post '/roles', :params => {role: { name: 'new role', issues_visibility: 'all' }, sudo_password: 'wrong'}
|
||||
assert_response :success
|
||||
assert_select 'h2', 'Confirm your password to continue'
|
||||
assert_select 'form[action="/roles"]'
|
||||
assert_select 'input[type=hidden][name=?][value=?]', 'role[name]', 'new role'
|
||||
assert_select '#flash_error'
|
||||
|
||||
assert_difference 'Role.count' do
|
||||
post '/roles', :params => {role: { name: 'new role', issues_visibility: 'all', assignable: '1', permissions: %w(view_calendar) }, sudo_password: 'admin'}
|
||||
end
|
||||
assert_redirected_to '/roles'
|
||||
end
|
||||
|
||||
def test_update_email_address
|
||||
log_user 'jsmith', 'jsmith'
|
||||
expire_sudo_mode!
|
||||
get '/my/account'
|
||||
assert_response :success
|
||||
post '/my/account', :params => {user: { mail: 'newmail@test.com' }}
|
||||
assert_response :success
|
||||
assert_select 'h2', 'Confirm your password to continue'
|
||||
assert_select 'form[action="/my/account"]'
|
||||
assert_select 'input[type=hidden][name=?][value=?]', 'user[mail]', 'newmail@test.com'
|
||||
assert_select '#flash_error', 0
|
||||
|
||||
# wrong password
|
||||
post '/my/account', :params => {user: { mail: 'newmail@test.com' }, sudo_password: 'wrong'}
|
||||
assert_response :success
|
||||
assert_select 'h2', 'Confirm your password to continue'
|
||||
assert_select 'form[action="/my/account"]'
|
||||
assert_select 'input[type=hidden][name=?][value=?]', 'user[mail]', 'newmail@test.com'
|
||||
assert_select '#flash_error'
|
||||
|
||||
# correct password
|
||||
post '/my/account', :params => {user: { mail: 'newmail@test.com' }, sudo_password: 'jsmith'}
|
||||
assert_redirected_to '/my/account'
|
||||
assert_equal 'newmail@test.com', User.find_by_login('jsmith').mail
|
||||
|
||||
# sudo mode should now be active and not require password again
|
||||
post '/my/account', :params => {user: { mail: 'even.newer.mail@test.com' }}
|
||||
assert_redirected_to '/my/account'
|
||||
assert_equal 'even.newer.mail@test.com', User.find_by_login('jsmith').mail
|
||||
end
|
||||
|
||||
def test_sudo_mode_should_skip_api_requests
|
||||
with_settings :rest_api_enabled => '1' do
|
||||
assert_difference('User.count') do
|
||||
post '/users.json', :params => {
|
||||
:user => {
|
||||
:login => 'foo', :firstname => 'Firstname', :lastname => 'Lastname',
|
||||
:mail => 'foo@example.net', :password => 'secret123',
|
||||
:mail_notification => 'only_assigned'
|
||||
}
|
||||
},
|
||||
:headers => credentials('admin')
|
||||
|
||||
assert_response :created
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
# sudo mode is active after sign, let it expire by advancing the time
|
||||
def expire_sudo_mode!
|
||||
travel_to 20.minutes.from_now
|
||||
end
|
||||
end
|
31
test/integration/users_test.rb
Normal file
31
test/integration/users_test.rb
Normal file
|
@ -0,0 +1,31 @@
|
|||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2017 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 UsersTest < Redmine::IntegrationTest
|
||||
fixtures :users, :email_addresses
|
||||
|
||||
def test_destroy_should_not_accept_get_requests
|
||||
log_user('admin', 'admin')
|
||||
|
||||
assert_no_difference 'User.count' do
|
||||
get '/users/destroy/2'
|
||||
assert_response 404
|
||||
end
|
||||
end
|
||||
end
|
Loading…
Add table
Add a link
Reference in a new issue