##// END OF EJS Templates
Move all API tests into the ApiTest module to make management easier...
Eric Davis -
r4243:d5fde17bf5d0
parent child
Show More
@@ -1,110 +1,110
1 require "#{File.dirname(__FILE__)}/../test_helper"
1 require "#{File.dirname(__FILE__)}/../../test_helper"
2 2
3 class DisabledRestApi < ActionController::IntegrationTest
3 class ApiTest::DisabledRestApiTest < ActionController::IntegrationTest
4 4 fixtures :all
5 5
6 6 def setup
7 7 Setting.rest_api_enabled = '0'
8 8 Setting.login_required = '1'
9 9 end
10 10
11 11 def teardown
12 12 Setting.rest_api_enabled = '1'
13 13 Setting.login_required = '0'
14 14 end
15 15
16 16 # Using the NewsController because it's a simple API.
17 17 context "get /news with the API disabled" do
18 18
19 19 context "in :xml format" do
20 20 context "with a valid api token" do
21 21 setup do
22 22 @user = User.generate_with_protected!
23 23 @token = Token.generate!(:user => @user, :action => 'api')
24 24 get "/news.xml?key=#{@token.value}"
25 25 end
26 26
27 27 should_respond_with :unauthorized
28 28 should_respond_with_content_type :xml
29 29 should "not login as the user" do
30 30 assert_equal User.anonymous, User.current
31 31 end
32 32 end
33 33
34 34 context "with a valid HTTP authentication" do
35 35 setup do
36 36 @user = User.generate_with_protected!(:password => 'my_password', :password_confirmation => 'my_password')
37 37 @authorization = ActionController::HttpAuthentication::Basic.encode_credentials(@user.login, 'my_password')
38 38 get "/news.xml", nil, :authorization => @authorization
39 39 end
40 40
41 41 should_respond_with :unauthorized
42 42 should_respond_with_content_type :xml
43 43 should "not login as the user" do
44 44 assert_equal User.anonymous, User.current
45 45 end
46 46 end
47 47
48 48 context "with a valid HTTP authentication using the API token" do
49 49 setup do
50 50 @user = User.generate_with_protected!
51 51 @token = Token.generate!(:user => @user, :action => 'api')
52 52 @authorization = ActionController::HttpAuthentication::Basic.encode_credentials(@token.value, 'X')
53 53 get "/news.xml", nil, :authorization => @authorization
54 54 end
55 55
56 56 should_respond_with :unauthorized
57 57 should_respond_with_content_type :xml
58 58 should "not login as the user" do
59 59 assert_equal User.anonymous, User.current
60 60 end
61 61 end
62 62 end
63 63
64 64 context "in :json format" do
65 65 context "with a valid api token" do
66 66 setup do
67 67 @user = User.generate_with_protected!
68 68 @token = Token.generate!(:user => @user, :action => 'api')
69 69 get "/news.json?key=#{@token.value}"
70 70 end
71 71
72 72 should_respond_with :unauthorized
73 73 should_respond_with_content_type :json
74 74 should "not login as the user" do
75 75 assert_equal User.anonymous, User.current
76 76 end
77 77 end
78 78
79 79 context "with a valid HTTP authentication" do
80 80 setup do
81 81 @user = User.generate_with_protected!(:password => 'my_password', :password_confirmation => 'my_password')
82 82 @authorization = ActionController::HttpAuthentication::Basic.encode_credentials(@user.login, 'my_password')
83 83 get "/news.json", nil, :authorization => @authorization
84 84 end
85 85
86 86 should_respond_with :unauthorized
87 87 should_respond_with_content_type :json
88 88 should "not login as the user" do
89 89 assert_equal User.anonymous, User.current
90 90 end
91 91 end
92 92
93 93 context "with a valid HTTP authentication using the API token" do
94 94 setup do
95 95 @user = User.generate_with_protected!
96 96 @token = Token.generate!(:user => @user, :action => 'api')
97 97 @authorization = ActionController::HttpAuthentication::Basic.encode_credentials(@token.value, 'DoesNotMatter')
98 98 get "/news.json", nil, :authorization => @authorization
99 99 end
100 100
101 101 should_respond_with :unauthorized
102 102 should_respond_with_content_type :json
103 103 should "not login as the user" do
104 104 assert_equal User.anonymous, User.current
105 105 end
106 106 end
107 107
108 108 end
109 109 end
110 110 end
@@ -1,103 +1,103
1 require "#{File.dirname(__FILE__)}/../test_helper"
1 require "#{File.dirname(__FILE__)}/../../test_helper"
2 2
3 class HttpBasicLoginTest < ActionController::IntegrationTest
3 class ApiTest::HttpBasicLoginTest < ActionController::IntegrationTest
4 4 fixtures :all
5 5
6 6 def setup
7 7 Setting.rest_api_enabled = '1'
8 8 Setting.login_required = '1'
9 9 end
10 10
11 11 def teardown
12 12 Setting.rest_api_enabled = '0'
13 13 Setting.login_required = '0'
14 14 end
15 15
16 16 # Using the NewsController because it's a simple API.
17 17 context "get /news" do
18 18
19 19 context "in :xml format" do
20 20 context "with a valid HTTP authentication" do
21 21 setup do
22 22 @user = User.generate_with_protected!(:password => 'my_password', :password_confirmation => 'my_password')
23 23 @authorization = ActionController::HttpAuthentication::Basic.encode_credentials(@user.login, 'my_password')
24 24 get "/news.xml", nil, :authorization => @authorization
25 25 end
26 26
27 27 should_respond_with :success
28 28 should_respond_with_content_type :xml
29 29 should "login as the user" do
30 30 assert_equal @user, User.current
31 31 end
32 32 end
33 33
34 34 context "with an invalid HTTP authentication" do
35 35 setup do
36 36 @user = User.generate_with_protected!
37 37 @authorization = ActionController::HttpAuthentication::Basic.encode_credentials(@user.login, 'wrong_password')
38 38 get "/news.xml", nil, :authorization => @authorization
39 39 end
40 40
41 41 should_respond_with :unauthorized
42 42 should_respond_with_content_type :xml
43 43 should "not login as the user" do
44 44 assert_equal User.anonymous, User.current
45 45 end
46 46 end
47 47
48 48 context "without credentials" do
49 49 setup do
50 50 get "/projects/onlinestore/news.xml"
51 51 end
52 52
53 53 should_respond_with :unauthorized
54 54 should_respond_with_content_type :xml
55 55 should "include_www_authenticate_header" do
56 56 assert @controller.response.headers.has_key?('WWW-Authenticate')
57 57 end
58 58 end
59 59 end
60 60
61 61 context "in :json format" do
62 62 context "with a valid HTTP authentication" do
63 63 setup do
64 64 @user = User.generate_with_protected!(:password => 'my_password', :password_confirmation => 'my_password')
65 65 @authorization = ActionController::HttpAuthentication::Basic.encode_credentials(@user.login, 'my_password')
66 66 get "/news.json", nil, :authorization => @authorization
67 67 end
68 68
69 69 should_respond_with :success
70 70 should_respond_with_content_type :json
71 71 should "login as the user" do
72 72 assert_equal @user, User.current
73 73 end
74 74 end
75 75
76 76 context "with an invalid HTTP authentication" do
77 77 setup do
78 78 @user = User.generate_with_protected!
79 79 @authorization = ActionController::HttpAuthentication::Basic.encode_credentials(@user.login, 'wrong_password')
80 80 get "/news.json", nil, :authorization => @authorization
81 81 end
82 82
83 83 should_respond_with :unauthorized
84 84 should_respond_with_content_type :json
85 85 should "not login as the user" do
86 86 assert_equal User.anonymous, User.current
87 87 end
88 88 end
89 89 end
90 90
91 91 context "without credentials" do
92 92 setup do
93 93 get "/projects/onlinestore/news.json"
94 94 end
95 95
96 96 should_respond_with :unauthorized
97 97 should_respond_with_content_type :json
98 98 should "include_www_authenticate_header" do
99 99 assert @controller.response.headers.has_key?('WWW-Authenticate')
100 100 end
101 101 end
102 102 end
103 103 end
@@ -1,84 +1,84
1 require "#{File.dirname(__FILE__)}/../test_helper"
1 require "#{File.dirname(__FILE__)}/../../test_helper"
2 2
3 class HttpBasicLoginWithApiTokenTest < ActionController::IntegrationTest
3 class ApiTest::HttpBasicLoginWithApiTokenTest < ActionController::IntegrationTest
4 4 fixtures :all
5 5
6 6 def setup
7 7 Setting.rest_api_enabled = '1'
8 8 Setting.login_required = '1'
9 9 end
10 10
11 11 def teardown
12 12 Setting.rest_api_enabled = '0'
13 13 Setting.login_required = '0'
14 14 end
15 15
16 16 # Using the NewsController because it's a simple API.
17 17 context "get /news" do
18 18
19 19 context "in :xml format" do
20 20 context "with a valid HTTP authentication using the API token" do
21 21 setup do
22 22 @user = User.generate_with_protected!
23 23 @token = Token.generate!(:user => @user, :action => 'api')
24 24 @authorization = ActionController::HttpAuthentication::Basic.encode_credentials(@token.value, 'X')
25 25 get "/news.xml", nil, :authorization => @authorization
26 26 end
27 27
28 28 should_respond_with :success
29 29 should_respond_with_content_type :xml
30 30 should "login as the user" do
31 31 assert_equal @user, User.current
32 32 end
33 33 end
34 34
35 35 context "with an invalid HTTP authentication" do
36 36 setup do
37 37 @user = User.generate_with_protected!
38 38 @token = Token.generate!(:user => @user, :action => 'feeds')
39 39 @authorization = ActionController::HttpAuthentication::Basic.encode_credentials(@token.value, 'X')
40 40 get "/news.xml", nil, :authorization => @authorization
41 41 end
42 42
43 43 should_respond_with :unauthorized
44 44 should_respond_with_content_type :xml
45 45 should "not login as the user" do
46 46 assert_equal User.anonymous, User.current
47 47 end
48 48 end
49 49 end
50 50
51 51 context "in :json format" do
52 52 context "with a valid HTTP authentication" do
53 53 setup do
54 54 @user = User.generate_with_protected!
55 55 @token = Token.generate!(:user => @user, :action => 'api')
56 56 @authorization = ActionController::HttpAuthentication::Basic.encode_credentials(@token.value, 'DoesNotMatter')
57 57 get "/news.json", nil, :authorization => @authorization
58 58 end
59 59
60 60 should_respond_with :success
61 61 should_respond_with_content_type :json
62 62 should "login as the user" do
63 63 assert_equal @user, User.current
64 64 end
65 65 end
66 66
67 67 context "with an invalid HTTP authentication" do
68 68 setup do
69 69 @user = User.generate_with_protected!
70 70 @token = Token.generate!(:user => @user, :action => 'feeds')
71 71 @authorization = ActionController::HttpAuthentication::Basic.encode_credentials(@token.value, 'DoesNotMatter')
72 72 get "/news.json", nil, :authorization => @authorization
73 73 end
74 74
75 75 should_respond_with :unauthorized
76 76 should_respond_with_content_type :json
77 77 should "not login as the user" do
78 78 assert_equal User.anonymous, User.current
79 79 end
80 80 end
81 81 end
82 82
83 83 end
84 84 end
@@ -1,349 +1,349
1 1 # Redmine - project management software
2 2 # Copyright (C) 2006-2010 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 require "#{File.dirname(__FILE__)}/../test_helper"
18 require "#{File.dirname(__FILE__)}/../../test_helper"
19 19
20 class IssuesApiTest < ActionController::IntegrationTest
20 class ApiTest::IssuesTest < ActionController::IntegrationTest
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 :versions,
29 29 :trackers,
30 30 :projects_trackers,
31 31 :issue_categories,
32 32 :enabled_modules,
33 33 :enumerations,
34 34 :attachments,
35 35 :workflows,
36 36 :custom_fields,
37 37 :custom_values,
38 38 :custom_fields_projects,
39 39 :custom_fields_trackers,
40 40 :time_entries,
41 41 :journals,
42 42 :journal_details,
43 43 :queries
44 44
45 45 def setup
46 46 Setting.rest_api_enabled = '1'
47 47 end
48 48
49 49 context "/index.xml" do
50 50 setup do
51 51 get '/issues.xml'
52 52 end
53 53
54 54 should_respond_with :success
55 55 should_respond_with_content_type 'application/xml'
56 56 end
57 57
58 58 context "/index.json" do
59 59 setup do
60 60 get '/issues.json'
61 61 end
62 62
63 63 should_respond_with :success
64 64 should_respond_with_content_type 'application/json'
65 65
66 66 should 'return a valid JSON string' do
67 67 assert ActiveSupport::JSON.decode(response.body)
68 68 end
69 69 end
70 70
71 71 context "/index.xml with filter" do
72 72 setup do
73 73 get '/issues.xml?status_id=5'
74 74 end
75 75
76 76 should_respond_with :success
77 77 should_respond_with_content_type 'application/xml'
78 78 should "show only issues with the status_id" do
79 79 assert_tag :tag => 'issues',
80 80 :children => { :count => Issue.visible.count(:conditions => {:status_id => 5}),
81 81 :only => { :tag => 'issue' } }
82 82 end
83 83 end
84 84
85 85 context "/index.json with filter" do
86 86 setup do
87 87 get '/issues.json?status_id=5'
88 88 end
89 89
90 90 should_respond_with :success
91 91 should_respond_with_content_type 'application/json'
92 92
93 93 should 'return a valid JSON string' do
94 94 assert ActiveSupport::JSON.decode(response.body)
95 95 end
96 96
97 97 should "show only issues with the status_id" do
98 98 json = ActiveSupport::JSON.decode(response.body)
99 99 status_ids_used = json.collect {|j| j['status_id'] }
100 100 assert_equal 3, status_ids_used.length
101 101 assert status_ids_used.all? {|id| id == 5 }
102 102 end
103 103
104 104 end
105 105
106 106 context "/issues/1.xml" do
107 107 setup do
108 108 get '/issues/1.xml'
109 109 end
110 110
111 111 should_respond_with :success
112 112 should_respond_with_content_type 'application/xml'
113 113 end
114 114
115 115 context "/issues/1.json" do
116 116 setup do
117 117 get '/issues/1.json'
118 118 end
119 119
120 120 should_respond_with :success
121 121 should_respond_with_content_type 'application/json'
122 122
123 123 should 'return a valid JSON string' do
124 124 assert ActiveSupport::JSON.decode(response.body)
125 125 end
126 126 end
127 127
128 128 context "POST /issues.xml" do
129 129 setup do
130 130 @issue_count = Issue.count
131 131 @attributes = {:project_id => 1, :subject => 'API test', :tracker_id => 2, :status_id => 3}
132 132 post '/issues.xml', {:issue => @attributes}, :authorization => credentials('jsmith')
133 133 end
134 134
135 135 should_respond_with :created
136 136 should_respond_with_content_type 'application/xml'
137 137
138 138 should "create an issue with the attributes" do
139 139 assert_equal Issue.count, @issue_count + 1
140 140
141 141 issue = Issue.first(:order => 'id DESC')
142 142 @attributes.each do |attribute, value|
143 143 assert_equal value, issue.send(attribute)
144 144 end
145 145 end
146 146 end
147 147
148 148 context "POST /issues.xml with failure" do
149 149 setup do
150 150 @attributes = {:project_id => 1}
151 151 post '/issues.xml', {:issue => @attributes}, :authorization => credentials('jsmith')
152 152 end
153 153
154 154 should_respond_with :unprocessable_entity
155 155 should_respond_with_content_type 'application/xml'
156 156
157 157 should "have an errors tag" do
158 158 assert_tag :errors, :child => {:tag => 'error', :content => "Subject can't be blank"}
159 159 end
160 160 end
161 161
162 162 context "POST /issues.json" do
163 163 setup do
164 164 @issue_count = Issue.count
165 165 @attributes = {:project_id => 1, :subject => 'API test', :tracker_id => 2, :status_id => 3}
166 166 post '/issues.json', {:issue => @attributes}, :authorization => credentials('jsmith')
167 167 end
168 168
169 169 should_respond_with :created
170 170 should_respond_with_content_type 'application/json'
171 171
172 172 should "create an issue with the attributes" do
173 173 assert_equal Issue.count, @issue_count + 1
174 174
175 175 issue = Issue.first(:order => 'id DESC')
176 176 @attributes.each do |attribute, value|
177 177 assert_equal value, issue.send(attribute)
178 178 end
179 179 end
180 180 end
181 181
182 182 context "POST /issues.json with failure" do
183 183 setup do
184 184 @attributes = {:project_id => 1}
185 185 post '/issues.json', {:issue => @attributes}, :authorization => credentials('jsmith')
186 186 end
187 187
188 188 should_respond_with :unprocessable_entity
189 189 should_respond_with_content_type 'application/json'
190 190
191 191 should "have an errors element" do
192 192 json = ActiveSupport::JSON.decode(response.body)
193 193 assert_equal "can't be blank", json.first['subject']
194 194 end
195 195 end
196 196
197 197 context "PUT /issues/1.xml" do
198 198 setup do
199 199 @issue_count = Issue.count
200 200 @journal_count = Journal.count
201 201 @attributes = {:subject => 'API update', :notes => 'A new note'}
202 202
203 203 put '/issues/1.xml', {:issue => @attributes}, :authorization => credentials('jsmith')
204 204 end
205 205
206 206 should_respond_with :ok
207 207 should_respond_with_content_type 'application/xml'
208 208
209 209 should "not create a new issue" do
210 210 assert_equal Issue.count, @issue_count
211 211 end
212 212
213 213 should "create a new journal" do
214 214 assert_equal Journal.count, @journal_count + 1
215 215 end
216 216
217 217 should "add the note to the journal" do
218 218 journal = Journal.last
219 219 assert_equal "A new note", journal.notes
220 220 end
221 221
222 222 should "update the issue" do
223 223 issue = Issue.find(1)
224 224 @attributes.each do |attribute, value|
225 225 assert_equal value, issue.send(attribute) unless attribute == :notes
226 226 end
227 227 end
228 228
229 229 end
230 230
231 231 context "PUT /issues/1.xml with failed update" do
232 232 setup do
233 233 @attributes = {:subject => ''}
234 234 @issue_count = Issue.count
235 235 @journal_count = Journal.count
236 236
237 237 put '/issues/1.xml', {:issue => @attributes}, :authorization => credentials('jsmith')
238 238 end
239 239
240 240 should_respond_with :unprocessable_entity
241 241 should_respond_with_content_type 'application/xml'
242 242
243 243 should "not create a new issue" do
244 244 assert_equal Issue.count, @issue_count
245 245 end
246 246
247 247 should "not create a new journal" do
248 248 assert_equal Journal.count, @journal_count
249 249 end
250 250
251 251 should "have an errors tag" do
252 252 assert_tag :errors, :child => {:tag => 'error', :content => "Subject can't be blank"}
253 253 end
254 254 end
255 255
256 256 context "PUT /issues/1.json" do
257 257 setup do
258 258 @issue_count = Issue.count
259 259 @journal_count = Journal.count
260 260 @attributes = {:subject => 'API update', :notes => 'A new note'}
261 261
262 262 put '/issues/1.json', {:issue => @attributes}, :authorization => credentials('jsmith')
263 263 end
264 264
265 265 should_respond_with :ok
266 266 should_respond_with_content_type 'application/json'
267 267
268 268 should "not create a new issue" do
269 269 assert_equal Issue.count, @issue_count
270 270 end
271 271
272 272 should "create a new journal" do
273 273 assert_equal Journal.count, @journal_count + 1
274 274 end
275 275
276 276 should "add the note to the journal" do
277 277 journal = Journal.last
278 278 assert_equal "A new note", journal.notes
279 279 end
280 280
281 281 should "update the issue" do
282 282 issue = Issue.find(1)
283 283 @attributes.each do |attribute, value|
284 284 assert_equal value, issue.send(attribute) unless attribute == :notes
285 285 end
286 286 end
287 287
288 288 end
289 289
290 290 context "PUT /issues/1.json with failed update" do
291 291 setup do
292 292 @attributes = {:subject => ''}
293 293 @issue_count = Issue.count
294 294 @journal_count = Journal.count
295 295
296 296 put '/issues/1.json', {:issue => @attributes}, :authorization => credentials('jsmith')
297 297 end
298 298
299 299 should_respond_with :unprocessable_entity
300 300 should_respond_with_content_type 'application/json'
301 301
302 302 should "not create a new issue" do
303 303 assert_equal Issue.count, @issue_count
304 304 end
305 305
306 306 should "not create a new journal" do
307 307 assert_equal Journal.count, @journal_count
308 308 end
309 309
310 310 should "have an errors attribute" do
311 311 json = ActiveSupport::JSON.decode(response.body)
312 312 assert_equal "can't be blank", json.first['subject']
313 313 end
314 314 end
315 315
316 316 context "DELETE /issues/1.xml" do
317 317 setup do
318 318 @issue_count = Issue.count
319 319 delete '/issues/1.xml', {}, :authorization => credentials('jsmith')
320 320 end
321 321
322 322 should_respond_with :ok
323 323 should_respond_with_content_type 'application/xml'
324 324
325 325 should "delete the issue" do
326 326 assert_equal Issue.count, @issue_count -1
327 327 assert_nil Issue.find_by_id(1)
328 328 end
329 329 end
330 330
331 331 context "DELETE /issues/1.json" do
332 332 setup do
333 333 @issue_count = Issue.count
334 334 delete '/issues/1.json', {}, :authorization => credentials('jsmith')
335 335 end
336 336
337 337 should_respond_with :ok
338 338 should_respond_with_content_type 'application/json'
339 339
340 340 should "delete the issue" do
341 341 assert_equal Issue.count, @issue_count -1
342 342 assert_nil Issue.find_by_id(1)
343 343 end
344 344 end
345 345
346 346 def credentials(user, password=nil)
347 347 ActionController::HttpAuthentication::Basic.encode_credentials(user, password || user)
348 348 end
349 349 end
@@ -1,99 +1,99
1 1 # Redmine - project management software
2 2 # Copyright (C) 2006-2010 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 require "#{File.dirname(__FILE__)}/../test_helper"
18 require "#{File.dirname(__FILE__)}/../../test_helper"
19 19
20 class ProjectsApiTest < ActionController::IntegrationTest
20 class ApiTest::ProjectsTest < ActionController::IntegrationTest
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
24 24
25 25 def setup
26 26 Setting.rest_api_enabled = '1'
27 27 end
28 28
29 29 def test_index
30 30 get '/projects.xml'
31 31 assert_response :success
32 32 assert_equal 'application/xml', @response.content_type
33 33 end
34 34
35 35 def test_show
36 36 get '/projects/1.xml'
37 37 assert_response :success
38 38 assert_equal 'application/xml', @response.content_type
39 39 end
40 40
41 41 def test_create
42 42 attributes = {:name => 'API test', :identifier => 'api-test'}
43 43 assert_difference 'Project.count' do
44 44 post '/projects.xml', {:project => attributes}, :authorization => credentials('admin')
45 45 end
46 46 assert_response :created
47 47 assert_equal 'application/xml', @response.content_type
48 48 project = Project.first(:order => 'id DESC')
49 49 attributes.each do |attribute, value|
50 50 assert_equal value, project.send(attribute)
51 51 end
52 52 end
53 53
54 54 def test_create_failure
55 55 attributes = {:name => 'API test'}
56 56 assert_no_difference 'Project.count' do
57 57 post '/projects.xml', {:project => attributes}, :authorization => credentials('admin')
58 58 end
59 59 assert_response :unprocessable_entity
60 60 assert_equal 'application/xml', @response.content_type
61 61 assert_tag :errors, :child => {:tag => 'error', :content => "Identifier can't be blank"}
62 62 end
63 63
64 64 def test_update
65 65 attributes = {:name => 'API update'}
66 66 assert_no_difference 'Project.count' do
67 67 put '/projects/1.xml', {:project => attributes}, :authorization => credentials('jsmith')
68 68 end
69 69 assert_response :ok
70 70 assert_equal 'application/xml', @response.content_type
71 71 project = Project.find(1)
72 72 attributes.each do |attribute, value|
73 73 assert_equal value, project.send(attribute)
74 74 end
75 75 end
76 76
77 77 def test_update_failure
78 78 attributes = {:name => ''}
79 79 assert_no_difference 'Project.count' do
80 80 put '/projects/1.xml', {:project => attributes}, :authorization => credentials('jsmith')
81 81 end
82 82 assert_response :unprocessable_entity
83 83 assert_equal 'application/xml', @response.content_type
84 84 assert_tag :errors, :child => {:tag => 'error', :content => "Name can't be blank"}
85 85 end
86 86
87 87 def test_destroy
88 88 assert_difference 'Project.count', -1 do
89 89 delete '/projects/2.xml', {}, :authorization => credentials('admin')
90 90 end
91 91 assert_response :ok
92 92 assert_equal 'application/xml', @response.content_type
93 93 assert_nil Project.find_by_id(2)
94 94 end
95 95
96 96 def credentials(user, password=nil)
97 97 ActionController::HttpAuthentication::Basic.encode_credentials(user, password || user)
98 98 end
99 99 end
@@ -1,80 +1,80
1 require "#{File.dirname(__FILE__)}/../test_helper"
1 require "#{File.dirname(__FILE__)}/../../test_helper"
2 2
3 class ApiTokenLoginTest < ActionController::IntegrationTest
3 class ApiTest::TokenAuthenticationTest < ActionController::IntegrationTest
4 4 fixtures :all
5 5
6 6 def setup
7 7 Setting.rest_api_enabled = '1'
8 8 Setting.login_required = '1'
9 9 end
10 10
11 11 def teardown
12 12 Setting.rest_api_enabled = '0'
13 13 Setting.login_required = '0'
14 14 end
15 15
16 16 # Using the NewsController because it's a simple API.
17 17 context "get /news" do
18 18
19 19 context "in :xml format" do
20 20 context "with a valid api token" do
21 21 setup do
22 22 @user = User.generate_with_protected!
23 23 @token = Token.generate!(:user => @user, :action => 'api')
24 24 get "/news.xml?key=#{@token.value}"
25 25 end
26 26
27 27 should_respond_with :success
28 28 should_respond_with_content_type :xml
29 29 should "login as the user" do
30 30 assert_equal @user, User.current
31 31 end
32 32 end
33 33
34 34 context "with an invalid api token" do
35 35 setup do
36 36 @user = User.generate_with_protected!
37 37 @token = Token.generate!(:user => @user, :action => 'feeds')
38 38 get "/news.xml?key=#{@token.value}"
39 39 end
40 40
41 41 should_respond_with :unauthorized
42 42 should_respond_with_content_type :xml
43 43 should "not login as the user" do
44 44 assert_equal User.anonymous, User.current
45 45 end
46 46 end
47 47 end
48 48
49 49 context "in :json format" do
50 50 context "with a valid api token" do
51 51 setup do
52 52 @user = User.generate_with_protected!
53 53 @token = Token.generate!(:user => @user, :action => 'api')
54 54 get "/news.json?key=#{@token.value}"
55 55 end
56 56
57 57 should_respond_with :success
58 58 should_respond_with_content_type :json
59 59 should "login as the user" do
60 60 assert_equal @user, User.current
61 61 end
62 62 end
63 63
64 64 context "with an invalid api token" do
65 65 setup do
66 66 @user = User.generate_with_protected!
67 67 @token = Token.generate!(:user => @user, :action => 'feeds')
68 68 get "/news.json?key=#{@token.value}"
69 69 end
70 70
71 71 should_respond_with :unauthorized
72 72 should_respond_with_content_type :json
73 73 should "not login as the user" do
74 74 assert_equal User.anonymous, User.current
75 75 end
76 76 end
77 77 end
78 78
79 79 end
80 80 end
@@ -1,188 +1,192
1 1 # redMine - project management software
2 2 # Copyright (C) 2006 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 'test_help'
21 21 require File.expand_path(File.dirname(__FILE__) + '/helper_testcase')
22 22 require File.join(RAILS_ROOT,'test', 'mocks', 'open_id_authentication_mock.rb')
23 23
24 24 require File.expand_path(File.dirname(__FILE__) + '/object_daddy_helpers')
25 25 include ObjectDaddyHelpers
26 26
27 27 class ActiveSupport::TestCase
28 28 # Transactional fixtures accelerate your tests by wrapping each test method
29 29 # in a transaction that's rolled back on completion. This ensures that the
30 30 # test database remains unchanged so your fixtures don't have to be reloaded
31 31 # between every test method. Fewer database queries means faster tests.
32 32 #
33 33 # Read Mike Clark's excellent walkthrough at
34 34 # http://clarkware.com/cgi/blosxom/2005/10/24#Rails10FastTesting
35 35 #
36 36 # Every Active Record database supports transactions except MyISAM tables
37 37 # in MySQL. Turn off transactional fixtures in this case; however, if you
38 38 # don't care one way or the other, switching from MyISAM to InnoDB tables
39 39 # is recommended.
40 40 self.use_transactional_fixtures = true
41 41
42 42 # Instantiated fixtures are slow, but give you @david where otherwise you
43 43 # would need people(:david). If you don't want to migrate your existing
44 44 # test cases which use the @david style and don't mind the speed hit (each
45 45 # instantiated fixtures translates to a database query per test method),
46 46 # then set this back to true.
47 47 self.use_instantiated_fixtures = false
48 48
49 49 # Add more helper methods to be used by all tests here...
50 50
51 51 def log_user(login, password)
52 52 User.anonymous
53 53 get "/login"
54 54 assert_equal nil, session[:user_id]
55 55 assert_response :success
56 56 assert_template "account/login"
57 57 post "/login", :username => login, :password => password
58 58 assert_equal login, User.find(session[:user_id]).login
59 59 end
60 60
61 61 def uploaded_test_file(name, mime)
62 62 ActionController::TestUploadedFile.new(ActiveSupport::TestCase.fixture_path + "/files/#{name}", mime)
63 63 end
64 64
65 65 # Mock out a file
66 66 def self.mock_file
67 67 file = 'a_file.png'
68 68 file.stubs(:size).returns(32)
69 69 file.stubs(:original_filename).returns('a_file.png')
70 70 file.stubs(:content_type).returns('image/png')
71 71 file.stubs(:read).returns(false)
72 72 file
73 73 end
74 74
75 75 def mock_file
76 76 self.class.mock_file
77 77 end
78 78
79 79 # Use a temporary directory for attachment related tests
80 80 def set_tmp_attachments_directory
81 81 Dir.mkdir "#{RAILS_ROOT}/tmp/test" unless File.directory?("#{RAILS_ROOT}/tmp/test")
82 82 Dir.mkdir "#{RAILS_ROOT}/tmp/test/attachments" unless File.directory?("#{RAILS_ROOT}/tmp/test/attachments")
83 83 Attachment.storage_path = "#{RAILS_ROOT}/tmp/test/attachments"
84 84 end
85 85
86 86 def with_settings(options, &block)
87 87 saved_settings = options.keys.inject({}) {|h, k| h[k] = Setting[k].dup; h}
88 88 options.each {|k, v| Setting[k] = v}
89 89 yield
90 90 saved_settings.each {|k, v| Setting[k] = v}
91 91 end
92 92
93 93 def change_user_password(login, new_password)
94 94 user = User.first(:conditions => {:login => login})
95 95 user.password, user.password_confirmation = new_password, new_password
96 96 user.save!
97 97 end
98 98
99 99 def self.ldap_configured?
100 100 @test_ldap = Net::LDAP.new(:host => '127.0.0.1', :port => 389)
101 101 return @test_ldap.bind
102 102 rescue Exception => e
103 103 # LDAP is not listening
104 104 return nil
105 105 end
106 106
107 107 # Returns the path to the test +vendor+ repository
108 108 def self.repository_path(vendor)
109 109 File.join(RAILS_ROOT.gsub(%r{config\/\.\.}, ''), "/tmp/test/#{vendor.downcase}_repository")
110 110 end
111 111
112 112 # Returns true if the +vendor+ test repository is configured
113 113 def self.repository_configured?(vendor)
114 114 File.directory?(repository_path(vendor))
115 115 end
116 116
117 117 def assert_error_tag(options={})
118 118 assert_tag({:tag => 'p', :attributes => { :id => 'errorExplanation' }}.merge(options))
119 119 end
120 120
121 121 # Shoulda macros
122 122 def self.should_render_404
123 123 should_respond_with :not_found
124 124 should_render_template 'common/error'
125 125 end
126 126
127 127 def self.should_have_before_filter(expected_method, options = {})
128 128 should_have_filter('before', expected_method, options)
129 129 end
130 130
131 131 def self.should_have_after_filter(expected_method, options = {})
132 132 should_have_filter('after', expected_method, options)
133 133 end
134 134
135 135 def self.should_have_filter(filter_type, expected_method, options)
136 136 description = "have #{filter_type}_filter :#{expected_method}"
137 137 description << " with #{options.inspect}" unless options.empty?
138 138
139 139 should description do
140 140 klass = "action_controller/filters/#{filter_type}_filter".classify.constantize
141 141 expected = klass.new(:filter, expected_method.to_sym, options)
142 142 assert_equal 1, @controller.class.filter_chain.select { |filter|
143 143 filter.method == expected.method && filter.kind == expected.kind &&
144 144 filter.options == expected.options && filter.class == expected.class
145 145 }.size
146 146 end
147 147 end
148 148
149 149 def self.should_show_the_old_and_new_values_for(prop_key, model, &block)
150 150 context "" do
151 151 setup do
152 152 if block_given?
153 153 instance_eval &block
154 154 else
155 155 @old_value = model.generate!
156 156 @new_value = model.generate!
157 157 end
158 158 end
159 159
160 160 should "use the new value's name" do
161 161 @detail = JournalDetail.generate!(:property => 'attr',
162 162 :old_value => @old_value.id,
163 163 :value => @new_value.id,
164 164 :prop_key => prop_key)
165 165
166 166 assert_match @new_value.name, show_detail(@detail, true)
167 167 end
168 168
169 169 should "use the old value's name" do
170 170 @detail = JournalDetail.generate!(:property => 'attr',
171 171 :old_value => @old_value.id,
172 172 :value => @new_value.id,
173 173 :prop_key => prop_key)
174 174
175 175 assert_match @old_value.name, show_detail(@detail, true)
176 176 end
177 177 end
178 178 end
179 179
180 180 def self.should_create_a_new_user(&block)
181 181 should "create a new user" do
182 182 user = instance_eval &block
183 183 assert user
184 184 assert_kind_of User, user
185 185 assert !user.new_record?
186 186 end
187 187 end
188 188 end
189
190 # Simple module to "namespace" all of the API tests
191 module ApiTest
192 end
General Comments 0
You need to be logged in to leave comments. Login now