##// END OF EJS Templates
Pull up #setup and #teardown in API tests....
Jean-Philippe Lang -
r13297:d22029083c48
parent child
Show More
@@ -1,41 +1,37
1 1 # Redmine - project management software
2 2 # Copyright (C) 2006-2014 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 18 require File.expand_path('../../../test_helper', __FILE__)
19 19
20 20 class Redmine::ApiTest::ApiTest < Redmine::ApiTest::Base
21 21 fixtures :users
22 22
23 def setup
24 Setting.rest_api_enabled = '1'
25 end
26
27 23 def test_api_should_work_with_protect_from_forgery
28 24 ActionController::Base.allow_forgery_protection = true
29 25 assert_difference('User.count') do
30 26 post '/users.xml', {
31 27 :user => {
32 28 :login => 'foo', :firstname => 'Firstname', :lastname => 'Lastname',
33 29 :mail => 'foo@example.net', :password => 'secret123'}
34 30 },
35 31 credentials('admin')
36 32 assert_response 201
37 33 end
38 34 ensure
39 35 ActionController::Base.allow_forgery_protection = false
40 36 end
41 37 end No newline at end of file
@@ -1,140 +1,141
1 1 # Redmine - project management software
2 2 # Copyright (C) 2006-2014 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 18 require File.expand_path('../../../test_helper', __FILE__)
19 19
20 20 class Redmine::ApiTest::AttachmentsTest < Redmine::ApiTest::Base
21 21 fixtures :projects, :trackers, :issue_statuses, :issues,
22 22 :enumerations, :users, :issue_categories,
23 23 :projects_trackers,
24 24 :roles,
25 25 :member_roles,
26 26 :members,
27 27 :enabled_modules,
28 28 :attachments
29 29
30 30 def setup
31 Setting.rest_api_enabled = '1'
31 super
32 32 set_fixtures_attachments_directory
33 33 end
34 34
35 35 def teardown
36 super
36 37 set_tmp_attachments_directory
37 38 end
38 39
39 40 test "GET /attachments/:id.xml should return the attachment" do
40 41 get '/attachments/7.xml', {}, credentials('jsmith')
41 42 assert_response :success
42 43 assert_equal 'application/xml', @response.content_type
43 44 assert_select 'attachment id:content(7)' do
44 45 assert_select '~ filename', :text => 'archive.zip'
45 46 assert_select '~ content_url', :text => 'http://www.example.com/attachments/download/7/archive.zip'
46 47 end
47 48 end
48 49
49 50 test "GET /attachments/:id.xml should deny access without credentials" do
50 51 get '/attachments/7.xml'
51 52 assert_response 401
52 53 set_tmp_attachments_directory
53 54 end
54 55
55 56 test "GET /attachments/download/:id/:filename should return the attachment content" do
56 57 get '/attachments/download/7/archive.zip', {}, credentials('jsmith')
57 58 assert_response :success
58 59 assert_equal 'application/octet-stream', @response.content_type
59 60 set_tmp_attachments_directory
60 61 end
61 62
62 63 test "GET /attachments/download/:id/:filename should deny access without credentials" do
63 64 get '/attachments/download/7/archive.zip'
64 65 assert_response 302
65 66 set_tmp_attachments_directory
66 67 end
67 68
68 69 test "POST /uploads.xml should return the token" do
69 70 set_tmp_attachments_directory
70 71 assert_difference 'Attachment.count' do
71 72 post '/uploads.xml', 'File content', {"CONTENT_TYPE" => 'application/octet-stream'}.merge(credentials('jsmith'))
72 73 assert_response :created
73 74 assert_equal 'application/xml', response.content_type
74 75 end
75 76
76 77 xml = Hash.from_xml(response.body)
77 78 assert_kind_of Hash, xml['upload']
78 79 token = xml['upload']['token']
79 80 assert_not_nil token
80 81
81 82 attachment = Attachment.order('id DESC').first
82 83 assert_equal token, attachment.token
83 84 assert_nil attachment.container
84 85 assert_equal 2, attachment.author_id
85 86 assert_equal 'File content'.size, attachment.filesize
86 87 assert attachment.content_type.blank?
87 88 assert attachment.filename.present?
88 89 assert_match /\d+_[0-9a-z]+/, attachment.diskfile
89 90 assert File.exist?(attachment.diskfile)
90 91 assert_equal 'File content', File.read(attachment.diskfile)
91 92 end
92 93
93 94 test "POST /uploads.json should return the token" do
94 95 set_tmp_attachments_directory
95 96 assert_difference 'Attachment.count' do
96 97 post '/uploads.json', 'File content', {"CONTENT_TYPE" => 'application/octet-stream'}.merge(credentials('jsmith'))
97 98 assert_response :created
98 99 assert_equal 'application/json', response.content_type
99 100 end
100 101
101 102 json = ActiveSupport::JSON.decode(response.body)
102 103 assert_kind_of Hash, json['upload']
103 104 token = json['upload']['token']
104 105 assert_not_nil token
105 106
106 107 attachment = Attachment.order('id DESC').first
107 108 assert_equal token, attachment.token
108 109 end
109 110
110 111 test "POST /uploads.xml should accept :filename param as the attachment filename" do
111 112 set_tmp_attachments_directory
112 113 assert_difference 'Attachment.count' do
113 114 post '/uploads.xml?filename=test.txt', 'File content', {"CONTENT_TYPE" => 'application/octet-stream'}.merge(credentials('jsmith'))
114 115 assert_response :created
115 116 end
116 117
117 118 attachment = Attachment.order('id DESC').first
118 119 assert_equal 'test.txt', attachment.filename
119 120 assert_match /_test\.txt$/, attachment.diskfile
120 121 end
121 122
122 123 test "POST /uploads.xml should not accept other content types" do
123 124 set_tmp_attachments_directory
124 125 assert_no_difference 'Attachment.count' do
125 126 post '/uploads.xml', 'PNG DATA', {"CONTENT_TYPE" => 'image/png'}.merge(credentials('jsmith'))
126 127 assert_response 406
127 128 end
128 129 end
129 130
130 131 test "POST /uploads.xml should return errors if file is too big" do
131 132 set_tmp_attachments_directory
132 133 with_settings :attachment_max_size => 1 do
133 134 assert_no_difference 'Attachment.count' do
134 135 post '/uploads.xml', ('x' * 2048), {"CONTENT_TYPE" => 'application/octet-stream'}.merge(credentials('jsmith'))
135 136 assert_response 422
136 137 assert_select 'error', :text => /exceeds the maximum allowed file size/
137 138 end
138 139 end
139 140 end
140 141 end
@@ -1,166 +1,158
1 1 # Redmine - project management software
2 2 # Copyright (C) 2006-2014 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 18 require File.expand_path('../../../test_helper', __FILE__)
19 19
20 20 class Redmine::ApiTest::AuthenticationTest < Redmine::ApiTest::Base
21 21 fixtures :users
22 22
23 def setup
24 Setting.rest_api_enabled = '1'
25 end
26
27 def teardown
28 Setting.rest_api_enabled = '0'
29 end
30
31 23 def test_api_should_deny_without_credentials
32 24 get '/users/current.xml', {}
33 25 assert_response 401
34 26 assert_equal User.anonymous, User.current
35 27 assert response.headers.has_key?('WWW-Authenticate')
36 28 end
37 29
38 30 def test_api_should_accept_http_basic_auth_using_username_and_password
39 31 user = User.generate! do |user|
40 32 user.password = 'my_password'
41 33 end
42 34 get '/users/current.xml', {}, credentials(user.login, 'my_password')
43 35 assert_response 200
44 36 assert_equal user, User.current
45 37 end
46 38
47 39 def test_api_should_deny_http_basic_auth_using_username_and_wrong_password
48 40 user = User.generate! do |user|
49 41 user.password = 'my_password'
50 42 end
51 43 get '/users/current.xml', {}, credentials(user.login, 'wrong_password')
52 44 assert_response 401
53 45 assert_equal User.anonymous, User.current
54 46 end
55 47
56 48 def test_api_should_accept_http_basic_auth_using_api_key
57 49 user = User.generate!
58 50 token = Token.create!(:user => user, :action => 'api')
59 51 get '/users/current.xml', {}, credentials(token.value, 'X')
60 52 assert_response 200
61 53 assert_equal user, User.current
62 54 end
63 55
64 56 def test_api_should_deny_http_basic_auth_using_wrong_api_key
65 57 user = User.generate!
66 58 token = Token.create!(:user => user, :action => 'feeds') # not the API key
67 59 get '/users/current.xml', {}, credentials(token.value, 'X')
68 60 assert_response 401
69 61 assert_equal User.anonymous, User.current
70 62 end
71 63
72 64 def test_api_should_accept_auth_using_api_key_as_parameter
73 65 user = User.generate!
74 66 token = Token.create!(:user => user, :action => 'api')
75 67 get "/users/current.xml?key=#{token.value}", {}
76 68 assert_response 200
77 69 assert_equal user, User.current
78 70 end
79 71
80 72 def test_api_should_deny_auth_using_wrong_api_key_as_parameter
81 73 user = User.generate!
82 74 token = Token.create!(:user => user, :action => 'feeds') # not the API key
83 75 get "/users/current.xml?key=#{token.value}", {}
84 76 assert_response 401
85 77 assert_equal User.anonymous, User.current
86 78 end
87 79
88 80 def test_api_should_accept_auth_using_api_key_as_request_header
89 81 user = User.generate!
90 82 token = Token.create!(:user => user, :action => 'api')
91 83 get "/users/current.xml", {}, {'X-Redmine-API-Key' => token.value.to_s}
92 84 assert_response 200
93 85 assert_equal user, User.current
94 86 end
95 87
96 88 def test_api_should_deny_auth_using_wrong_api_key_as_request_header
97 89 user = User.generate!
98 90 token = Token.create!(:user => user, :action => 'feeds') # not the API key
99 91 get "/users/current.xml", {}, {'X-Redmine-API-Key' => token.value.to_s}
100 92 assert_response 401
101 93 assert_equal User.anonymous, User.current
102 94 end
103 95
104 96 def test_api_should_trigger_basic_http_auth_with_basic_authorization_header
105 97 ApplicationController.any_instance.expects(:authenticate_with_http_basic).once
106 98 get '/users/current.xml', {}, credentials('jsmith')
107 99 assert_response 401
108 100 end
109 101
110 102 def test_api_should_not_trigger_basic_http_auth_with_non_basic_authorization_header
111 103 ApplicationController.any_instance.expects(:authenticate_with_http_basic).never
112 104 get '/users/current.xml', {}, 'HTTP_AUTHORIZATION' => 'Digest foo bar'
113 105 assert_response 401
114 106 end
115 107
116 108 def test_invalid_utf8_credentials_should_not_trigger_an_error
117 109 invalid_utf8 = "\x82".force_encoding('UTF-8')
118 110 assert !invalid_utf8.valid_encoding?
119 111 assert_nothing_raised do
120 112 get '/users/current.xml', {}, credentials(invalid_utf8, "foo")
121 113 end
122 114 end
123 115
124 116 def test_api_request_should_not_use_user_session
125 117 log_user('jsmith', 'jsmith')
126 118
127 119 get '/users/current'
128 120 assert_response :success
129 121
130 122 get '/users/current.json'
131 123 assert_response 401
132 124 end
133 125
134 126 def test_api_should_accept_switch_user_header_for_admin_user
135 127 user = User.find(1)
136 128 su = User.find(4)
137 129
138 130 get '/users/current', {}, {'X-Redmine-API-Key' => user.api_key, 'X-Redmine-Switch-User' => su.login}
139 131 assert_response :success
140 132 assert_equal su, assigns(:user)
141 133 assert_equal su, User.current
142 134 end
143 135
144 136 def test_api_should_respond_with_412_when_trying_to_switch_to_a_invalid_user
145 137 get '/users/current', {}, {'X-Redmine-API-Key' => User.find(1).api_key, 'X-Redmine-Switch-User' => 'foobar'}
146 138 assert_response 412
147 139 end
148 140
149 141 def test_api_should_respond_with_412_when_trying_to_switch_to_a_locked_user
150 142 user = User.find(5)
151 143 assert user.locked?
152 144
153 145 get '/users/current', {}, {'X-Redmine-API-Key' => User.find(1).api_key, 'X-Redmine-Switch-User' => user.login}
154 146 assert_response 412
155 147 end
156 148
157 149 def test_api_should_not_accept_switch_user_header_for_non_admin_user
158 150 user = User.find(2)
159 151 su = User.find(4)
160 152
161 153 get '/users/current', {}, {'X-Redmine-API-Key' => user.api_key, 'X-Redmine-Switch-User' => su.login}
162 154 assert_response :success
163 155 assert_equal user, assigns(:user)
164 156 assert_equal user, User.current
165 157 end
166 158 end
@@ -1,46 +1,42
1 1 # Redmine - project management software
2 2 # Copyright (C) 2006-2014 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 18 require File.expand_path('../../../test_helper', __FILE__)
19 19
20 20 class Redmine::ApiTest::CustomFieldsAttributeTest < Redmine::ApiTest::Base
21 21 fixtures :users
22 22
23 def setup
24 Setting.rest_api_enabled = '1'
25 end
26
27 23 def test_integer_custom_fields_should_accept_strings
28 24 field = GroupCustomField.generate!(:field_format => 'int')
29 25
30 26 post '/groups.json', %({"group":{"name":"Foo","custom_field_values":{"#{field.id}":"52"}}}),
31 27 {'CONTENT_TYPE' => 'application/json'}.merge(credentials('admin'))
32 28 assert_response :created
33 29 group = Group.order('id DESC').first
34 30 assert_equal "52", group.custom_field_value(field)
35 31 end
36 32
37 33 def test_integer_custom_fields_should_accept_integers
38 34 field = GroupCustomField.generate!(:field_format => 'int')
39 35
40 36 post '/groups.json', %({"group":{"name":"Foo","custom_field_values":{"#{field.id}":52}}}),
41 37 {'CONTENT_TYPE' => 'application/json'}.merge(credentials('admin'))
42 38 assert_response :created
43 39 group = Group.order('id DESC').first
44 40 assert_equal "52", group.custom_field_value(field)
45 41 end
46 42 end
@@ -1,45 +1,41
1 1 # Redmine - project management software
2 2 # Copyright (C) 2006-2014 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 18 require File.expand_path('../../../test_helper', __FILE__)
19 19
20 20 class Redmine::ApiTest::CustomFieldsTest < Redmine::ApiTest::Base
21 21 fixtures :users, :custom_fields
22 22
23 def setup
24 Setting.rest_api_enabled = '1'
25 end
26
27 23 test "GET /custom_fields.xml should return custom fields" do
28 24 get '/custom_fields.xml', {}, credentials('admin')
29 25 assert_response :success
30 26 assert_equal 'application/xml', response.content_type
31 27
32 28 assert_select 'custom_fields' do
33 29 assert_select 'custom_field' do
34 30 assert_select 'name', :text => 'Database'
35 31 assert_select 'id', :text => '2'
36 32 assert_select 'customized_type', :text => 'issue'
37 33 assert_select 'possible_values[type=array]' do
38 34 assert_select 'possible_value>value', :text => 'PostgreSQL'
39 35 end
40 36 assert_select 'trackers[type=array]'
41 37 assert_select 'roles[type=array]'
42 38 end
43 39 end
44 40 end
45 41 end
@@ -1,38 +1,34
1 1 # Redmine - project management software
2 2 # Copyright (C) 2006-2014 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 18 require File.expand_path('../../../test_helper', __FILE__)
19 19
20 20 class Redmine::ApiTest::EnumerationsTest < Redmine::ApiTest::Base
21 21 fixtures :enumerations
22 22
23 def setup
24 Setting.rest_api_enabled = '1'
25 end
26
27 23 test "GET /enumerations/issue_priorities.xml should return priorities" do
28 24 get '/enumerations/issue_priorities.xml'
29 25 assert_response :success
30 26 assert_equal 'application/xml', response.content_type
31 27 assert_select 'issue_priorities[type=array]' do
32 28 assert_select 'issue_priority' do
33 29 assert_select 'id', :text => '6'
34 30 assert_select 'name', :text => 'High'
35 31 end
36 32 end
37 33 end
38 34 end
@@ -1,200 +1,196
1 1 # Redmine - project management software
2 2 # Copyright (C) 2006-2014 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 18 require File.expand_path('../../../test_helper', __FILE__)
19 19
20 20 class Redmine::ApiTest::GroupsTest < Redmine::ApiTest::Base
21 21 fixtures :users, :groups_users
22 22
23 def setup
24 Setting.rest_api_enabled = '1'
25 end
26
27 23 test "GET /groups.xml should require authentication" do
28 24 get '/groups.xml'
29 25 assert_response 401
30 26 end
31 27
32 28 test "GET /groups.xml should return givable groups" do
33 29 get '/groups.xml', {}, credentials('admin')
34 30 assert_response :success
35 31 assert_equal 'application/xml', response.content_type
36 32
37 33 assert_select 'groups' do
38 34 assert_select 'group', Group.givable.count
39 35 assert_select 'group' do
40 36 assert_select 'name', :text => 'A Team'
41 37 assert_select 'id', :text => '10'
42 38 end
43 39 end
44 40 end
45 41
46 42 test "GET /groups.xml?builtin=1 should return all groups" do
47 43 get '/groups.xml?builtin=1', {}, credentials('admin')
48 44 assert_response :success
49 45 assert_equal 'application/xml', response.content_type
50 46
51 47 assert_select 'groups' do
52 48 assert_select 'group', Group.givable.count + 2
53 49 assert_select 'group' do
54 50 assert_select 'builtin', :text => 'non_member'
55 51 assert_select 'id', :text => '12'
56 52 end
57 53 assert_select 'group' do
58 54 assert_select 'builtin', :text => 'anonymous'
59 55 assert_select 'id', :text => '13'
60 56 end
61 57 end
62 58 end
63 59
64 60 test "GET /groups.json should require authentication" do
65 61 get '/groups.json'
66 62 assert_response 401
67 63 end
68 64
69 65 test "GET /groups.json should return groups" do
70 66 get '/groups.json', {}, credentials('admin')
71 67 assert_response :success
72 68 assert_equal 'application/json', response.content_type
73 69
74 70 json = MultiJson.load(response.body)
75 71 groups = json['groups']
76 72 assert_kind_of Array, groups
77 73 group = groups.detect {|g| g['name'] == 'A Team'}
78 74 assert_not_nil group
79 75 assert_equal({'id' => 10, 'name' => 'A Team'}, group)
80 76 end
81 77
82 78 test "GET /groups/:id.xml should return the group" do
83 79 get '/groups/10.xml', {}, credentials('admin')
84 80 assert_response :success
85 81 assert_equal 'application/xml', response.content_type
86 82
87 83 assert_select 'group' do
88 84 assert_select 'name', :text => 'A Team'
89 85 assert_select 'id', :text => '10'
90 86 end
91 87 end
92 88
93 89 test "GET /groups/:id.xml should return the builtin group" do
94 90 get '/groups/12.xml', {}, credentials('admin')
95 91 assert_response :success
96 92 assert_equal 'application/xml', response.content_type
97 93
98 94 assert_select 'group' do
99 95 assert_select 'builtin', :text => 'non_member'
100 96 assert_select 'id', :text => '12'
101 97 end
102 98 end
103 99
104 100 test "GET /groups/:id.xml should include users if requested" do
105 101 get '/groups/10.xml?include=users', {}, credentials('admin')
106 102 assert_response :success
107 103 assert_equal 'application/xml', response.content_type
108 104
109 105 assert_select 'group' do
110 106 assert_select 'users' do
111 107 assert_select 'user', Group.find(10).users.count
112 108 assert_select 'user[id=8]'
113 109 end
114 110 end
115 111 end
116 112
117 113 test "GET /groups/:id.xml include memberships if requested" do
118 114 get '/groups/10.xml?include=memberships', {}, credentials('admin')
119 115 assert_response :success
120 116 assert_equal 'application/xml', response.content_type
121 117
122 118 assert_select 'group' do
123 119 assert_select 'memberships'
124 120 end
125 121 end
126 122
127 123 test "POST /groups.xml with valid parameters should create the group" do
128 124 assert_difference('Group.count') do
129 125 post '/groups.xml', {:group => {:name => 'Test', :user_ids => [2, 3]}}, credentials('admin')
130 126 assert_response :created
131 127 assert_equal 'application/xml', response.content_type
132 128 end
133 129
134 130 group = Group.order('id DESC').first
135 131 assert_equal 'Test', group.name
136 132 assert_equal [2, 3], group.users.map(&:id).sort
137 133
138 134 assert_select 'group' do
139 135 assert_select 'name', :text => 'Test'
140 136 end
141 137 end
142 138
143 139 test "POST /groups.xml with invalid parameters should return errors" do
144 140 assert_no_difference('Group.count') do
145 141 post '/groups.xml', {:group => {:name => ''}}, credentials('admin')
146 142 end
147 143 assert_response :unprocessable_entity
148 144 assert_equal 'application/xml', response.content_type
149 145
150 146 assert_select 'errors' do
151 147 assert_select 'error', :text => /Name can't be blank/
152 148 end
153 149 end
154 150
155 151 test "PUT /groups/:id.xml with valid parameters should update the group" do
156 152 put '/groups/10.xml', {:group => {:name => 'New name', :user_ids => [2, 3]}}, credentials('admin')
157 153 assert_response :ok
158 154 assert_equal '', @response.body
159 155
160 156 group = Group.find(10)
161 157 assert_equal 'New name', group.name
162 158 assert_equal [2, 3], group.users.map(&:id).sort
163 159 end
164 160
165 161 test "PUT /groups/:id.xml with invalid parameters should return errors" do
166 162 put '/groups/10.xml', {:group => {:name => ''}}, credentials('admin')
167 163 assert_response :unprocessable_entity
168 164 assert_equal 'application/xml', response.content_type
169 165
170 166 assert_select 'errors' do
171 167 assert_select 'error', :text => /Name can't be blank/
172 168 end
173 169 end
174 170
175 171 test "DELETE /groups/:id.xml should delete the group" do
176 172 assert_difference 'Group.count', -1 do
177 173 delete '/groups/10.xml', {}, credentials('admin')
178 174 assert_response :ok
179 175 assert_equal '', @response.body
180 176 end
181 177 end
182 178
183 179 test "POST /groups/:id/users.xml should add user to the group" do
184 180 assert_difference 'Group.find(10).users.count' do
185 181 post '/groups/10/users.xml', {:user_id => 5}, credentials('admin')
186 182 assert_response :ok
187 183 assert_equal '', @response.body
188 184 end
189 185 assert_include User.find(5), Group.find(10).users
190 186 end
191 187
192 188 test "DELETE /groups/:id/users/:user_id.xml should remove user from the group" do
193 189 assert_difference 'Group.find(10).users.count', -1 do
194 190 delete '/groups/10/users/8.xml', {}, credentials('admin')
195 191 assert_response :ok
196 192 assert_equal '', @response.body
197 193 end
198 194 assert_not_include User.find(8), Group.find(10).users
199 195 end
200 196 end
@@ -1,108 +1,104
1 1 # Redmine - project management software
2 2 # Copyright (C) 2006-2014 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 18 require File.expand_path('../../../test_helper', __FILE__)
19 19
20 20 class Redmine::ApiTest::IssueCategoriesTest < Redmine::ApiTest::Base
21 21 fixtures :projects, :users, :issue_categories, :issues,
22 22 :roles,
23 23 :member_roles,
24 24 :members,
25 25 :enabled_modules
26 26
27 def setup
28 Setting.rest_api_enabled = '1'
29 end
30
31 27 test "GET /projects/:project_id/issue_categories.xml should return the issue categories" do
32 28 get '/projects/1/issue_categories.xml', {}, credentials('jsmith')
33 29 assert_response :success
34 30 assert_equal 'application/xml', @response.content_type
35 31 assert_select 'issue_categories issue_category id', :text => '2'
36 32 end
37 33
38 34 test "GET /issue_categories/:id.xml should return the issue category" do
39 35 get '/issue_categories/2.xml', {}, credentials('jsmith')
40 36 assert_response :success
41 37 assert_equal 'application/xml', @response.content_type
42 38 assert_select 'issue_category id', :text => '2'
43 39 end
44 40
45 41 test "POST /projects/:project_id/issue_categories.xml should return create issue category" do
46 42 assert_difference 'IssueCategory.count' do
47 43 post '/projects/1/issue_categories.xml', {:issue_category => {:name => 'API'}}, credentials('jsmith')
48 44 end
49 45 assert_response :created
50 46 assert_equal 'application/xml', @response.content_type
51 47
52 48 category = IssueCategory.order('id DESC').first
53 49 assert_equal 'API', category.name
54 50 assert_equal 1, category.project_id
55 51 end
56 52
57 53 test "POST /projects/:project_id/issue_categories.xml with invalid parameters should return errors" do
58 54 assert_no_difference 'IssueCategory.count' do
59 55 post '/projects/1/issue_categories.xml', {:issue_category => {:name => ''}}, credentials('jsmith')
60 56 end
61 57 assert_response :unprocessable_entity
62 58 assert_equal 'application/xml', @response.content_type
63 59
64 60 assert_select 'errors error', :text => "Name can't be blank"
65 61 end
66 62
67 63 test "PUT /issue_categories/:id.xml with valid parameters should update the issue category" do
68 64 assert_no_difference 'IssueCategory.count' do
69 65 put '/issue_categories/2.xml', {:issue_category => {:name => 'API Update'}}, credentials('jsmith')
70 66 end
71 67 assert_response :ok
72 68 assert_equal '', @response.body
73 69 assert_equal 'API Update', IssueCategory.find(2).name
74 70 end
75 71
76 72 test "PUT /issue_categories/:id.xml with invalid parameters should return errors" do
77 73 assert_no_difference 'IssueCategory.count' do
78 74 put '/issue_categories/2.xml', {:issue_category => {:name => ''}}, credentials('jsmith')
79 75 end
80 76 assert_response :unprocessable_entity
81 77 assert_equal 'application/xml', @response.content_type
82 78
83 79 assert_select 'errors error', :text => "Name can't be blank"
84 80 end
85 81
86 82 test "DELETE /issue_categories/:id.xml should destroy the issue category" do
87 83 assert_difference 'IssueCategory.count', -1 do
88 84 delete '/issue_categories/1.xml', {}, credentials('jsmith')
89 85 end
90 86 assert_response :ok
91 87 assert_equal '', @response.body
92 88 assert_nil IssueCategory.find_by_id(1)
93 89 end
94 90
95 91 test "DELETE /issue_categories/:id.xml should reassign issues with :reassign_to_id param" do
96 92 issue_count = Issue.where(:category_id => 1).count
97 93 assert issue_count > 0
98 94
99 95 assert_difference 'IssueCategory.count', -1 do
100 96 assert_difference 'Issue.where(:category_id => 2).count', 3 do
101 97 delete '/issue_categories/1.xml', {:reassign_to_id => 2}, credentials('jsmith')
102 98 end
103 99 end
104 100 assert_response :ok
105 101 assert_equal '', @response.body
106 102 assert_nil IssueCategory.find_by_id(1)
107 103 end
108 104 end
@@ -1,84 +1,80
1 1 # Redmine - project management software
2 2 # Copyright (C) 2006-2014 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 18 require File.expand_path('../../../test_helper', __FILE__)
19 19
20 20 class Redmine::ApiTest::IssueRelationsTest < Redmine::ApiTest::Base
21 21 fixtures :projects, :trackers, :issue_statuses, :issues,
22 22 :enumerations, :users, :issue_categories,
23 23 :projects_trackers,
24 24 :roles,
25 25 :member_roles,
26 26 :members,
27 27 :enabled_modules,
28 28 :issue_relations
29 29
30 def setup
31 Setting.rest_api_enabled = '1'
32 end
33
34 30 test "GET /issues/:issue_id/relations.xml should return issue relations" do
35 31 get '/issues/9/relations.xml', {}, credentials('jsmith')
36 32
37 33 assert_response :success
38 34 assert_equal 'application/xml', @response.content_type
39 35
40 36 assert_select 'relations[type=array] relation id', :text => '1'
41 37 end
42 38
43 39 test "POST /issues/:issue_id/relations.xml should create the relation" do
44 40 assert_difference('IssueRelation.count') do
45 41 post '/issues/2/relations.xml', {:relation => {:issue_to_id => 7, :relation_type => 'relates'}}, credentials('jsmith')
46 42 end
47 43
48 44 relation = IssueRelation.order('id DESC').first
49 45 assert_equal 2, relation.issue_from_id
50 46 assert_equal 7, relation.issue_to_id
51 47 assert_equal 'relates', relation.relation_type
52 48
53 49 assert_response :created
54 50 assert_equal 'application/xml', @response.content_type
55 51 assert_select 'relation id', :text => relation.id.to_s
56 52 end
57 53
58 54 test "POST /issues/:issue_id/relations.xml with failure should return errors" do
59 55 assert_no_difference('IssueRelation.count') do
60 56 post '/issues/2/relations.xml', {:relation => {:issue_to_id => 7, :relation_type => 'foo'}}, credentials('jsmith')
61 57 end
62 58
63 59 assert_response :unprocessable_entity
64 60 assert_select 'errors error', :text => /relation_type is not included in the list/
65 61 end
66 62
67 63 test "GET /relations/:id.xml should return the relation" do
68 64 get '/relations/2.xml', {}, credentials('jsmith')
69 65
70 66 assert_response :success
71 67 assert_equal 'application/xml', @response.content_type
72 68 assert_select 'relation id', :text => '2'
73 69 end
74 70
75 71 test "DELETE /relations/:id.xml should delete the relation" do
76 72 assert_difference('IssueRelation.count', -1) do
77 73 delete '/relations/2.xml', {}, credentials('jsmith')
78 74 end
79 75
80 76 assert_response :ok
81 77 assert_equal '', @response.body
82 78 assert_nil IssueRelation.find_by_id(2)
83 79 end
84 80 end
@@ -1,36 +1,32
1 1 # Redmine - project management software
2 2 # Copyright (C) 2006-2014 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 18 require File.expand_path('../../../test_helper', __FILE__)
19 19
20 20 class Redmine::ApiTest::IssueStatusesTest < Redmine::ApiTest::Base
21 21 fixtures :issue_statuses
22 22
23 def setup
24 Setting.rest_api_enabled = '1'
25 end
26
27 23 test "GET /issue_statuses.xml should return issue statuses" do
28 24 get '/issue_statuses.xml'
29 25
30 26 assert_response :success
31 27 assert_equal 'application/xml', @response.content_type
32 28 assert_select 'issue_statuses[type=array] issue_status id:content(2)' do
33 29 assert_select '~ name', :text => 'Assigned'
34 30 end
35 31 end
36 32 end
@@ -1,594 +1,590
1 1 # Redmine - project management software
2 2 # Copyright (C) 2006-2014 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 18 require File.expand_path('../../../test_helper', __FILE__)
19 19
20 20 class Redmine::ApiTest::IssuesTest < Redmine::ApiTest::Base
21 21 fixtures :projects,
22 22 :users,
23 23 :roles,
24 24 :members,
25 25 :member_roles,
26 26 :issues,
27 27 :issue_statuses,
28 28 :issue_relations,
29 29 :versions,
30 30 :trackers,
31 31 :projects_trackers,
32 32 :issue_categories,
33 33 :enabled_modules,
34 34 :enumerations,
35 35 :attachments,
36 36 :workflows,
37 37 :custom_fields,
38 38 :custom_values,
39 39 :custom_fields_projects,
40 40 :custom_fields_trackers,
41 41 :time_entries,
42 42 :journals,
43 43 :journal_details,
44 44 :queries,
45 45 :attachments
46 46
47 def setup
48 Setting.rest_api_enabled = '1'
49 end
50
51 47 test "GET /issues.xml should contain metadata" do
52 48 get '/issues.xml'
53 49 assert_select 'issues[type=array][total_count=?][limit="25"][offset="0"]',
54 50 assigns(:issue_count).to_s
55 51 end
56 52
57 53 test "GET /issues.xml with nometa param should not contain metadata" do
58 54 get '/issues.xml?nometa=1'
59 55 assert_select 'issues[type=array]:not([total_count]):not([limit]):not([offset])'
60 56 end
61 57
62 58 test "GET /issues.xml with nometa header should not contain metadata" do
63 59 get '/issues.xml', {}, {'X-Redmine-Nometa' => '1'}
64 60 assert_select 'issues[type=array]:not([total_count]):not([limit]):not([offset])'
65 61 end
66 62
67 63 test "GET /issues.xml with offset and limit" do
68 64 get '/issues.xml?offset=2&limit=3'
69 65
70 66 assert_equal 3, assigns(:limit)
71 67 assert_equal 2, assigns(:offset)
72 68 assert_select 'issues issue', 3
73 69 end
74 70
75 71 test "GET /issues.xml with relations" do
76 72 get '/issues.xml?include=relations'
77 73
78 74 assert_response :success
79 75 assert_equal 'application/xml', @response.content_type
80 76
81 77 assert_select 'issue id:content(3)' do
82 78 assert_select '~ relations relation', 1
83 79 assert_select '~ relations relation[id="2"][issue_id="2"][issue_to_id="3"][relation_type=relates]'
84 80 end
85 81
86 82 assert_select 'issue id:content(1)' do
87 83 assert_select '~ relations'
88 84 assert_select '~ relations relation', 0
89 85 end
90 86 end
91 87
92 88 test "GET /issues.xml with invalid query params" do
93 89 get '/issues.xml', {:f => ['start_date'], :op => {:start_date => '='}}
94 90
95 91 assert_response :unprocessable_entity
96 92 assert_equal 'application/xml', @response.content_type
97 93 assert_select 'errors error', :text => "Start date can't be blank"
98 94 end
99 95
100 96 test "GET /issues.xml with custom field filter" do
101 97 get '/issues.xml',
102 98 {:set_filter => 1, :f => ['cf_1'], :op => {:cf_1 => '='}, :v => {:cf_1 => ['MySQL']}}
103 99
104 100 expected_ids = Issue.visible.
105 101 joins(:custom_values).
106 102 where(:custom_values => {:custom_field_id => 1, :value => 'MySQL'}).map(&:id)
107 103 assert expected_ids.any?
108 104
109 105 assert_select 'issues > issue > id', :count => expected_ids.count do |ids|
110 106 ids.each { |id| assert expected_ids.delete(id.children.first.content.to_i) }
111 107 end
112 108 end
113 109
114 110 test "GET /issues.xml with custom field filter (shorthand method)" do
115 111 get '/issues.xml', {:cf_1 => 'MySQL'}
116 112
117 113 expected_ids = Issue.visible.
118 114 joins(:custom_values).
119 115 where(:custom_values => {:custom_field_id => 1, :value => 'MySQL'}).map(&:id)
120 116 assert expected_ids.any?
121 117
122 118 assert_select 'issues > issue > id', :count => expected_ids.count do |ids|
123 119 ids.each { |id| assert expected_ids.delete(id.children.first.content.to_i) }
124 120 end
125 121 end
126 122
127 123 def test_index_should_include_issue_attributes
128 124 get '/issues.xml'
129 125 assert_select 'issues>issue>is_private', :text => 'false'
130 126 end
131 127
132 128 def test_index_should_allow_timestamp_filtering
133 129 Issue.delete_all
134 130 Issue.generate!(:subject => '1').update_column(:updated_on, Time.parse("2014-01-02T10:25:00Z"))
135 131 Issue.generate!(:subject => '2').update_column(:updated_on, Time.parse("2014-01-02T12:13:00Z"))
136 132
137 133 get '/issues.xml',
138 134 {:set_filter => 1, :f => ['updated_on'], :op => {:updated_on => '<='},
139 135 :v => {:updated_on => ['2014-01-02T12:00:00Z']}}
140 136 assert_select 'issues>issue', :count => 1
141 137 assert_select 'issues>issue>subject', :text => '1'
142 138
143 139 get '/issues.xml',
144 140 {:set_filter => 1, :f => ['updated_on'], :op => {:updated_on => '>='},
145 141 :v => {:updated_on => ['2014-01-02T12:00:00Z']}}
146 142 assert_select 'issues>issue', :count => 1
147 143 assert_select 'issues>issue>subject', :text => '2'
148 144
149 145 get '/issues.xml',
150 146 {:set_filter => 1, :f => ['updated_on'], :op => {:updated_on => '>='},
151 147 :v => {:updated_on => ['2014-01-02T08:00:00Z']}}
152 148 assert_select 'issues>issue', :count => 2
153 149 end
154 150
155 151 test "GET /issues.xml with filter" do
156 152 get '/issues.xml?status_id=5'
157 153
158 154 expected_ids = Issue.visible.where(:status_id => 5).map(&:id)
159 155 assert expected_ids.any?
160 156
161 157 assert_select 'issues > issue > id', :count => expected_ids.count do |ids|
162 158 ids.each { |id| assert expected_ids.delete(id.children.first.content.to_i) }
163 159 end
164 160 end
165 161
166 162 test "GET /issues.json with filter" do
167 163 get '/issues.json?status_id=5'
168 164
169 165 json = ActiveSupport::JSON.decode(response.body)
170 166 status_ids_used = json['issues'].collect {|j| j['status']['id'] }
171 167 assert_equal 3, status_ids_used.length
172 168 assert status_ids_used.all? {|id| id == 5 }
173 169 end
174 170
175 171 test "GET /issues/:id.xml with journals" do
176 172 get '/issues/1.xml?include=journals'
177 173
178 174 assert_select 'issue journals[type=array]' do
179 175 assert_select 'journal[id="1"]' do
180 176 assert_select 'details[type=array]' do
181 177 assert_select 'detail[name=status_id]' do
182 178 assert_select 'old_value', :text => '1'
183 179 assert_select 'new_value', :text => '2'
184 180 end
185 181 end
186 182 end
187 183 end
188 184 end
189 185
190 186 test "GET /issues/:id.xml with custom fields" do
191 187 get '/issues/3.xml'
192 188
193 189 assert_select 'issue custom_fields[type=array]' do
194 190 assert_select 'custom_field[id="1"]' do
195 191 assert_select 'value', :text => 'MySQL'
196 192 end
197 193 end
198 194 assert_nothing_raised do
199 195 Hash.from_xml(response.body).to_xml
200 196 end
201 197 end
202 198
203 199 test "GET /issues/:id.xml with multi custom fields" do
204 200 field = CustomField.find(1)
205 201 field.update_attribute :multiple, true
206 202 issue = Issue.find(3)
207 203 issue.custom_field_values = {1 => ['MySQL', 'Oracle']}
208 204 issue.save!
209 205
210 206 get '/issues/3.xml'
211 207 assert_response :success
212 208
213 209 assert_select 'issue custom_fields[type=array]' do
214 210 assert_select 'custom_field[id="1"]' do
215 211 assert_select 'value[type=array] value', 2
216 212 end
217 213 end
218 214 xml = Hash.from_xml(response.body)
219 215 custom_fields = xml['issue']['custom_fields']
220 216 assert_kind_of Array, custom_fields
221 217 field = custom_fields.detect {|f| f['id'] == '1'}
222 218 assert_kind_of Hash, field
223 219 assert_equal ['MySQL', 'Oracle'], field['value'].sort
224 220 end
225 221
226 222 test "GET /issues/:id.json with multi custom fields" do
227 223 field = CustomField.find(1)
228 224 field.update_attribute :multiple, true
229 225 issue = Issue.find(3)
230 226 issue.custom_field_values = {1 => ['MySQL', 'Oracle']}
231 227 issue.save!
232 228
233 229 get '/issues/3.json'
234 230 assert_response :success
235 231
236 232 json = ActiveSupport::JSON.decode(response.body)
237 233 custom_fields = json['issue']['custom_fields']
238 234 assert_kind_of Array, custom_fields
239 235 field = custom_fields.detect {|f| f['id'] == 1}
240 236 assert_kind_of Hash, field
241 237 assert_equal ['MySQL', 'Oracle'], field['value'].sort
242 238 end
243 239
244 240 test "GET /issues/:id.xml with empty value for multi custom field" do
245 241 field = CustomField.find(1)
246 242 field.update_attribute :multiple, true
247 243 issue = Issue.find(3)
248 244 issue.custom_field_values = {1 => ['']}
249 245 issue.save!
250 246
251 247 get '/issues/3.xml'
252 248
253 249 assert_select 'issue custom_fields[type=array]' do
254 250 assert_select 'custom_field[id="1"]' do
255 251 assert_select 'value[type=array]:empty'
256 252 end
257 253 end
258 254 xml = Hash.from_xml(response.body)
259 255 custom_fields = xml['issue']['custom_fields']
260 256 assert_kind_of Array, custom_fields
261 257 field = custom_fields.detect {|f| f['id'] == '1'}
262 258 assert_kind_of Hash, field
263 259 assert_equal [], field['value']
264 260 end
265 261
266 262 test "GET /issues/:id.json with empty value for multi custom field" do
267 263 field = CustomField.find(1)
268 264 field.update_attribute :multiple, true
269 265 issue = Issue.find(3)
270 266 issue.custom_field_values = {1 => ['']}
271 267 issue.save!
272 268
273 269 get '/issues/3.json'
274 270 assert_response :success
275 271 json = ActiveSupport::JSON.decode(response.body)
276 272 custom_fields = json['issue']['custom_fields']
277 273 assert_kind_of Array, custom_fields
278 274 field = custom_fields.detect {|f| f['id'] == 1}
279 275 assert_kind_of Hash, field
280 276 assert_equal [], field['value'].sort
281 277 end
282 278
283 279 test "GET /issues/:id.xml with attachments" do
284 280 get '/issues/3.xml?include=attachments'
285 281
286 282 assert_select 'issue attachments[type=array]' do
287 283 assert_select 'attachment', 5
288 284 assert_select 'attachment id:content(4)' do
289 285 assert_select '~ filename', :text => 'source.rb'
290 286 assert_select '~ content_url', :text => 'http://www.example.com/attachments/download/4/source.rb'
291 287 end
292 288 end
293 289 end
294 290
295 291 test "GET /issues/:id.xml with subtasks" do
296 292 issue = Issue.generate_with_descendants!(:project_id => 1)
297 293 get "/issues/#{issue.id}.xml?include=children"
298 294
299 295 assert_select 'issue children[type=array]' do
300 296 assert_select 'issue', 2
301 297 assert_select 'issue children', 1
302 298 end
303 299 end
304 300
305 301 test "GET /issues/:id.json with subtasks" do
306 302 issue = Issue.generate_with_descendants!(:project_id => 1)
307 303 get "/issues/#{issue.id}.json?include=children"
308 304
309 305 json = ActiveSupport::JSON.decode(response.body)
310 306 assert_equal 2, json['issue']['children'].size
311 307 assert_equal 1, json['issue']['children'].select {|child| child.key?('children')}.size
312 308 end
313 309
314 310 def test_show_should_include_issue_attributes
315 311 get '/issues/1.xml'
316 312 assert_select 'issue>is_private', :text => 'false'
317 313 end
318 314
319 315 test "GET /issues/:id.xml?include=watchers should include watchers" do
320 316 Watcher.create!(:user_id => 3, :watchable => Issue.find(1))
321 317
322 318 get '/issues/1.xml?include=watchers', {}, credentials('jsmith')
323 319
324 320 assert_response :ok
325 321 assert_equal 'application/xml', response.content_type
326 322 assert_select 'issue' do
327 323 assert_select 'watchers', Issue.find(1).watchers.count
328 324 assert_select 'watchers' do
329 325 assert_select 'user[id=3]'
330 326 end
331 327 end
332 328 end
333 329
334 330 test "POST /issues.xml should create an issue with the attributes" do
335 331 assert_difference('Issue.count') do
336 332 post '/issues.xml',
337 333 {:issue => {:project_id => 1, :subject => 'API test',
338 334 :tracker_id => 2, :status_id => 3}}, credentials('jsmith')
339 335 end
340 336 issue = Issue.order('id DESC').first
341 337 assert_equal 1, issue.project_id
342 338 assert_equal 2, issue.tracker_id
343 339 assert_equal 3, issue.status_id
344 340 assert_equal 'API test', issue.subject
345 341
346 342 assert_response :created
347 343 assert_equal 'application/xml', @response.content_type
348 344 assert_select 'issue > id', :text => issue.id.to_s
349 345 end
350 346
351 347 test "POST /issues.xml with watcher_user_ids should create issue with watchers" do
352 348 assert_difference('Issue.count') do
353 349 post '/issues.xml',
354 350 {:issue => {:project_id => 1, :subject => 'Watchers',
355 351 :tracker_id => 2, :status_id => 3, :watcher_user_ids => [3, 1]}}, credentials('jsmith')
356 352 assert_response :created
357 353 end
358 354 issue = Issue.order('id desc').first
359 355 assert_equal 2, issue.watchers.size
360 356 assert_equal [1, 3], issue.watcher_user_ids.sort
361 357 end
362 358
363 359 test "POST /issues.xml with failure should return errors" do
364 360 assert_no_difference('Issue.count') do
365 361 post '/issues.xml', {:issue => {:project_id => 1}}, credentials('jsmith')
366 362 end
367 363
368 364 assert_select 'errors error', :text => "Subject can't be blank"
369 365 end
370 366
371 367 test "POST /issues.json should create an issue with the attributes" do
372 368 assert_difference('Issue.count') do
373 369 post '/issues.json',
374 370 {:issue => {:project_id => 1, :subject => 'API test',
375 371 :tracker_id => 2, :status_id => 3}},
376 372 credentials('jsmith')
377 373 end
378 374
379 375 issue = Issue.order('id DESC').first
380 376 assert_equal 1, issue.project_id
381 377 assert_equal 2, issue.tracker_id
382 378 assert_equal 3, issue.status_id
383 379 assert_equal 'API test', issue.subject
384 380 end
385 381
386 382 test "POST /issues.json with failure should return errors" do
387 383 assert_no_difference('Issue.count') do
388 384 post '/issues.json', {:issue => {:project_id => 1}}, credentials('jsmith')
389 385 end
390 386
391 387 json = ActiveSupport::JSON.decode(response.body)
392 388 assert json['errors'].include?("Subject can't be blank")
393 389 end
394 390
395 391 test "PUT /issues/:id.xml" do
396 392 assert_difference('Journal.count') do
397 393 put '/issues/6.xml',
398 394 {:issue => {:subject => 'API update', :notes => 'A new note'}},
399 395 credentials('jsmith')
400 396 end
401 397
402 398 issue = Issue.find(6)
403 399 assert_equal "API update", issue.subject
404 400 journal = Journal.last
405 401 assert_equal "A new note", journal.notes
406 402 end
407 403
408 404 test "PUT /issues/:id.xml with custom fields" do
409 405 put '/issues/3.xml',
410 406 {:issue => {:custom_fields => [
411 407 {'id' => '1', 'value' => 'PostgreSQL' },
412 408 {'id' => '2', 'value' => '150'}
413 409 ]}},
414 410 credentials('jsmith')
415 411
416 412 issue = Issue.find(3)
417 413 assert_equal '150', issue.custom_value_for(2).value
418 414 assert_equal 'PostgreSQL', issue.custom_value_for(1).value
419 415 end
420 416
421 417 test "PUT /issues/:id.xml with multi custom fields" do
422 418 field = CustomField.find(1)
423 419 field.update_attribute :multiple, true
424 420
425 421 put '/issues/3.xml',
426 422 {:issue => {:custom_fields => [
427 423 {'id' => '1', 'value' => ['MySQL', 'PostgreSQL'] },
428 424 {'id' => '2', 'value' => '150'}
429 425 ]}},
430 426 credentials('jsmith')
431 427
432 428 issue = Issue.find(3)
433 429 assert_equal '150', issue.custom_value_for(2).value
434 430 assert_equal ['MySQL', 'PostgreSQL'], issue.custom_field_value(1).sort
435 431 end
436 432
437 433 test "PUT /issues/:id.xml with project change" do
438 434 put '/issues/3.xml',
439 435 {:issue => {:project_id => 2, :subject => 'Project changed'}},
440 436 credentials('jsmith')
441 437
442 438 issue = Issue.find(3)
443 439 assert_equal 2, issue.project_id
444 440 assert_equal 'Project changed', issue.subject
445 441 end
446 442
447 443 test "PUT /issues/:id.xml with failed update" do
448 444 put '/issues/6.xml', {:issue => {:subject => ''}}, credentials('jsmith')
449 445
450 446 assert_response :unprocessable_entity
451 447 assert_select 'errors error', :text => "Subject can't be blank"
452 448 end
453 449
454 450 test "PUT /issues/:id.json" do
455 451 assert_difference('Journal.count') do
456 452 put '/issues/6.json',
457 453 {:issue => {:subject => 'API update', :notes => 'A new note'}},
458 454 credentials('jsmith')
459 455
460 456 assert_response :ok
461 457 assert_equal '', response.body
462 458 end
463 459
464 460 issue = Issue.find(6)
465 461 assert_equal "API update", issue.subject
466 462 journal = Journal.last
467 463 assert_equal "A new note", journal.notes
468 464 end
469 465
470 466 test "PUT /issues/:id.json with failed update" do
471 467 put '/issues/6.json', {:issue => {:subject => ''}}, credentials('jsmith')
472 468
473 469 assert_response :unprocessable_entity
474 470 json = ActiveSupport::JSON.decode(response.body)
475 471 assert json['errors'].include?("Subject can't be blank")
476 472 end
477 473
478 474 test "DELETE /issues/:id.xml" do
479 475 assert_difference('Issue.count', -1) do
480 476 delete '/issues/6.xml', {}, credentials('jsmith')
481 477
482 478 assert_response :ok
483 479 assert_equal '', response.body
484 480 end
485 481 assert_nil Issue.find_by_id(6)
486 482 end
487 483
488 484 test "DELETE /issues/:id.json" do
489 485 assert_difference('Issue.count', -1) do
490 486 delete '/issues/6.json', {}, credentials('jsmith')
491 487
492 488 assert_response :ok
493 489 assert_equal '', response.body
494 490 end
495 491 assert_nil Issue.find_by_id(6)
496 492 end
497 493
498 494 test "POST /issues/:id/watchers.xml should add watcher" do
499 495 assert_difference 'Watcher.count' do
500 496 post '/issues/1/watchers.xml', {:user_id => 3}, credentials('jsmith')
501 497
502 498 assert_response :ok
503 499 assert_equal '', response.body
504 500 end
505 501 watcher = Watcher.order('id desc').first
506 502 assert_equal Issue.find(1), watcher.watchable
507 503 assert_equal User.find(3), watcher.user
508 504 end
509 505
510 506 test "DELETE /issues/:id/watchers/:user_id.xml should remove watcher" do
511 507 Watcher.create!(:user_id => 3, :watchable => Issue.find(1))
512 508
513 509 assert_difference 'Watcher.count', -1 do
514 510 delete '/issues/1/watchers/3.xml', {}, credentials('jsmith')
515 511
516 512 assert_response :ok
517 513 assert_equal '', response.body
518 514 end
519 515 assert_equal false, Issue.find(1).watched_by?(User.find(3))
520 516 end
521 517
522 518 def test_create_issue_with_uploaded_file
523 519 set_tmp_attachments_directory
524 520 # upload the file
525 521 assert_difference 'Attachment.count' do
526 522 post '/uploads.xml', 'test_create_with_upload',
527 523 {"CONTENT_TYPE" => 'application/octet-stream'}.merge(credentials('jsmith'))
528 524 assert_response :created
529 525 end
530 526 xml = Hash.from_xml(response.body)
531 527 token = xml['upload']['token']
532 528 attachment = Attachment.order('id DESC').first
533 529
534 530 # create the issue with the upload's token
535 531 assert_difference 'Issue.count' do
536 532 post '/issues.xml',
537 533 {:issue => {:project_id => 1, :subject => 'Uploaded file',
538 534 :uploads => [{:token => token, :filename => 'test.txt',
539 535 :content_type => 'text/plain'}]}},
540 536 credentials('jsmith')
541 537 assert_response :created
542 538 end
543 539 issue = Issue.order('id DESC').first
544 540 assert_equal 1, issue.attachments.count
545 541 assert_equal attachment, issue.attachments.first
546 542
547 543 attachment.reload
548 544 assert_equal 'test.txt', attachment.filename
549 545 assert_equal 'text/plain', attachment.content_type
550 546 assert_equal 'test_create_with_upload'.size, attachment.filesize
551 547 assert_equal 2, attachment.author_id
552 548
553 549 # get the issue with its attachments
554 550 get "/issues/#{issue.id}.xml", :include => 'attachments'
555 551 assert_response :success
556 552 xml = Hash.from_xml(response.body)
557 553 attachments = xml['issue']['attachments']
558 554 assert_kind_of Array, attachments
559 555 assert_equal 1, attachments.size
560 556 url = attachments.first['content_url']
561 557 assert_not_nil url
562 558
563 559 # download the attachment
564 560 get url
565 561 assert_response :success
566 562 end
567 563
568 564 def test_update_issue_with_uploaded_file
569 565 set_tmp_attachments_directory
570 566 # upload the file
571 567 assert_difference 'Attachment.count' do
572 568 post '/uploads.xml', 'test_upload_with_upload',
573 569 {"CONTENT_TYPE" => 'application/octet-stream'}.merge(credentials('jsmith'))
574 570 assert_response :created
575 571 end
576 572 xml = Hash.from_xml(response.body)
577 573 token = xml['upload']['token']
578 574 attachment = Attachment.order('id DESC').first
579 575
580 576 # update the issue with the upload's token
581 577 assert_difference 'Journal.count' do
582 578 put '/issues/1.xml',
583 579 {:issue => {:notes => 'Attachment added',
584 580 :uploads => [{:token => token, :filename => 'test.txt',
585 581 :content_type => 'text/plain'}]}},
586 582 credentials('jsmith')
587 583 assert_response :ok
588 584 assert_equal '', @response.body
589 585 end
590 586
591 587 issue = Issue.find(1)
592 588 assert_include attachment, issue.attachments
593 589 end
594 590 end
@@ -1,162 +1,158
1 1 # Redmine - project management software
2 2 # Copyright (C) 2006-2014 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 18 require File.expand_path('../../../test_helper', __FILE__)
19 19
20 20 class Redmine::ApiTest::MembershipsTest < Redmine::ApiTest::Base
21 21 fixtures :projects, :users, :roles, :members, :member_roles
22 22
23 def setup
24 Setting.rest_api_enabled = '1'
25 end
26
27 23 test "GET /projects/:project_id/memberships.xml should return memberships" do
28 24 get '/projects/1/memberships.xml', {}, credentials('jsmith')
29 25
30 26 assert_response :success
31 27 assert_equal 'application/xml', @response.content_type
32 28 assert_select 'memberships[type=array] membership id:content(2)' do
33 29 assert_select '~ user[id=3][name=Dave Lopper]'
34 30 assert_select '~ roles role[id=2][name=Developer]'
35 31 end
36 32 end
37 33
38 34 test "GET /projects/:project_id/memberships.json should return memberships" do
39 35 get '/projects/1/memberships.json', {}, credentials('jsmith')
40 36
41 37 assert_response :success
42 38 assert_equal 'application/json', @response.content_type
43 39 json = ActiveSupport::JSON.decode(response.body)
44 40 assert_equal({
45 41 "memberships" =>
46 42 [{"id"=>1,
47 43 "project" => {"name"=>"eCookbook", "id"=>1},
48 44 "roles" => [{"name"=>"Manager", "id"=>1}],
49 45 "user" => {"name"=>"John Smith", "id"=>2}},
50 46 {"id"=>2,
51 47 "project" => {"name"=>"eCookbook", "id"=>1},
52 48 "roles" => [{"name"=>"Developer", "id"=>2}],
53 49 "user" => {"name"=>"Dave Lopper", "id"=>3}}],
54 50 "limit" => 25,
55 51 "total_count" => 2,
56 52 "offset" => 0},
57 53 json)
58 54 end
59 55
60 56 test "GET /projects/:project_id/memberships.xml should succeed for closed project" do
61 57 project = Project.find(1)
62 58 project.close
63 59 assert !project.reload.active?
64 60 get '/projects/1/memberships.json', {}, credentials('jsmith')
65 61 assert_response :success
66 62 end
67 63
68 64 test "POST /projects/:project_id/memberships.xml should create the membership" do
69 65 assert_difference 'Member.count' do
70 66 post '/projects/1/memberships.xml', {:membership => {:user_id => 7, :role_ids => [2,3]}}, credentials('jsmith')
71 67
72 68 assert_response :created
73 69 end
74 70 end
75 71
76 72 test "POST /projects/:project_id/memberships.xml should create the group membership" do
77 73 group = Group.find(11)
78 74
79 75 assert_difference 'Member.count', 1 + group.users.count do
80 76 post '/projects/1/memberships.xml', {:membership => {:user_id => 11, :role_ids => [2,3]}}, credentials('jsmith')
81 77
82 78 assert_response :created
83 79 end
84 80 end
85 81
86 82 test "POST /projects/:project_id/memberships.xml with invalid parameters should return errors" do
87 83 assert_no_difference 'Member.count' do
88 84 post '/projects/1/memberships.xml', {:membership => {:role_ids => [2,3]}}, credentials('jsmith')
89 85
90 86 assert_response :unprocessable_entity
91 87 assert_equal 'application/xml', @response.content_type
92 88 assert_select 'errors error', :text => "Principal can't be blank"
93 89 end
94 90 end
95 91
96 92 test "GET /memberships/:id.xml should return the membership" do
97 93 get '/memberships/2.xml', {}, credentials('jsmith')
98 94
99 95 assert_response :success
100 96 assert_equal 'application/xml', @response.content_type
101 97 assert_select 'membership id:content(2)' do
102 98 assert_select '~ user[id=3][name=Dave Lopper]'
103 99 assert_select '~ roles role[id=2][name=Developer]'
104 100 end
105 101 end
106 102
107 103 test "GET /memberships/:id.json should return the membership" do
108 104 get '/memberships/2.json', {}, credentials('jsmith')
109 105
110 106 assert_response :success
111 107 assert_equal 'application/json', @response.content_type
112 108 json = ActiveSupport::JSON.decode(response.body)
113 109 assert_equal(
114 110 {"membership" => {
115 111 "id" => 2,
116 112 "project" => {"name"=>"eCookbook", "id"=>1},
117 113 "roles" => [{"name"=>"Developer", "id"=>2}],
118 114 "user" => {"name"=>"Dave Lopper", "id"=>3}}
119 115 },
120 116 json)
121 117 end
122 118
123 119 test "PUT /memberships/:id.xml should update the membership" do
124 120 assert_not_equal [1,2], Member.find(2).role_ids.sort
125 121 assert_no_difference 'Member.count' do
126 122 put '/memberships/2.xml', {:membership => {:user_id => 3, :role_ids => [1,2]}}, credentials('jsmith')
127 123
128 124 assert_response :ok
129 125 assert_equal '', @response.body
130 126 end
131 127 member = Member.find(2)
132 128 assert_equal [1,2], member.role_ids.sort
133 129 end
134 130
135 131 test "PUT /memberships/:id.xml with invalid parameters should return errors" do
136 132 put '/memberships/2.xml', {:membership => {:user_id => 3, :role_ids => [99]}}, credentials('jsmith')
137 133
138 134 assert_response :unprocessable_entity
139 135 assert_equal 'application/xml', @response.content_type
140 136 assert_select 'errors error', :text => "Role can't be empty"
141 137 end
142 138
143 139 test "DELETE /memberships/:id.xml should destroy the membership" do
144 140 assert_difference 'Member.count', -1 do
145 141 delete '/memberships/2.xml', {}, credentials('jsmith')
146 142
147 143 assert_response :ok
148 144 assert_equal '', @response.body
149 145 end
150 146 assert_nil Member.find_by_id(2)
151 147 end
152 148
153 149 test "DELETE /memberships/:id.xml should respond with 422 on failure" do
154 150 assert_no_difference 'Member.count' do
155 151 # A membership with an inherited role can't be deleted
156 152 Member.find(2).member_roles.first.update_attribute :inherited_from, 99
157 153 delete '/memberships/2.xml', {}, credentials('jsmith')
158 154
159 155 assert_response :unprocessable_entity
160 156 end
161 157 end
162 158 end
@@ -1,65 +1,61
1 1 # Redmine - project management software
2 2 # Copyright (C) 2006-2014 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 18 require File.expand_path('../../../test_helper', __FILE__)
19 19
20 20 class Redmine::ApiTest::NewsTest < Redmine::ApiTest::Base
21 21 fixtures :projects, :trackers, :issue_statuses, :issues,
22 22 :enumerations, :users, :issue_categories,
23 23 :projects_trackers,
24 24 :roles,
25 25 :member_roles,
26 26 :members,
27 27 :enabled_modules,
28 28 :news
29 29
30 def setup
31 Setting.rest_api_enabled = '1'
32 end
33
34 30 test "GET /news.xml should return news" do
35 31 get '/news.xml'
36 32
37 33 assert_select 'news[type=array] news id', :text => '2'
38 34 end
39 35
40 36 test "GET /news.json should return news" do
41 37 get '/news.json'
42 38
43 39 json = ActiveSupport::JSON.decode(response.body)
44 40 assert_kind_of Hash, json
45 41 assert_kind_of Array, json['news']
46 42 assert_kind_of Hash, json['news'].first
47 43 assert_equal 2, json['news'].first['id']
48 44 end
49 45
50 46 test "GET /projects/:project_id/news.xml should return news" do
51 47 get '/projects/ecookbook/news.xml'
52 48
53 49 assert_select 'news[type=array] news id', :text => '2'
54 50 end
55 51
56 52 test "GET /projects/:project_id/news.json should return news" do
57 53 get '/projects/ecookbook/news.json'
58 54
59 55 json = ActiveSupport::JSON.decode(response.body)
60 56 assert_kind_of Hash, json
61 57 assert_kind_of Array, json['news']
62 58 assert_kind_of Hash, json['news'].first
63 59 assert_equal 2, json['news'].first['id']
64 60 end
65 61 end
@@ -1,234 +1,234
1 1 # Redmine - project management software
2 2 # Copyright (C) 2006-2014 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 18 require File.expand_path('../../../test_helper', __FILE__)
19 19
20 20 class Redmine::ApiTest::ProjectsTest < Redmine::ApiTest::Base
21 21 fixtures :projects, :versions, :users, :roles, :members, :member_roles, :issues, :journals, :journal_details,
22 22 :trackers, :projects_trackers, :issue_statuses, :enabled_modules, :enumerations, :boards, :messages,
23 23 :attachments, :custom_fields, :custom_values, :time_entries, :issue_categories
24 24
25 25 def setup
26 Setting.rest_api_enabled = '1'
26 super
27 27 set_tmp_attachments_directory
28 28 end
29 29
30 30 test "GET /projects.xml should return projects" do
31 31 get '/projects.xml'
32 32 assert_response :success
33 33 assert_equal 'application/xml', @response.content_type
34 34
35 35 assert_select 'projects>project>id', :text => '1'
36 36 assert_select 'projects>project>status', :text => '1'
37 37 assert_select 'projects>project>is_public', :text => 'true'
38 38 end
39 39
40 40 test "GET /projects.json should return projects" do
41 41 get '/projects.json'
42 42 assert_response :success
43 43 assert_equal 'application/json', @response.content_type
44 44
45 45 json = ActiveSupport::JSON.decode(response.body)
46 46 assert_kind_of Hash, json
47 47 assert_kind_of Array, json['projects']
48 48 assert_kind_of Hash, json['projects'].first
49 49 assert json['projects'].first.has_key?('id')
50 50 end
51 51
52 52 test "GET /projects.xml with include=issue_categories should return categories" do
53 53 get '/projects.xml?include=issue_categories'
54 54 assert_response :success
55 55 assert_equal 'application/xml', @response.content_type
56 56
57 57 assert_select 'issue_categories[type=array] issue_category[id=2][name=Recipes]'
58 58 end
59 59
60 60 test "GET /projects.xml with include=trackers should return trackers" do
61 61 get '/projects.xml?include=trackers'
62 62 assert_response :success
63 63 assert_equal 'application/xml', @response.content_type
64 64
65 65 assert_select 'trackers[type=array] tracker[id=2][name=Feature request]'
66 66 end
67 67
68 68 test "GET /projects.xml with include=enabled_modules should return enabled modules" do
69 69 get '/projects.xml?include=enabled_modules'
70 70 assert_response :success
71 71 assert_equal 'application/xml', @response.content_type
72 72
73 73 assert_select 'enabled_modules[type=array] enabled_module[name=issue_tracking]'
74 74 end
75 75
76 76 test "GET /projects/:id.xml should return the project" do
77 77 get '/projects/1.xml'
78 78 assert_response :success
79 79 assert_equal 'application/xml', @response.content_type
80 80
81 81 assert_select 'project>id', :text => '1'
82 82 assert_select 'project>status', :text => '1'
83 83 assert_select 'project>is_public', :text => 'true'
84 84 assert_select 'custom_field[name=Development status]', :text => 'Stable'
85 85
86 86 assert_select 'trackers', 0
87 87 assert_select 'issue_categories', 0
88 88 end
89 89
90 90 test "GET /projects/:id.json should return the project" do
91 91 get '/projects/1.json'
92 92
93 93 json = ActiveSupport::JSON.decode(response.body)
94 94 assert_kind_of Hash, json
95 95 assert_kind_of Hash, json['project']
96 96 assert_equal 1, json['project']['id']
97 97 end
98 98
99 99 test "GET /projects/:id.xml with hidden custom fields should not display hidden custom fields" do
100 100 ProjectCustomField.find_by_name('Development status').update_attribute :visible, false
101 101
102 102 get '/projects/1.xml'
103 103 assert_response :success
104 104 assert_equal 'application/xml', @response.content_type
105 105
106 106 assert_select 'custom_field[name=?]', 'Development status', 0
107 107 end
108 108
109 109 test "GET /projects/:id.xml with include=issue_categories should return categories" do
110 110 get '/projects/1.xml?include=issue_categories'
111 111 assert_response :success
112 112 assert_equal 'application/xml', @response.content_type
113 113
114 114 assert_select 'issue_categories[type=array] issue_category[id=2][name=Recipes]'
115 115 end
116 116
117 117 test "GET /projects/:id.xml with include=trackers should return trackers" do
118 118 get '/projects/1.xml?include=trackers'
119 119 assert_response :success
120 120 assert_equal 'application/xml', @response.content_type
121 121
122 122 assert_select 'trackers[type=array] tracker[id=2][name=Feature request]'
123 123 end
124 124
125 125 test "GET /projects/:id.xml with include=enabled_modules should return enabled modules" do
126 126 get '/projects/1.xml?include=enabled_modules'
127 127 assert_response :success
128 128 assert_equal 'application/xml', @response.content_type
129 129
130 130 assert_select 'enabled_modules[type=array] enabled_module[name=issue_tracking]'
131 131 end
132 132
133 133 test "POST /projects.xml with valid parameters should create the project" do
134 134 with_settings :default_projects_modules => ['issue_tracking', 'repository'] do
135 135 assert_difference('Project.count') do
136 136 post '/projects.xml',
137 137 {:project => {:name => 'API test', :identifier => 'api-test'}},
138 138 credentials('admin')
139 139 end
140 140 end
141 141
142 142 project = Project.order('id DESC').first
143 143 assert_equal 'API test', project.name
144 144 assert_equal 'api-test', project.identifier
145 145 assert_equal ['issue_tracking', 'repository'], project.enabled_module_names.sort
146 146 assert_equal Tracker.all.size, project.trackers.size
147 147
148 148 assert_response :created
149 149 assert_equal 'application/xml', @response.content_type
150 150 assert_select 'project id', :text => project.id.to_s
151 151 end
152 152
153 153 test "POST /projects.xml should accept enabled_module_names attribute" do
154 154 assert_difference('Project.count') do
155 155 post '/projects.xml',
156 156 {:project => {:name => 'API test', :identifier => 'api-test', :enabled_module_names => ['issue_tracking', 'news', 'time_tracking']}},
157 157 credentials('admin')
158 158 end
159 159
160 160 project = Project.order('id DESC').first
161 161 assert_equal ['issue_tracking', 'news', 'time_tracking'], project.enabled_module_names.sort
162 162 end
163 163
164 164 test "POST /projects.xml should accept tracker_ids attribute" do
165 165 assert_difference('Project.count') do
166 166 post '/projects.xml',
167 167 {:project => {:name => 'API test', :identifier => 'api-test', :tracker_ids => [1, 3]}},
168 168 credentials('admin')
169 169 end
170 170
171 171 project = Project.order('id DESC').first
172 172 assert_equal [1, 3], project.trackers.map(&:id).sort
173 173 end
174 174
175 175 test "POST /projects.xml with invalid parameters should return errors" do
176 176 assert_no_difference('Project.count') do
177 177 post '/projects.xml', {:project => {:name => 'API test'}}, credentials('admin')
178 178 end
179 179
180 180 assert_response :unprocessable_entity
181 181 assert_equal 'application/xml', @response.content_type
182 182 assert_select 'errors error', :text => "Identifier can't be blank"
183 183 end
184 184
185 185 test "PUT /projects/:id.xml with valid parameters should update the project" do
186 186 assert_no_difference 'Project.count' do
187 187 put '/projects/2.xml', {:project => {:name => 'API update'}}, credentials('jsmith')
188 188 end
189 189 assert_response :ok
190 190 assert_equal '', @response.body
191 191 assert_equal 'application/xml', @response.content_type
192 192 project = Project.find(2)
193 193 assert_equal 'API update', project.name
194 194 end
195 195
196 196 test "PUT /projects/:id.xml should accept enabled_module_names attribute" do
197 197 assert_no_difference 'Project.count' do
198 198 put '/projects/2.xml', {:project => {:name => 'API update', :enabled_module_names => ['issue_tracking', 'news', 'time_tracking']}}, credentials('admin')
199 199 end
200 200 assert_response :ok
201 201 assert_equal '', @response.body
202 202 project = Project.find(2)
203 203 assert_equal ['issue_tracking', 'news', 'time_tracking'], project.enabled_module_names.sort
204 204 end
205 205
206 206 test "PUT /projects/:id.xml should accept tracker_ids attribute" do
207 207 assert_no_difference 'Project.count' do
208 208 put '/projects/2.xml', {:project => {:name => 'API update', :tracker_ids => [1, 3]}}, credentials('admin')
209 209 end
210 210 assert_response :ok
211 211 assert_equal '', @response.body
212 212 project = Project.find(2)
213 213 assert_equal [1, 3], project.trackers.map(&:id).sort
214 214 end
215 215
216 216 test "PUT /projects/:id.xml with invalid parameters should return errors" do
217 217 assert_no_difference('Project.count') do
218 218 put '/projects/2.xml', {:project => {:name => ''}}, credentials('admin')
219 219 end
220 220
221 221 assert_response :unprocessable_entity
222 222 assert_equal 'application/xml', @response.content_type
223 223 assert_select 'errors error', :text => "Name can't be blank"
224 224 end
225 225
226 226 test "DELETE /projects/:id.xml should delete the project" do
227 227 assert_difference('Project.count',-1) do
228 228 delete '/projects/2.xml', {}, credentials('admin')
229 229 end
230 230 assert_response :ok
231 231 assert_equal '', @response.body
232 232 assert_nil Project.find_by_id(2)
233 233 end
234 234 end
@@ -1,43 +1,39
1 1 # Redmine - project management software
2 2 # Copyright (C) 2006-2014 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 18 require File.expand_path('../../../test_helper', __FILE__)
19 19
20 20 class Redmine::ApiTest::QueriesTest < Redmine::ApiTest::Base
21 21 fixtures :projects, :trackers, :issue_statuses, :issues,
22 22 :enumerations, :users, :issue_categories,
23 23 :projects_trackers,
24 24 :roles,
25 25 :member_roles,
26 26 :members,
27 27 :enabled_modules,
28 28 :queries
29 29
30 def setup
31 Setting.rest_api_enabled = '1'
32 end
33
34 30 test "GET /queries.xml should return queries" do
35 31 get '/queries.xml'
36 32
37 33 assert_response :success
38 34 assert_equal 'application/xml', @response.content_type
39 35 assert_select 'queries[type=array] query id:content(4)' do
40 36 assert_select '~ name', :text => 'Public query for all projects'
41 37 end
42 38 end
43 39 end
@@ -1,66 +1,62
1 1 # Redmine - project management software
2 2 # Copyright (C) 2006-2014 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 18 require File.expand_path('../../../test_helper', __FILE__)
19 19
20 20 class Redmine::ApiTest::RolesTest < Redmine::ApiTest::Base
21 21 fixtures :roles
22 22
23 def setup
24 Setting.rest_api_enabled = '1'
25 end
26
27 23 test "GET /roles.xml should return the roles" do
28 24 get '/roles.xml'
29 25
30 26 assert_response :success
31 27 assert_equal 'application/xml', @response.content_type
32 28 assert_equal 3, assigns(:roles).size
33 29
34 30 assert_select 'roles[type=array] role id:content(2)' do
35 31 assert_select '~ name', :text => 'Developer'
36 32 end
37 33 end
38 34
39 35 test "GET /roles.json should return the roles" do
40 36 get '/roles.json'
41 37
42 38 assert_response :success
43 39 assert_equal 'application/json', @response.content_type
44 40 assert_equal 3, assigns(:roles).size
45 41
46 42 json = ActiveSupport::JSON.decode(response.body)
47 43 assert_kind_of Hash, json
48 44 assert_kind_of Array, json['roles']
49 45 assert_include({'id' => 2, 'name' => 'Developer'}, json['roles'])
50 46 end
51 47
52 48 test "GET /roles/:id.xml should return the role" do
53 49 get '/roles/1.xml'
54 50
55 51 assert_response :success
56 52 assert_equal 'application/xml', @response.content_type
57 53
58 54 assert_select 'role' do
59 55 assert_select 'name', :text => 'Manager'
60 56 assert_select 'role permissions[type=array]' do
61 57 assert_select 'permission', Role.find(1).permissions.size
62 58 assert_select 'permission', :text => 'view_issues'
63 59 end
64 60 end
65 61 end
66 62 end
@@ -1,139 +1,135
1 1 # Redmine - project management software
2 2 # Copyright (C) 2006-2014 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 18 require File.expand_path('../../../test_helper', __FILE__)
19 19
20 20 class Redmine::ApiTest::TimeEntriesTest < Redmine::ApiTest::Base
21 21 fixtures :projects, :trackers, :issue_statuses, :issues,
22 22 :enumerations, :users, :issue_categories,
23 23 :projects_trackers,
24 24 :roles,
25 25 :member_roles,
26 26 :members,
27 27 :enabled_modules,
28 28 :time_entries
29 29
30 def setup
31 Setting.rest_api_enabled = '1'
32 end
33
34 30 test "GET /time_entries.xml should return time entries" do
35 31 get '/time_entries.xml', {}, credentials('jsmith')
36 32 assert_response :success
37 33 assert_equal 'application/xml', @response.content_type
38 34 assert_select 'time_entries[type=array] time_entry id', :text => '2'
39 35 end
40 36
41 37 test "GET /time_entries.xml with limit should return limited results" do
42 38 get '/time_entries.xml?limit=2', {}, credentials('jsmith')
43 39 assert_response :success
44 40 assert_equal 'application/xml', @response.content_type
45 41 assert_select 'time_entries[type=array] time_entry', 2
46 42 end
47 43
48 44 test "GET /time_entries/:id.xml should return the time entry" do
49 45 get '/time_entries/2.xml', {}, credentials('jsmith')
50 46 assert_response :success
51 47 assert_equal 'application/xml', @response.content_type
52 48 assert_select 'time_entry id', :text => '2'
53 49 end
54 50
55 51 test "POST /time_entries.xml with issue_id should create time entry" do
56 52 assert_difference 'TimeEntry.count' do
57 53 post '/time_entries.xml', {:time_entry => {:issue_id => '1', :spent_on => '2010-12-02', :hours => '3.5', :activity_id => '11'}}, credentials('jsmith')
58 54 end
59 55 assert_response :created
60 56 assert_equal 'application/xml', @response.content_type
61 57
62 58 entry = TimeEntry.order('id DESC').first
63 59 assert_equal 'jsmith', entry.user.login
64 60 assert_equal Issue.find(1), entry.issue
65 61 assert_equal Project.find(1), entry.project
66 62 assert_equal Date.parse('2010-12-02'), entry.spent_on
67 63 assert_equal 3.5, entry.hours
68 64 assert_equal TimeEntryActivity.find(11), entry.activity
69 65 end
70 66
71 67 test "POST /time_entries.xml with issue_id should accept custom fields" do
72 68 field = TimeEntryCustomField.create!(:name => 'Test', :field_format => 'string')
73 69
74 70 assert_difference 'TimeEntry.count' do
75 71 post '/time_entries.xml', {:time_entry => {
76 72 :issue_id => '1', :spent_on => '2010-12-02', :hours => '3.5', :activity_id => '11', :custom_fields => [{:id => field.id.to_s, :value => 'accepted'}]
77 73 }}, credentials('jsmith')
78 74 end
79 75 assert_response :created
80 76 assert_equal 'application/xml', @response.content_type
81 77
82 78 entry = TimeEntry.order('id DESC').first
83 79 assert_equal 'accepted', entry.custom_field_value(field)
84 80 end
85 81
86 82 test "POST /time_entries.xml with project_id should create time entry" do
87 83 assert_difference 'TimeEntry.count' do
88 84 post '/time_entries.xml', {:time_entry => {:project_id => '1', :spent_on => '2010-12-02', :hours => '3.5', :activity_id => '11'}}, credentials('jsmith')
89 85 end
90 86 assert_response :created
91 87 assert_equal 'application/xml', @response.content_type
92 88
93 89 entry = TimeEntry.order('id DESC').first
94 90 assert_equal 'jsmith', entry.user.login
95 91 assert_nil entry.issue
96 92 assert_equal Project.find(1), entry.project
97 93 assert_equal Date.parse('2010-12-02'), entry.spent_on
98 94 assert_equal 3.5, entry.hours
99 95 assert_equal TimeEntryActivity.find(11), entry.activity
100 96 end
101 97
102 98 test "POST /time_entries.xml with invalid parameters should return errors" do
103 99 assert_no_difference 'TimeEntry.count' do
104 100 post '/time_entries.xml', {:time_entry => {:project_id => '1', :spent_on => '2010-12-02', :activity_id => '11'}}, credentials('jsmith')
105 101 end
106 102 assert_response :unprocessable_entity
107 103 assert_equal 'application/xml', @response.content_type
108 104
109 105 assert_select 'errors error', :text => "Hours can't be blank"
110 106 end
111 107
112 108 test "PUT /time_entries/:id.xml with valid parameters should update time entry" do
113 109 assert_no_difference 'TimeEntry.count' do
114 110 put '/time_entries/2.xml', {:time_entry => {:comments => 'API Update'}}, credentials('jsmith')
115 111 end
116 112 assert_response :ok
117 113 assert_equal '', @response.body
118 114 assert_equal 'API Update', TimeEntry.find(2).comments
119 115 end
120 116
121 117 test "PUT /time_entries/:id.xml with invalid parameters should return errors" do
122 118 assert_no_difference 'TimeEntry.count' do
123 119 put '/time_entries/2.xml', {:time_entry => {:hours => '', :comments => 'API Update'}}, credentials('jsmith')
124 120 end
125 121 assert_response :unprocessable_entity
126 122 assert_equal 'application/xml', @response.content_type
127 123
128 124 assert_select 'errors error', :text => "Hours can't be blank"
129 125 end
130 126
131 127 test "DELETE /time_entries/:id.xml should destroy time entry" do
132 128 assert_difference 'TimeEntry.count', -1 do
133 129 delete '/time_entries/2.xml', {}, credentials('jsmith')
134 130 end
135 131 assert_response :ok
136 132 assert_equal '', @response.body
137 133 assert_nil TimeEntry.find_by_id(2)
138 134 end
139 135 end
@@ -1,37 +1,33
1 1 # Redmine - project management software
2 2 # Copyright (C) 2006-2014 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 18 require File.expand_path('../../../test_helper', __FILE__)
19 19
20 20 class Redmine::ApiTest::TrackersTest < Redmine::ApiTest::Base
21 21 fixtures :trackers
22 22
23 def setup
24 Setting.rest_api_enabled = '1'
25 end
26
27 23 test "GET /trackers.xml should return trackers" do
28 24 get '/trackers.xml'
29 25
30 26 assert_response :success
31 27 assert_equal 'application/xml', @response.content_type
32 28
33 29 assert_select 'trackers[type=array] tracker id:content(2)' do
34 30 assert_select '~ name', :text => 'Feature request'
35 31 end
36 32 end
37 33 end
@@ -1,278 +1,274
1 1 # Redmine - project management software
2 2 # Copyright (C) 2006-2014 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 18 require File.expand_path('../../../test_helper', __FILE__)
19 19
20 20 class Redmine::ApiTest::UsersTest < Redmine::ApiTest::Base
21 21 fixtures :users, :members, :member_roles, :roles, :projects
22 22
23 def setup
24 Setting.rest_api_enabled = '1'
25 end
26
27 23 test "GET /users/:id.xml should return the user" do
28 24 get '/users/2.xml'
29 25
30 26 assert_response :success
31 27 assert_select 'user id', :text => '2'
32 28 end
33 29
34 30 test "GET /users/:id.json should return the user" do
35 31 get '/users/2.json'
36 32
37 33 assert_response :success
38 34 json = ActiveSupport::JSON.decode(response.body)
39 35 assert_kind_of Hash, json
40 36 assert_kind_of Hash, json['user']
41 37 assert_equal 2, json['user']['id']
42 38 end
43 39
44 40 test "GET /users/:id.xml with include=memberships should include memberships" do
45 41 get '/users/2.xml?include=memberships'
46 42
47 43 assert_response :success
48 44 assert_select 'user memberships', 1
49 45 end
50 46
51 47 test "GET /users/:id.json with include=memberships should include memberships" do
52 48 get '/users/2.json?include=memberships'
53 49
54 50 assert_response :success
55 51 json = ActiveSupport::JSON.decode(response.body)
56 52 assert_kind_of Array, json['user']['memberships']
57 53 assert_equal [{
58 54 "id"=>1,
59 55 "project"=>{"name"=>"eCookbook", "id"=>1},
60 56 "roles"=>[{"name"=>"Manager", "id"=>1}]
61 57 }], json['user']['memberships']
62 58 end
63 59
64 60 test "GET /users/current.xml should require authentication" do
65 61 get '/users/current.xml'
66 62
67 63 assert_response 401
68 64 end
69 65
70 66 test "GET /users/current.xml should return current user" do
71 67 get '/users/current.xml', {}, credentials('jsmith')
72 68
73 69 assert_select 'user id', :text => '2'
74 70 end
75 71
76 72 test "GET /users/:id should not return login for other user" do
77 73 get '/users/3.xml', {}, credentials('jsmith')
78 74 assert_response :success
79 75 assert_select 'user login', 0
80 76 end
81 77
82 78 test "GET /users/:id should return login for current user" do
83 79 get '/users/2.xml', {}, credentials('jsmith')
84 80 assert_response :success
85 81 assert_select 'user login', :text => 'jsmith'
86 82 end
87 83
88 84 test "GET /users/:id should not return api_key for other user" do
89 85 get '/users/3.xml', {}, credentials('jsmith')
90 86 assert_response :success
91 87 assert_select 'user api_key', 0
92 88 end
93 89
94 90 test "GET /users/:id should return api_key for current user" do
95 91 get '/users/2.xml', {}, credentials('jsmith')
96 92 assert_response :success
97 93 assert_select 'user api_key', :text => User.find(2).api_key
98 94 end
99 95
100 96 test "GET /users/:id should not return status for standard user" do
101 97 get '/users/3.xml', {}, credentials('jsmith')
102 98 assert_response :success
103 99 assert_select 'user status', 0
104 100 end
105 101
106 102 test "GET /users/:id should return status for administrators" do
107 103 get '/users/2.xml', {}, credentials('admin')
108 104 assert_response :success
109 105 assert_select 'user status', :text => User.find(1).status.to_s
110 106 end
111 107
112 108 test "POST /users.xml with valid parameters should create the user" do
113 109 assert_difference('User.count') do
114 110 post '/users.xml', {
115 111 :user => {
116 112 :login => 'foo', :firstname => 'Firstname', :lastname => 'Lastname',
117 113 :mail => 'foo@example.net', :password => 'secret123',
118 114 :mail_notification => 'only_assigned'}
119 115 },
120 116 credentials('admin')
121 117 end
122 118
123 119 user = User.order('id DESC').first
124 120 assert_equal 'foo', user.login
125 121 assert_equal 'Firstname', user.firstname
126 122 assert_equal 'Lastname', user.lastname
127 123 assert_equal 'foo@example.net', user.mail
128 124 assert_equal 'only_assigned', user.mail_notification
129 125 assert !user.admin?
130 126 assert user.check_password?('secret123')
131 127
132 128 assert_response :created
133 129 assert_equal 'application/xml', @response.content_type
134 130 assert_select 'user id', :text => user.id.to_s
135 131 end
136 132
137 133 test "POST /users.json with valid parameters should create the user" do
138 134 assert_difference('User.count') do
139 135 post '/users.json', {
140 136 :user => {
141 137 :login => 'foo', :firstname => 'Firstname', :lastname => 'Lastname',
142 138 :mail => 'foo@example.net', :password => 'secret123',
143 139 :mail_notification => 'only_assigned'}
144 140 },
145 141 credentials('admin')
146 142 end
147 143
148 144 user = User.order('id DESC').first
149 145 assert_equal 'foo', user.login
150 146 assert_equal 'Firstname', user.firstname
151 147 assert_equal 'Lastname', user.lastname
152 148 assert_equal 'foo@example.net', user.mail
153 149 assert !user.admin?
154 150
155 151 assert_response :created
156 152 assert_equal 'application/json', @response.content_type
157 153 json = ActiveSupport::JSON.decode(response.body)
158 154 assert_kind_of Hash, json
159 155 assert_kind_of Hash, json['user']
160 156 assert_equal user.id, json['user']['id']
161 157 end
162 158
163 159 test "POST /users.xml with with invalid parameters should return errors" do
164 160 assert_no_difference('User.count') do
165 161 post '/users.xml', {:user => {:login => 'foo', :lastname => 'Lastname', :mail => 'foo'}}, credentials('admin')
166 162 end
167 163
168 164 assert_response :unprocessable_entity
169 165 assert_equal 'application/xml', @response.content_type
170 166 assert_select 'errors error', :text => "First name can't be blank"
171 167 end
172 168
173 169 test "POST /users.json with with invalid parameters should return errors" do
174 170 assert_no_difference('User.count') do
175 171 post '/users.json', {:user => {:login => 'foo', :lastname => 'Lastname', :mail => 'foo'}}, credentials('admin')
176 172 end
177 173
178 174 assert_response :unprocessable_entity
179 175 assert_equal 'application/json', @response.content_type
180 176 json = ActiveSupport::JSON.decode(response.body)
181 177 assert_kind_of Hash, json
182 178 assert json.has_key?('errors')
183 179 assert_kind_of Array, json['errors']
184 180 end
185 181
186 182 test "PUT /users/:id.xml with valid parameters should update the user" do
187 183 assert_no_difference('User.count') do
188 184 put '/users/2.xml', {
189 185 :user => {
190 186 :login => 'jsmith', :firstname => 'John', :lastname => 'Renamed',
191 187 :mail => 'jsmith@somenet.foo'}
192 188 },
193 189 credentials('admin')
194 190 end
195 191
196 192 user = User.find(2)
197 193 assert_equal 'jsmith', user.login
198 194 assert_equal 'John', user.firstname
199 195 assert_equal 'Renamed', user.lastname
200 196 assert_equal 'jsmith@somenet.foo', user.mail
201 197 assert !user.admin?
202 198
203 199 assert_response :ok
204 200 assert_equal '', @response.body
205 201 end
206 202
207 203 test "PUT /users/:id.json with valid parameters should update the user" do
208 204 assert_no_difference('User.count') do
209 205 put '/users/2.json', {
210 206 :user => {
211 207 :login => 'jsmith', :firstname => 'John', :lastname => 'Renamed',
212 208 :mail => 'jsmith@somenet.foo'}
213 209 },
214 210 credentials('admin')
215 211 end
216 212
217 213 user = User.find(2)
218 214 assert_equal 'jsmith', user.login
219 215 assert_equal 'John', user.firstname
220 216 assert_equal 'Renamed', user.lastname
221 217 assert_equal 'jsmith@somenet.foo', user.mail
222 218 assert !user.admin?
223 219
224 220 assert_response :ok
225 221 assert_equal '', @response.body
226 222 end
227 223
228 224 test "PUT /users/:id.xml with invalid parameters" do
229 225 assert_no_difference('User.count') do
230 226 put '/users/2.xml', {
231 227 :user => {
232 228 :login => 'jsmith', :firstname => '', :lastname => 'Lastname',
233 229 :mail => 'foo'}
234 230 },
235 231 credentials('admin')
236 232 end
237 233
238 234 assert_response :unprocessable_entity
239 235 assert_equal 'application/xml', @response.content_type
240 236 assert_select 'errors error', :text => "First name can't be blank"
241 237 end
242 238
243 239 test "PUT /users/:id.json with invalid parameters" do
244 240 assert_no_difference('User.count') do
245 241 put '/users/2.json', {
246 242 :user => {
247 243 :login => 'jsmith', :firstname => '', :lastname => 'Lastname',
248 244 :mail => 'foo'}
249 245 },
250 246 credentials('admin')
251 247 end
252 248
253 249 assert_response :unprocessable_entity
254 250 assert_equal 'application/json', @response.content_type
255 251 json = ActiveSupport::JSON.decode(response.body)
256 252 assert_kind_of Hash, json
257 253 assert json.has_key?('errors')
258 254 assert_kind_of Array, json['errors']
259 255 end
260 256
261 257 test "DELETE /users/:id.xml should delete the user" do
262 258 assert_difference('User.count', -1) do
263 259 delete '/users/2.xml', {}, credentials('admin')
264 260 end
265 261
266 262 assert_response :ok
267 263 assert_equal '', @response.body
268 264 end
269 265
270 266 test "DELETE /users/:id.json should delete the user" do
271 267 assert_difference('User.count', -1) do
272 268 delete '/users/2.json', {}, credentials('admin')
273 269 end
274 270
275 271 assert_response :ok
276 272 assert_equal '', @response.body
277 273 end
278 274 end
@@ -1,133 +1,129
1 1 # Redmine - project management software
2 2 # Copyright (C) 2006-2014 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 18 require File.expand_path('../../../test_helper', __FILE__)
19 19
20 20 class Redmine::ApiTest::VersionsTest < Redmine::ApiTest::Base
21 21 fixtures :projects, :trackers, :issue_statuses, :issues,
22 22 :enumerations, :users, :issue_categories,
23 23 :projects_trackers,
24 24 :roles,
25 25 :member_roles,
26 26 :members,
27 27 :enabled_modules,
28 28 :versions
29 29
30 def setup
31 Setting.rest_api_enabled = '1'
32 end
33
34 30 test "GET /projects/:project_id/versions.xml should return project versions" do
35 31 get '/projects/1/versions.xml'
36 32
37 33 assert_response :success
38 34 assert_equal 'application/xml', @response.content_type
39 35
40 36 assert_select 'versions[type=array] version id:content(2)' do
41 37 assert_select '~ name', :text => '1.0'
42 38 end
43 39 end
44 40
45 41 test "POST /projects/:project_id/versions.xml should create the version" do
46 42 assert_difference 'Version.count' do
47 43 post '/projects/1/versions.xml', {:version => {:name => 'API test'}}, credentials('jsmith')
48 44 end
49 45
50 46 version = Version.order('id DESC').first
51 47 assert_equal 'API test', version.name
52 48
53 49 assert_response :created
54 50 assert_equal 'application/xml', @response.content_type
55 51 assert_select 'version id', :text => version.id.to_s
56 52 end
57 53
58 54 test "POST /projects/:project_id/versions.xml should create the version with due date" do
59 55 assert_difference 'Version.count' do
60 56 post '/projects/1/versions.xml', {:version => {:name => 'API test', :due_date => '2012-01-24'}}, credentials('jsmith')
61 57 end
62 58
63 59 version = Version.order('id DESC').first
64 60 assert_equal 'API test', version.name
65 61 assert_equal Date.parse('2012-01-24'), version.due_date
66 62
67 63 assert_response :created
68 64 assert_equal 'application/xml', @response.content_type
69 65 assert_select 'version id', :text => version.id.to_s
70 66 end
71 67
72 68 test "POST /projects/:project_id/versions.xml should create the version with custom fields" do
73 69 field = VersionCustomField.generate!
74 70
75 71 assert_difference 'Version.count' do
76 72 post '/projects/1/versions.xml', {
77 73 :version => {
78 74 :name => 'API test',
79 75 :custom_fields => [
80 76 {'id' => field.id.to_s, 'value' => 'Some value'}
81 77 ]
82 78 }
83 79 }, credentials('jsmith')
84 80 end
85 81
86 82 version = Version.order('id DESC').first
87 83 assert_equal 'API test', version.name
88 84 assert_equal 'Some value', version.custom_field_value(field)
89 85
90 86 assert_response :created
91 87 assert_equal 'application/xml', @response.content_type
92 88 assert_select 'version>custom_fields>custom_field[id=?]>value', field.id.to_s, 'Some value'
93 89 end
94 90
95 91 test "POST /projects/:project_id/versions.xml with failure should return the errors" do
96 92 assert_no_difference('Version.count') do
97 93 post '/projects/1/versions.xml', {:version => {:name => ''}}, credentials('jsmith')
98 94 end
99 95
100 96 assert_response :unprocessable_entity
101 97 assert_select 'errors error', :text => "Name can't be blank"
102 98 end
103 99
104 100 test "GET /versions/:id.xml should return the version" do
105 101 get '/versions/2.xml'
106 102
107 103 assert_response :success
108 104 assert_equal 'application/xml', @response.content_type
109 105 assert_select 'version' do
110 106 assert_select 'id', :text => '2'
111 107 assert_select 'name', :text => '1.0'
112 108 assert_select 'sharing', :text => 'none'
113 109 end
114 110 end
115 111
116 112 test "PUT /versions/:id.xml should update the version" do
117 113 put '/versions/2.xml', {:version => {:name => 'API update'}}, credentials('jsmith')
118 114
119 115 assert_response :ok
120 116 assert_equal '', @response.body
121 117 assert_equal 'API update', Version.find(2).name
122 118 end
123 119
124 120 test "DELETE /versions/:id.xml should destroy the version" do
125 121 assert_difference 'Version.count', -1 do
126 122 delete '/versions/3.xml', {}, credentials('jsmith')
127 123 end
128 124
129 125 assert_response :ok
130 126 assert_equal '', @response.body
131 127 assert_nil Version.find_by_id(3)
132 128 end
133 129 end
@@ -1,194 +1,190
1 1 # Redmine - project management software
2 2 # Copyright (C) 2006-2014 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 18 require File.expand_path('../../../test_helper', __FILE__)
19 19
20 20 class Redmine::ApiTest::WikiPagesTest < Redmine::ApiTest::Base
21 21 fixtures :projects, :users, :roles, :members, :member_roles,
22 22 :enabled_modules, :wikis, :wiki_pages, :wiki_contents,
23 23 :wiki_content_versions, :attachments
24 24
25 def setup
26 Setting.rest_api_enabled = '1'
27 end
28
29 25 test "GET /projects/:project_id/wiki/index.xml should return wiki pages" do
30 26 get '/projects/ecookbook/wiki/index.xml'
31 27 assert_response 200
32 28 assert_equal 'application/xml', response.content_type
33 29 assert_select 'wiki_pages[type=array]' do
34 30 assert_select 'wiki_page', :count => Wiki.find(1).pages.count
35 31 assert_select 'wiki_page' do
36 32 assert_select 'title', :text => 'CookBook_documentation'
37 33 assert_select 'version', :text => '3'
38 34 assert_select 'created_on'
39 35 assert_select 'updated_on'
40 36 end
41 37 assert_select 'wiki_page' do
42 38 assert_select 'title', :text => 'Page_with_an_inline_image'
43 39 assert_select 'parent[title=?]', 'CookBook_documentation'
44 40 end
45 41 end
46 42 end
47 43
48 44 test "GET /projects/:project_id/wiki/:title.xml should return wiki page" do
49 45 get '/projects/ecookbook/wiki/CookBook_documentation.xml'
50 46 assert_response 200
51 47 assert_equal 'application/xml', response.content_type
52 48 assert_select 'wiki_page' do
53 49 assert_select 'title', :text => 'CookBook_documentation'
54 50 assert_select 'version', :text => '3'
55 51 assert_select 'text'
56 52 assert_select 'author'
57 53 assert_select 'comments'
58 54 assert_select 'created_on'
59 55 assert_select 'updated_on'
60 56 end
61 57 end
62 58
63 59 test "GET /projects/:project_id/wiki/:title.xml?include=attachments should include attachments" do
64 60 get '/projects/ecookbook/wiki/Page_with_an_inline_image.xml?include=attachments'
65 61 assert_response 200
66 62 assert_equal 'application/xml', response.content_type
67 63 assert_select 'wiki_page' do
68 64 assert_select 'title', :text => 'Page_with_an_inline_image'
69 65 assert_select 'attachments[type=array]' do
70 66 assert_select 'attachment' do
71 67 assert_select 'id', :text => '3'
72 68 assert_select 'filename', :text => 'logo.gif'
73 69 end
74 70 end
75 71 end
76 72 end
77 73
78 74 test "GET /projects/:project_id/wiki/:title.xml with unknown title and edit permission should respond with 404" do
79 75 get '/projects/ecookbook/wiki/Invalid_Page.xml', {}, credentials('jsmith')
80 76 assert_response 404
81 77 assert_equal 'application/xml', response.content_type
82 78 end
83 79
84 80 test "GET /projects/:project_id/wiki/:title/:version.xml should return wiki page version" do
85 81 get '/projects/ecookbook/wiki/CookBook_documentation/2.xml'
86 82 assert_response 200
87 83 assert_equal 'application/xml', response.content_type
88 84 assert_select 'wiki_page' do
89 85 assert_select 'title', :text => 'CookBook_documentation'
90 86 assert_select 'version', :text => '2'
91 87 assert_select 'text'
92 88 assert_select 'author'
93 89 assert_select 'comments', :text => 'Small update'
94 90 assert_select 'created_on'
95 91 assert_select 'updated_on'
96 92 end
97 93 end
98 94
99 95 test "GET /projects/:project_id/wiki/:title/:version.xml without permission should be denied" do
100 96 Role.anonymous.remove_permission! :view_wiki_edits
101 97
102 98 get '/projects/ecookbook/wiki/CookBook_documentation/2.xml'
103 99 assert_response 401
104 100 assert_equal 'application/xml', response.content_type
105 101 end
106 102
107 103 test "PUT /projects/:project_id/wiki/:title.xml should update wiki page" do
108 104 assert_no_difference 'WikiPage.count' do
109 105 assert_difference 'WikiContent::Version.count' do
110 106 put '/projects/ecookbook/wiki/CookBook_documentation.xml',
111 107 {:wiki_page => {:text => 'New content from API', :comments => 'API update'}},
112 108 credentials('jsmith')
113 109 assert_response 200
114 110 end
115 111 end
116 112
117 113 page = WikiPage.find(1)
118 114 assert_equal 'New content from API', page.content.text
119 115 assert_equal 4, page.content.version
120 116 assert_equal 'API update', page.content.comments
121 117 assert_equal 'jsmith', page.content.author.login
122 118 end
123 119
124 120 test "PUT /projects/:project_id/wiki/:title.xml with current versino should update wiki page" do
125 121 assert_no_difference 'WikiPage.count' do
126 122 assert_difference 'WikiContent::Version.count' do
127 123 put '/projects/ecookbook/wiki/CookBook_documentation.xml',
128 124 {:wiki_page => {:text => 'New content from API', :comments => 'API update', :version => '3'}},
129 125 credentials('jsmith')
130 126 assert_response 200
131 127 end
132 128 end
133 129
134 130 page = WikiPage.find(1)
135 131 assert_equal 'New content from API', page.content.text
136 132 assert_equal 4, page.content.version
137 133 assert_equal 'API update', page.content.comments
138 134 assert_equal 'jsmith', page.content.author.login
139 135 end
140 136
141 137 test "PUT /projects/:project_id/wiki/:title.xml with stale version should respond with 409" do
142 138 assert_no_difference 'WikiPage.count' do
143 139 assert_no_difference 'WikiContent::Version.count' do
144 140 put '/projects/ecookbook/wiki/CookBook_documentation.xml',
145 141 {:wiki_page => {:text => 'New content from API', :comments => 'API update', :version => '2'}},
146 142 credentials('jsmith')
147 143 assert_response 409
148 144 end
149 145 end
150 146 end
151 147
152 148 test "PUT /projects/:project_id/wiki/:title.xml should create the page if it does not exist" do
153 149 assert_difference 'WikiPage.count' do
154 150 assert_difference 'WikiContent::Version.count' do
155 151 put '/projects/ecookbook/wiki/New_page_from_API.xml',
156 152 {:wiki_page => {:text => 'New content from API', :comments => 'API create'}},
157 153 credentials('jsmith')
158 154 assert_response 201
159 155 end
160 156 end
161 157
162 158 page = WikiPage.order('id DESC').first
163 159 assert_equal 'New_page_from_API', page.title
164 160 assert_equal 'New content from API', page.content.text
165 161 assert_equal 1, page.content.version
166 162 assert_equal 'API create', page.content.comments
167 163 assert_equal 'jsmith', page.content.author.login
168 164 assert_nil page.parent
169 165 end
170 166
171 167 test "PUT /projects/:project_id/wiki/:title.xml with parent" do
172 168 assert_difference 'WikiPage.count' do
173 169 assert_difference 'WikiContent::Version.count' do
174 170 put '/projects/ecookbook/wiki/New_subpage_from_API.xml',
175 171 {:wiki_page => {:parent_title => 'CookBook_documentation', :text => 'New content from API', :comments => 'API create'}},
176 172 credentials('jsmith')
177 173 assert_response 201
178 174 end
179 175 end
180 176
181 177 page = WikiPage.order('id DESC').first
182 178 assert_equal 'New_subpage_from_API', page.title
183 179 assert_equal WikiPage.find(1), page.parent
184 180 end
185 181
186 182 test "DELETE /projects/:project_id/wiki/:title.xml should destroy the page" do
187 183 assert_difference 'WikiPage.count', -1 do
188 184 delete '/projects/ecookbook/wiki/CookBook_documentation.xml', {}, credentials('jsmith')
189 185 assert_response 200
190 186 end
191 187
192 188 assert_nil WikiPage.find_by_id(1)
193 189 end
194 190 end
@@ -1,283 +1,290
1 1 # Redmine - project management software
2 2 # Copyright (C) 2006-2014 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 18 ENV["RAILS_ENV"] = "test"
19 19 require File.expand_path(File.dirname(__FILE__) + "/../config/environment")
20 20 require 'rails/test_help'
21 21 require Rails.root.join('test', 'mocks', 'open_id_authentication_mock.rb').to_s
22 22
23 23 require File.expand_path(File.dirname(__FILE__) + '/object_helpers')
24 24 include ObjectHelpers
25 25
26 26 require 'awesome_nested_set/version'
27 27 require 'net/ldap'
28 28
29 29 class ActionView::TestCase
30 30 helper :application
31 31 include ApplicationHelper
32 32 end
33 33
34 34 class ActiveSupport::TestCase
35 35 include ActionDispatch::TestProcess
36 36
37 37 self.use_transactional_fixtures = true
38 38 self.use_instantiated_fixtures = false
39 39
40 40 #ESCAPED_CANT = 'can&#x27;t'
41 41 #ESCAPED_UCANT = 'Can&#x27;t'
42 42 # Rails 4.0.2
43 43 ESCAPED_CANT = 'can&#39;t'
44 44 ESCAPED_UCANT = 'Can&#39;t'
45 45
46 46 def log_user(login, password)
47 47 User.anonymous
48 48 get "/login"
49 49 assert_equal nil, session[:user_id]
50 50 assert_response :success
51 51 assert_template "account/login"
52 52 post "/login", :username => login, :password => password
53 53 assert_equal login, User.find(session[:user_id]).login
54 54 end
55 55
56 56 def uploaded_test_file(name, mime)
57 57 fixture_file_upload("files/#{name}", mime, true)
58 58 end
59 59
60 60 def credentials(user, password=nil)
61 61 {'HTTP_AUTHORIZATION' => ActionController::HttpAuthentication::Basic.encode_credentials(user, password || user)}
62 62 end
63 63
64 64 # Mock out a file
65 65 def self.mock_file
66 66 file = 'a_file.png'
67 67 file.stubs(:size).returns(32)
68 68 file.stubs(:original_filename).returns('a_file.png')
69 69 file.stubs(:content_type).returns('image/png')
70 70 file.stubs(:read).returns(false)
71 71 file
72 72 end
73 73
74 74 def mock_file
75 75 self.class.mock_file
76 76 end
77 77
78 78 def mock_file_with_options(options={})
79 79 file = ''
80 80 file.stubs(:size).returns(32)
81 81 original_filename = options[:original_filename] || nil
82 82 file.stubs(:original_filename).returns(original_filename)
83 83 content_type = options[:content_type] || nil
84 84 file.stubs(:content_type).returns(content_type)
85 85 file.stubs(:read).returns(false)
86 86 file
87 87 end
88 88
89 89 # Use a temporary directory for attachment related tests
90 90 def set_tmp_attachments_directory
91 91 Dir.mkdir "#{Rails.root}/tmp/test" unless File.directory?("#{Rails.root}/tmp/test")
92 92 unless File.directory?("#{Rails.root}/tmp/test/attachments")
93 93 Dir.mkdir "#{Rails.root}/tmp/test/attachments"
94 94 end
95 95 Attachment.storage_path = "#{Rails.root}/tmp/test/attachments"
96 96 end
97 97
98 98 def set_fixtures_attachments_directory
99 99 Attachment.storage_path = "#{Rails.root}/test/fixtures/files"
100 100 end
101 101
102 102 def with_settings(options, &block)
103 103 saved_settings = options.keys.inject({}) do |h, k|
104 104 h[k] = case Setting[k]
105 105 when Symbol, false, true, nil
106 106 Setting[k]
107 107 else
108 108 Setting[k].dup
109 109 end
110 110 h
111 111 end
112 112 options.each {|k, v| Setting[k] = v}
113 113 yield
114 114 ensure
115 115 saved_settings.each {|k, v| Setting[k] = v} if saved_settings
116 116 end
117 117
118 118 # Yields the block with user as the current user
119 119 def with_current_user(user, &block)
120 120 saved_user = User.current
121 121 User.current = user
122 122 yield
123 123 ensure
124 124 User.current = saved_user
125 125 end
126 126
127 127 def with_locale(locale, &block)
128 128 saved_localed = ::I18n.locale
129 129 ::I18n.locale = locale
130 130 yield
131 131 ensure
132 132 ::I18n.locale = saved_localed
133 133 end
134 134
135 135 def self.ldap_configured?
136 136 @test_ldap = Net::LDAP.new(:host => '127.0.0.1', :port => 389)
137 137 return @test_ldap.bind
138 138 rescue Exception => e
139 139 # LDAP is not listening
140 140 return nil
141 141 end
142 142
143 143 def self.convert_installed?
144 144 Redmine::Thumbnail.convert_available?
145 145 end
146 146
147 147 # Returns the path to the test +vendor+ repository
148 148 def self.repository_path(vendor)
149 149 path = Rails.root.join("tmp/test/#{vendor.downcase}_repository").to_s
150 150 # Unlike ruby, JRuby returns Rails.root with backslashes under Windows
151 151 path.tr("\\", "/")
152 152 end
153 153
154 154 # Returns the url of the subversion test repository
155 155 def self.subversion_repository_url
156 156 path = repository_path('subversion')
157 157 path = '/' + path unless path.starts_with?('/')
158 158 "file://#{path}"
159 159 end
160 160
161 161 # Returns true if the +vendor+ test repository is configured
162 162 def self.repository_configured?(vendor)
163 163 File.directory?(repository_path(vendor))
164 164 end
165 165
166 166 def repository_path_hash(arr)
167 167 hs = {}
168 168 hs[:path] = arr.join("/")
169 169 hs[:param] = arr.join("/")
170 170 hs
171 171 end
172 172
173 173 def assert_save(object)
174 174 saved = object.save
175 175 message = "#{object.class} could not be saved"
176 176 errors = object.errors.full_messages.map {|m| "- #{m}"}
177 177 message << ":\n#{errors.join("\n")}" if errors.any?
178 178 assert_equal true, saved, message
179 179 end
180 180
181 181 def assert_select_error(arg)
182 182 assert_select '#errorExplanation', :text => arg
183 183 end
184 184
185 185 def assert_include(expected, s, message=nil)
186 186 assert s.include?(expected), (message || "\"#{expected}\" not found in \"#{s}\"")
187 187 end
188 188
189 189 def assert_not_include(expected, s, message=nil)
190 190 assert !s.include?(expected), (message || "\"#{expected}\" found in \"#{s}\"")
191 191 end
192 192
193 193 def assert_select_in(text, *args, &block)
194 194 d = HTML::Document.new(CGI::unescapeHTML(String.new(text))).root
195 195 assert_select(d, *args, &block)
196 196 end
197 197
198 198 def assert_mail_body_match(expected, mail, message=nil)
199 199 if expected.is_a?(String)
200 200 assert_include expected, mail_body(mail), message
201 201 else
202 202 assert_match expected, mail_body(mail), message
203 203 end
204 204 end
205 205
206 206 def assert_mail_body_no_match(expected, mail, message=nil)
207 207 if expected.is_a?(String)
208 208 assert_not_include expected, mail_body(mail), message
209 209 else
210 210 assert_no_match expected, mail_body(mail), message
211 211 end
212 212 end
213 213
214 214 def mail_body(mail)
215 215 mail.parts.first.body.encoded
216 216 end
217 217
218 218 # awesome_nested_set new node lft and rgt value changed this refactor revision.
219 219 # https://github.com/collectiveidea/awesome_nested_set/commit/199fca9bb938e40200cd90714dc69247ef017c61
220 220 # The reason of behavior change is that "self.class.base_class.unscoped" was added to this line.
221 221 # https://github.com/collectiveidea/awesome_nested_set/commit/199fca9bb9#diff-f61b59a5e6319024e211b0ffdd0e4ef1R273
222 222 # It seems correct behavior because of this line comment.
223 223 # https://github.com/collectiveidea/awesome_nested_set/blame/199fca9bb9/lib/awesome_nested_set/model.rb#L278
224 224 def new_issue_lft
225 225 # ::AwesomeNestedSet::VERSION > "2.1.6" ? Issue.maximum(:rgt) + 1 : 1
226 226 Issue.maximum(:rgt) + 1
227 227 end
228 228 end
229 229
230 230 module Redmine
231 231 class RoutingTest < ActionDispatch::IntegrationTest
232 232 def should_route(arg)
233 233 arg = arg.dup
234 234 request = arg.keys.detect {|key| key.is_a?(String)}
235 235 raise ArgumentError unless request
236 236 options = arg.slice!(request)
237 237
238 238 raise ArgumentError unless request =~ /\A(GET|POST|PUT|PATCH|DELETE)\s+(.+)\z/
239 239 method, path = $1.downcase.to_sym, $2
240 240
241 241 raise ArgumentError unless arg.values.first =~ /\A(.+)#(.+)\z/
242 242 controller, action = $1, $2
243 243
244 244 assert_routing(
245 245 {:method => method, :path => path},
246 246 options.merge(:controller => controller, :action => action)
247 247 )
248 248 end
249 249 end
250 250
251 251 module ApiTest
252 252 API_FORMATS = %w(json xml).freeze
253 253
254 254 # Base class for API tests
255 255 class Base < ActionDispatch::IntegrationTest
256 def setup
257 Setting.rest_api_enabled = '1'
258 end
259
260 def teardown
261 Setting.rest_api_enabled = '0'
262 end
256 263 end
257 264
258 265 class Routing < Redmine::RoutingTest
259 266 def should_route(arg)
260 267 arg = arg.dup
261 268 request = arg.keys.detect {|key| key.is_a?(String)}
262 269 raise ArgumentError unless request
263 270 options = arg.slice!(request)
264 271
265 272 API_FORMATS.each do |format|
266 273 format_request = request.sub /$/, ".#{format}"
267 274 super options.merge(format_request => arg[request], :format => format)
268 275 end
269 276 end
270 277 end
271 278 end
272 279 end
273 280
274 281 # URL helpers do not work with config.threadsafe!
275 282 # https://github.com/rspec/rspec-rails/issues/476#issuecomment-4705454
276 283 ActionView::TestCase::TestController.instance_eval do
277 284 helper Rails.application.routes.url_helpers
278 285 end
279 286 ActionView::TestCase::TestController.class_eval do
280 287 def _routes
281 288 Rails.application.routes
282 289 end
283 290 end
General Comments 0
You need to be logged in to leave comments. Login now