1 # frozen_string_literal: true
6 class ChangesetsControllerTest < ActionDispatch::IntegrationTest
8 # test all routes which lead to this controller
11 { :path => "/api/0.6/changesets", :method => :get },
12 { :controller => "api/changesets", :action => "index" }
15 { :path => "/api/0.6/changesets.json", :method => :get },
16 { :controller => "api/changesets", :action => "index", :format => "json" }
19 { :path => "/api/0.6/changesets", :method => :post },
20 { :controller => "api/changesets", :action => "create" }
23 { :path => "/api/0.6/changeset/1", :method => :get },
24 { :controller => "api/changesets", :action => "show", :id => "1" }
27 { :path => "/api/0.6/changeset/1.json", :method => :get },
28 { :controller => "api/changesets", :action => "show", :id => "1", :format => "json" }
31 { :path => "/api/0.6/changeset/1", :method => :put },
32 { :controller => "api/changesets", :action => "update", :id => "1" }
36 { :controller => "api/changesets", :action => "create" },
37 { :path => "/api/0.6/changeset/create", :method => :put }
42 # test the query functionality of changesets
44 private_user = create(:user, :data_public => false)
45 private_user_changeset = create(:changeset, :user => private_user)
46 private_user_closed_changeset = create(:changeset, :closed, :user => private_user)
48 changeset = create(:changeset, :user => user)
49 closed_changeset = create(:changeset, :closed, :user => user, :created_at => Time.utc(2008, 1, 1, 0, 0, 0), :closed_at => Time.utc(2008, 1, 2, 0, 0, 0))
50 changeset2 = create(:changeset, :bbox => [5, 5, 15, 15])
51 changeset3 = create(:changeset, :bbox => [4.5, 4.5, 5, 5])
53 get api_changesets_path(:bbox => "-10,-10, 10, 10")
54 assert_response :success, "can't get changesets in bbox"
55 assert_changesets_in_order [changeset3, changeset2]
57 get api_changesets_path(:bbox => "4.5,4.5,4.6,4.6")
58 assert_response :success, "can't get changesets in bbox"
59 assert_changesets_in_order [changeset3]
61 # not found when looking for changesets of non-existing users
62 get api_changesets_path(:user => User.maximum(:id) + 1)
63 assert_response :not_found
64 assert_equal "text/plain", @response.media_type
65 get api_changesets_path(:display_name => " ")
66 assert_response :not_found
67 assert_equal "text/plain", @response.media_type
69 # can't get changesets of user 1 without authenticating
70 get api_changesets_path(:user => private_user.id)
71 assert_response :not_found, "shouldn't be able to get changesets by non-public user (ID)"
72 get api_changesets_path(:display_name => private_user.display_name)
73 assert_response :not_found, "shouldn't be able to get changesets by non-public user (name)"
75 # but this should work
76 auth_header = bearer_authorization_header private_user
77 get api_changesets_path(:user => private_user.id), :headers => auth_header
78 assert_response :success, "can't get changesets by user ID"
79 assert_changesets_in_order [private_user_changeset, private_user_closed_changeset]
81 get api_changesets_path(:display_name => private_user.display_name), :headers => auth_header
82 assert_response :success, "can't get changesets by user name"
83 assert_changesets_in_order [private_user_changeset, private_user_closed_changeset]
86 get api_changesets_path(:display_name => private_user.display_name), :headers => auth_header, :params => { :format => "json" }
87 assert_response :success, "can't get changesets by user name"
89 js = ActiveSupport::JSON.decode(@response.body)
92 assert_equal Settings.api_version, js["version"]
93 assert_equal Settings.generator, js["generator"]
94 assert_equal 2, js["changesets"].count
96 # check that the correct error is given when we provide both UID and name
97 get api_changesets_path(:user => private_user.id,
98 :display_name => private_user.display_name), :headers => auth_header
99 assert_response :bad_request, "should be a bad request to have both ID and name specified"
101 get api_changesets_path(:user => private_user.id, :open => true), :headers => auth_header
102 assert_response :success, "can't get changesets by user and open"
103 assert_changesets_in_order [private_user_changeset]
105 get api_changesets_path(:time => "2007-12-31"), :headers => auth_header
106 assert_response :success, "can't get changesets by time-since"
107 assert_changesets_in_order [changeset3, changeset2, changeset, private_user_changeset, private_user_closed_changeset, closed_changeset]
109 get api_changesets_path(:time => "2008-01-01T12:34Z"), :headers => auth_header
110 assert_response :success, "can't get changesets by time-since with hour"
111 assert_changesets_in_order [changeset3, changeset2, changeset, private_user_changeset, private_user_closed_changeset, closed_changeset]
113 get api_changesets_path(:time => "2007-12-31T23:59Z,2008-01-02T00:01Z"), :headers => auth_header
114 assert_response :success, "can't get changesets by time-range"
115 assert_changesets_in_order [closed_changeset]
117 get api_changesets_path(:open => "true"), :headers => auth_header
118 assert_response :success, "can't get changesets by open-ness"
119 assert_changesets_in_order [changeset3, changeset2, changeset, private_user_changeset]
121 get api_changesets_path(:closed => "true"), :headers => auth_header
122 assert_response :success, "can't get changesets by closed-ness"
123 assert_changesets_in_order [private_user_closed_changeset, closed_changeset]
125 get api_changesets_path(:closed => "true", :user => private_user.id), :headers => auth_header
126 assert_response :success, "can't get changesets by closed-ness and user"
127 assert_changesets_in_order [private_user_closed_changeset]
129 get api_changesets_path(:closed => "true", :user => user.id), :headers => auth_header
130 assert_response :success, "can't get changesets by closed-ness and user"
131 assert_changesets_in_order [closed_changeset]
133 get api_changesets_path(:changesets => "#{private_user_changeset.id},#{changeset.id},#{closed_changeset.id}"), :headers => auth_header
134 assert_response :success, "can't get changesets by id (as comma-separated string)"
135 assert_changesets_in_order [changeset, private_user_changeset, closed_changeset]
137 get api_changesets_path(:changesets => ""), :headers => auth_header
138 assert_response :bad_request, "should be a bad request since changesets is empty"
142 # test the query functionality of changesets with the limit parameter
145 changeset1 = create(:changeset, :closed, :user => user, :created_at => Time.utc(2008, 1, 1, 0, 0, 0), :closed_at => Time.utc(2008, 1, 2, 0, 0, 0))
146 changeset2 = create(:changeset, :closed, :user => user, :created_at => Time.utc(2008, 2, 1, 0, 0, 0), :closed_at => Time.utc(2008, 2, 2, 0, 0, 0))
147 changeset3 = create(:changeset, :closed, :user => user, :created_at => Time.utc(2008, 3, 1, 0, 0, 0), :closed_at => Time.utc(2008, 3, 2, 0, 0, 0))
148 changeset4 = create(:changeset, :closed, :user => user, :created_at => Time.utc(2008, 4, 1, 0, 0, 0), :closed_at => Time.utc(2008, 4, 2, 0, 0, 0))
149 changeset5 = create(:changeset, :closed, :user => user, :created_at => Time.utc(2008, 5, 1, 0, 0, 0), :closed_at => Time.utc(2008, 5, 2, 0, 0, 0))
151 get api_changesets_path
152 assert_response :success
153 assert_changesets_in_order [changeset5, changeset4, changeset3, changeset2, changeset1]
155 get api_changesets_path(:limit => "3")
156 assert_response :success
157 assert_changesets_in_order [changeset5, changeset4, changeset3]
159 get api_changesets_path(:limit => "0")
160 assert_response :bad_request
162 get api_changesets_path(:limit => Settings.max_changeset_query_limit)
163 assert_response :success
164 assert_changesets_in_order [changeset5, changeset4, changeset3, changeset2, changeset1]
166 get api_changesets_path(:limit => Settings.max_changeset_query_limit + 1)
167 assert_response :bad_request
171 # test the query functionality of sequential changesets with order and time parameters
174 changeset1 = create(:changeset, :closed, :user => user, :created_at => Time.utc(2008, 1, 1, 0, 0, 0), :closed_at => Time.utc(2008, 1, 2, 0, 0, 0))
175 changeset2 = create(:changeset, :closed, :user => user, :created_at => Time.utc(2008, 2, 1, 0, 0, 0), :closed_at => Time.utc(2008, 2, 2, 0, 0, 0))
176 changeset3 = create(:changeset, :closed, :user => user, :created_at => Time.utc(2008, 3, 1, 0, 0, 0), :closed_at => Time.utc(2008, 3, 2, 0, 0, 0))
177 changeset4 = create(:changeset, :closed, :user => user, :created_at => Time.utc(2008, 4, 1, 0, 0, 0), :closed_at => Time.utc(2008, 4, 2, 0, 0, 0))
178 changeset5 = create(:changeset, :closed, :user => user, :created_at => Time.utc(2008, 5, 1, 0, 0, 0), :closed_at => Time.utc(2008, 5, 2, 0, 0, 0))
179 changeset6 = create(:changeset, :closed, :user => user, :created_at => Time.utc(2008, 6, 1, 0, 0, 0), :closed_at => Time.utc(2008, 6, 2, 0, 0, 0))
181 get api_changesets_path
182 assert_response :success
183 assert_changesets_in_order [changeset6, changeset5, changeset4, changeset3, changeset2, changeset1]
185 get api_changesets_path(:order => "oldest")
186 assert_response :success
187 assert_changesets_in_order [changeset1, changeset2, changeset3, changeset4, changeset5, changeset6]
190 # lower time bound at the opening time of a changeset
191 ["2008-02-01T00:00:00Z", "2008-05-15T00:00:00Z", [changeset5, changeset4, changeset3, changeset2], [changeset5, changeset4, changeset3, changeset2]],
192 # lower time bound in the middle of a changeset
193 ["2008-02-01T12:00:00Z", "2008-05-15T00:00:00Z", [changeset5, changeset4, changeset3, changeset2], [changeset5, changeset4, changeset3]],
194 # lower time bound at the closing time of a changeset
195 ["2008-02-02T00:00:00Z", "2008-05-15T00:00:00Z", [changeset5, changeset4, changeset3, changeset2], [changeset5, changeset4, changeset3]],
196 # lower time bound after the closing time of a changeset
197 ["2008-02-02T00:00:01Z", "2008-05-15T00:00:00Z", [changeset5, changeset4, changeset3], [changeset5, changeset4, changeset3]],
198 # upper time bound in the middle of a changeset
199 ["2007-09-09T12:00:00Z", "2008-04-01T12:00:00Z", [changeset4, changeset3, changeset2, changeset1], [changeset4, changeset3, changeset2, changeset1]],
201 ["2009-02-02T00:00:01Z", "2018-05-15T00:00:00Z", [], []]
202 ].each do |from, to, interval_changesets, point_changesets|
203 get api_changesets_path(:time => "#{from},#{to}")
204 assert_response :success
205 assert_changesets_in_order interval_changesets
207 get api_changesets_path(:from => from, :to => to)
208 assert_response :success
209 assert_changesets_in_order point_changesets
211 get api_changesets_path(:from => from, :to => to, :order => "oldest")
212 assert_response :success
213 assert_changesets_in_order point_changesets.reverse
218 # test the query functionality of overlapping changesets with order and time parameters
219 def test_index_order_overlapping
221 changeset1 = create(:changeset, :closed, :user => user, :created_at => Time.utc(2015, 6, 4, 17, 0, 0), :closed_at => Time.utc(2015, 6, 4, 17, 0, 0))
222 changeset2 = create(:changeset, :closed, :user => user, :created_at => Time.utc(2015, 6, 4, 16, 0, 0), :closed_at => Time.utc(2015, 6, 4, 18, 0, 0))
223 changeset3 = create(:changeset, :closed, :user => user, :created_at => Time.utc(2015, 6, 4, 14, 0, 0), :closed_at => Time.utc(2015, 6, 4, 20, 0, 0))
224 changeset4 = create(:changeset, :closed, :user => user, :created_at => Time.utc(2015, 6, 3, 23, 0, 0), :closed_at => Time.utc(2015, 6, 4, 23, 0, 0))
225 create(:changeset, :closed, :user => user, :created_at => Time.utc(2015, 6, 2, 23, 0, 0), :closed_at => Time.utc(2015, 6, 3, 23, 0, 0))
227 get api_changesets_path(:time => "2015-06-04T00:00:00Z")
228 assert_response :success
229 assert_changesets_in_order [changeset1, changeset2, changeset3, changeset4]
231 get api_changesets_path(:from => "2015-06-04T00:00:00Z")
232 assert_response :success
233 assert_changesets_in_order [changeset1, changeset2, changeset3]
235 get api_changesets_path(:from => "2015-06-04T00:00:00Z", :order => "oldest")
236 assert_response :success
237 assert_changesets_in_order [changeset3, changeset2, changeset1]
239 get api_changesets_path(:time => "2015-06-04T16:00:00Z,2015-06-04T17:30:00Z")
240 assert_response :success
241 assert_changesets_in_order [changeset1, changeset2, changeset3, changeset4]
243 get api_changesets_path(:from => "2015-06-04T16:00:00Z", :to => "2015-06-04T17:30:00Z")
244 assert_response :success
245 assert_changesets_in_order [changeset1, changeset2]
247 get api_changesets_path(:from => "2015-06-04T16:00:00Z", :to => "2015-06-04T17:30:00Z", :order => "oldest")
248 assert_response :success
249 assert_changesets_in_order [changeset2, changeset1]
253 # check that errors are returned if garbage is inserted
255 def test_index_invalid
258 ";drop table users;"].each do |bbox|
259 get api_changesets_path(:bbox => bbox)
260 assert_response :bad_request, "'#{bbox}' isn't a bbox"
265 ";drop table users;",
267 "-,-"].each do |time|
268 get api_changesets_path(:time => time)
269 assert_response :bad_request, "'#{time}' isn't a valid time range"
276 get api_changesets_path(:user => uid)
277 assert_response :bad_request, "'#{uid}' isn't a valid user ID"
280 get api_changesets_path(:order => "oldest", :time => "2008-01-01T00:00Z,2018-01-01T00:00Z")
281 assert_response :bad_request, "cannot use order=oldest with time"
284 # -----------------------
285 # Test simple changeset creation
286 # -----------------------
290 auth_header = bearer_authorization_header user
291 # Create the first user's changeset
292 xml = "<osm><changeset>" \
293 "<tag k='created_by' v='osm test suite checking changesets'/>" \
296 assert_difference "Changeset.count", 1 do
297 post api_changesets_path, :params => xml, :headers => auth_header
298 assert_response :success, "Creation of changeset did not return success status"
300 newid = @response.body.to_i
302 # check end time, should be an hour ahead of creation time
303 changeset = Changeset.find(newid)
304 duration = changeset.closed_at - changeset.created_at
305 # the difference can either be a rational, or a floating point number
306 # of seconds, depending on the code path taken :-(
307 if duration.instance_of?(Rational)
308 assert_equal Rational(1, 24), duration, "initial idle timeout should be an hour (#{changeset.created_at} -> #{changeset.closed_at})"
310 # must be number of seconds...
311 assert_equal 3600, duration.round, "initial idle timeout should be an hour (#{changeset.created_at} -> #{changeset.closed_at})"
314 assert_equal [user], changeset.subscribers
315 assert_predicate changeset, :num_type_changes_in_sync?
318 def test_create_invalid
319 auth_header = bearer_authorization_header create(:user, :data_public => false)
320 xml = "<osm><changeset></osm>"
321 post api_changesets_path, :params => xml, :headers => auth_header
322 assert_require_public_data
324 ## Try the public user
325 auth_header = bearer_authorization_header
326 xml = "<osm><changeset></osm>"
327 post api_changesets_path, :params => xml, :headers => auth_header
328 assert_response :bad_request, "creating a invalid changeset should fail"
331 def test_create_invalid_no_content
332 ## First check with no auth
333 post api_changesets_path
334 assert_response :unauthorized, "shouldn't be able to create a changeset with no auth"
336 ## Now try to with a non-public user
337 auth_header = bearer_authorization_header create(:user, :data_public => false)
338 post api_changesets_path, :headers => auth_header
339 assert_require_public_data
341 ## Try an inactive user
342 auth_header = bearer_authorization_header create(:user, :pending)
343 post api_changesets_path, :headers => auth_header
346 ## Now try to use a normal user
347 auth_header = bearer_authorization_header
348 post api_changesets_path, :headers => auth_header
349 assert_response :bad_request, "creating a changeset with no content should fail"
352 def test_create_wrong_method
353 auth_header = bearer_authorization_header
355 put api_changesets_path, :headers => auth_header
356 assert_response :not_found
357 assert_template "rescues/routing_error"
360 def test_create_legacy_path
361 auth_header = bearer_authorization_header
362 xml = "<osm><changeset></changeset></osm>"
364 assert_difference "Changeset.count", 1 do
365 put "/api/0.6/changeset/create", :params => xml, :headers => auth_header
368 assert_response :success, "Creation of changeset did not return success status"
369 assert_equal Changeset.last.id, @response.body.to_i
373 # check that the changeset can be shown and returns the correct
374 # document structure.
376 changeset = create(:changeset)
378 get api_changeset_path(changeset)
379 assert_response :success, "cannot get first changeset"
381 assert_dom "osm[version='#{Settings.api_version}'][generator='#{Settings.generator}']", 1
382 assert_single_changeset changeset do
383 assert_dom "> discussion", 0
386 get api_changeset_path(changeset, :include_discussion => true)
387 assert_response :success, "cannot get first changeset with comments"
389 assert_dom "osm[version='#{Settings.api_version}'][generator='#{Settings.generator}']", 1
390 assert_single_changeset changeset do
391 assert_dom "> discussion", 1
392 assert_dom "> discussion > comment", 0
396 def test_show_comments
397 # all comments visible
398 changeset = create(:changeset, :closed)
399 comment1, comment2, comment3 = create_list(:changeset_comment, 3, :changeset_id => changeset.id)
401 get api_changeset_path(changeset, :include_discussion => true)
402 assert_response :success, "cannot get closed changeset with comments"
404 assert_dom "osm[version='#{Settings.api_version}'][generator='#{Settings.generator}']", 1 do
405 assert_single_changeset changeset do
406 assert_dom "> discussion", 1 do
407 assert_dom "> comment", 3 do |dom_comments|
408 assert_dom dom_comments[0], "> @id", comment1.id.to_s
409 assert_dom dom_comments[0], "> @visible", "true"
410 assert_dom dom_comments[1], "> @id", comment2.id.to_s
411 assert_dom dom_comments[1], "> @visible", "true"
412 assert_dom dom_comments[2], "> @id", comment3.id.to_s
413 assert_dom dom_comments[2], "> @visible", "true"
419 # one hidden comment not included because not asked for
420 comment2.update(:visible => false)
423 get api_changeset_path(changeset, :include_discussion => true)
424 assert_response :success, "cannot get closed changeset with comments"
426 assert_dom "osm[version='#{Settings.api_version}'][generator='#{Settings.generator}']", 1
427 assert_single_changeset changeset do
428 assert_dom "> discussion", 1 do
429 assert_dom "> comment", 2 do |dom_comments|
430 assert_dom dom_comments[0], "> @id", comment1.id.to_s
431 assert_dom dom_comments[0], "> @visible", "true"
432 assert_dom dom_comments[1], "> @id", comment3.id.to_s
433 assert_dom dom_comments[1], "> @visible", "true"
438 # one hidden comment not included because no permissions
439 get api_changeset_path(changeset, :include_discussion => true, :show_hidden_comments => true)
440 assert_response :success, "cannot get closed changeset with comments"
442 assert_dom "osm[version='#{Settings.api_version}'][generator='#{Settings.generator}']", 1
443 assert_single_changeset changeset do
444 assert_dom "> discussion", 1 do
445 assert_dom "> comment", 2 do |dom_comments|
446 assert_dom dom_comments[0], "> @id", comment1.id.to_s
447 assert_dom dom_comments[0], "> @visible", "true"
448 # maybe will show an empty comment element with visible=false in the future
449 assert_dom dom_comments[1], "> @id", comment3.id.to_s
450 assert_dom dom_comments[1], "> @visible", "true"
455 # one hidden comment shown to moderators
456 moderator_user = create(:moderator_user)
457 auth_header = bearer_authorization_header moderator_user
458 get api_changeset_path(changeset, :include_discussion => true, :show_hidden_comments => true), :headers => auth_header
459 assert_response :success, "cannot get closed changeset with comments"
461 assert_dom "osm[version='#{Settings.api_version}'][generator='#{Settings.generator}']", 1
462 assert_single_changeset changeset do
463 assert_dom "> discussion", 1 do
464 assert_dom "> comment", 3 do |dom_comments|
465 assert_dom dom_comments[0], "> @id", comment1.id.to_s
466 assert_dom dom_comments[0], "> @visible", "true"
467 assert_dom dom_comments[1], "> @id", comment2.id.to_s
468 assert_dom dom_comments[1], "> @visible", "false"
469 assert_dom dom_comments[2], "> @id", comment3.id.to_s
470 assert_dom dom_comments[2], "> @visible", "true"
477 changeset = create(:changeset, :closed)
478 create(:changeset_tag, :changeset => changeset, :k => "created_by", :v => "JOSM/1.5 (18364)")
479 create(:changeset_tag, :changeset => changeset, :k => "comment", :v => "changeset comment")
481 get api_changeset_path(changeset)
483 assert_response :success
484 assert_dom "osm[version='#{Settings.api_version}'][generator='#{Settings.generator}']", 1
485 assert_single_changeset changeset do
486 assert_dom "> tag", 2
487 assert_dom "> tag[k='created_by'][v='JOSM/1.5 (18364)']", 1
488 assert_dom "> tag[k='comment'][v='changeset comment']", 1
493 changeset = create(:changeset)
495 get api_changeset_path(changeset, :format => "json")
496 assert_response :success, "cannot get first changeset"
498 js = ActiveSupport::JSON.decode(@response.body)
501 assert_equal Settings.api_version, js["version"]
502 assert_equal Settings.generator, js["generator"]
503 assert_single_changeset_json changeset, js
504 assert_nil js["changeset"]["tags"]
505 assert_nil js["changeset"]["comments"]
506 assert_equal changeset.user.id, js["changeset"]["uid"]
507 assert_equal changeset.user.display_name, js["changeset"]["user"]
509 get api_changeset_path(changeset, :format => "json", :include_discussion => true)
510 assert_response :success, "cannot get first changeset with comments"
512 js = ActiveSupport::JSON.decode(@response.body)
514 assert_equal Settings.api_version, js["version"]
515 assert_equal Settings.generator, js["generator"]
516 assert_single_changeset_json changeset, js
517 assert_nil js["changeset"]["tags"]
518 assert_nil js["changeset"]["min_lat"]
519 assert_nil js["changeset"]["min_lon"]
520 assert_nil js["changeset"]["max_lat"]
521 assert_nil js["changeset"]["max_lon"]
522 assert_equal 0, js["changeset"]["comments"].count
525 def test_show_comments_json
526 # all comments visible
527 changeset = create(:changeset, :closed)
528 comment0, comment1, comment2 = create_list(:changeset_comment, 3, :changeset_id => changeset.id)
530 get api_changeset_path(changeset, :format => "json", :include_discussion => true)
531 assert_response :success, "cannot get closed changeset with comments"
533 js = ActiveSupport::JSON.decode(@response.body)
535 assert_equal Settings.api_version, js["version"]
536 assert_equal Settings.generator, js["generator"]
537 assert_single_changeset_json changeset, js
538 assert_equal 3, js["changeset"]["comments"].count
539 assert_equal comment0.id, js["changeset"]["comments"][0]["id"]
540 assert js["changeset"]["comments"][0]["visible"]
541 assert_equal comment1.id, js["changeset"]["comments"][1]["id"]
542 assert js["changeset"]["comments"][1]["visible"]
543 assert_equal comment2.id, js["changeset"]["comments"][2]["id"]
544 assert js["changeset"]["comments"][2]["visible"]
546 # one hidden comment not included because not asked for
547 comment1.update(:visible => false)
550 get api_changeset_path(changeset, :format => "json", :include_discussion => true)
551 assert_response :success, "cannot get closed changeset with comments"
553 js = ActiveSupport::JSON.decode(@response.body)
555 assert_equal Settings.api_version, js["version"]
556 assert_equal Settings.generator, js["generator"]
557 assert_single_changeset_json changeset, js
558 assert_equal 2, js["changeset"]["comments"].count
559 assert_equal comment0.id, js["changeset"]["comments"][0]["id"]
560 assert js["changeset"]["comments"][0]["visible"]
561 assert_equal comment2.id, js["changeset"]["comments"][1]["id"]
562 assert js["changeset"]["comments"][1]["visible"]
564 # one hidden comment not included because no permissions
565 get api_changeset_path(changeset, :format => "json", :include_discussion => true, :show_hidden_comments => true)
566 assert_response :success, "cannot get closed changeset with comments"
568 js = ActiveSupport::JSON.decode(@response.body)
570 assert_equal Settings.api_version, js["version"]
571 assert_equal Settings.generator, js["generator"]
572 assert_single_changeset_json changeset, js
573 assert_equal 2, js["changeset"]["comments"].count
574 assert_equal comment0.id, js["changeset"]["comments"][0]["id"]
575 assert js["changeset"]["comments"][0]["visible"]
576 # maybe will show an empty comment element with visible=false in the future
577 assert_equal comment2.id, js["changeset"]["comments"][1]["id"]
578 assert js["changeset"]["comments"][1]["visible"]
580 # one hidden comment shown to moderators
581 moderator_user = create(:moderator_user)
582 auth_header = bearer_authorization_header moderator_user
583 get api_changeset_path(changeset, :format => "json", :include_discussion => true, :show_hidden_comments => true), :headers => auth_header
584 assert_response :success, "cannot get closed changeset with comments"
586 js = ActiveSupport::JSON.decode(@response.body)
588 assert_equal Settings.api_version, js["version"]
589 assert_equal Settings.generator, js["generator"]
590 assert_single_changeset_json changeset, js
591 assert_equal 3, js["changeset"]["comments"].count
592 assert_equal comment0.id, js["changeset"]["comments"][0]["id"]
593 assert js["changeset"]["comments"][0]["visible"]
594 assert_equal comment1.id, js["changeset"]["comments"][1]["id"]
595 assert_not js["changeset"]["comments"][1]["visible"]
596 assert_equal comment2.id, js["changeset"]["comments"][2]["id"]
597 assert js["changeset"]["comments"][2]["visible"]
600 def test_show_tags_json
601 changeset = create(:changeset, :closed)
602 create(:changeset_tag, :changeset => changeset, :k => "created_by", :v => "JOSM/1.5 (18364)")
603 create(:changeset_tag, :changeset => changeset, :k => "comment", :v => "changeset comment")
605 get api_changeset_path(changeset, :format => "json")
607 assert_response :success
608 js = ActiveSupport::JSON.decode(@response.body)
610 assert_equal Settings.api_version, js["version"]
611 assert_equal Settings.generator, js["generator"]
612 assert_single_changeset_json changeset, js
613 assert_equal 2, js["changeset"]["tags"].count
614 assert_equal "JOSM/1.5 (18364)", js["changeset"]["tags"]["created_by"]
615 assert_equal "changeset comment", js["changeset"]["tags"]["comment"]
618 def test_show_bbox_json
619 changeset = create(:changeset, :bbox => [5, -5, 12, 15])
621 get api_changeset_path(changeset, :format => "json")
622 assert_response :success, "cannot get first changeset"
624 js = ActiveSupport::JSON.decode(@response.body)
626 assert_equal(-5, js["changeset"]["min_lat"])
627 assert_equal 5, js["changeset"]["min_lon"]
628 assert_equal 15, js["changeset"]["max_lat"]
629 assert_equal 12, js["changeset"]["max_lon"]
633 # check that a changeset that doesn't exist returns an appropriate message
634 def test_show_not_found
635 [0, -32, 233455644, "afg", "213"].each do |id|
636 get api_changeset_path(id)
637 assert_response :not_found, "should get a not found"
638 rescue ActionController::UrlGenerationError => e
639 assert_match(/No route matches/, e.to_s)
643 def test_repeated_changeset_create
645 auth_header = bearer_authorization_header
647 # create a temporary changeset
648 xml = "<osm><changeset>" \
649 "<tag k='created_by' v='osm test suite checking changesets'/>" \
651 assert_difference "Changeset.count", 1 do
652 post api_changesets_path, :params => xml, :headers => auth_header
654 assert_response :success
659 # check updating tags on a changeset
660 def test_changeset_update
661 private_user = create(:user, :data_public => false)
662 private_changeset = create(:changeset, :user => private_user)
664 changeset = create(:changeset, :user => user)
666 ## First try with a non-public user
667 new_changeset = create_changeset_xml(:user => private_user)
668 new_tag = XML::Node.new "tag"
669 new_tag["k"] = "tagtesting"
670 new_tag["v"] = "valuetesting"
671 new_changeset.find("//osm/changeset").first << new_tag
673 # try without any authorization
674 put api_changeset_path(private_changeset), :params => new_changeset.to_s
675 assert_response :unauthorized
677 # try with the wrong authorization
678 auth_header = bearer_authorization_header
679 put api_changeset_path(private_changeset), :params => new_changeset.to_s, :headers => auth_header
680 assert_response :conflict
682 # now this should get an unauthorized
683 auth_header = bearer_authorization_header private_user
684 put api_changeset_path(private_changeset), :params => new_changeset.to_s, :headers => auth_header
685 assert_require_public_data "user with their data non-public, shouldn't be able to edit their changeset"
687 ## Now try with the public user
688 new_changeset = create_changeset_xml(:id => 1)
689 new_tag = XML::Node.new "tag"
690 new_tag["k"] = "tagtesting"
691 new_tag["v"] = "valuetesting"
692 new_changeset.find("//osm/changeset").first << new_tag
694 # try without any authorization
695 put api_changeset_path(changeset), :params => new_changeset.to_s
696 assert_response :unauthorized
698 # try with the wrong authorization
699 auth_header = bearer_authorization_header
700 put api_changeset_path(changeset), :params => new_changeset.to_s, :headers => auth_header
701 assert_response :conflict
703 # now this should work...
704 auth_header = bearer_authorization_header user
705 put api_changeset_path(changeset), :params => new_changeset.to_s, :headers => auth_header
706 assert_response :success
708 assert_select "osm>changeset[id='#{changeset.id}']", 1
709 assert_select "osm>changeset>tag", 1
710 assert_select "osm>changeset>tag[k='tagtesting'][v='valuetesting']", 1
714 # check that a user different from the one who opened the changeset
716 def test_changeset_update_invalid
717 auth_header = bearer_authorization_header
719 changeset = create(:changeset)
720 new_changeset = create_changeset_xml(:user => changeset.user, :id => changeset.id)
721 new_tag = XML::Node.new "tag"
722 new_tag["k"] = "testing"
723 new_tag["v"] = "testing"
724 new_changeset.find("//osm/changeset").first << new_tag
726 put api_changeset_path(changeset), :params => new_changeset.to_s, :headers => auth_header
727 assert_response :conflict
731 # check that a changeset can contain a certain max number of changes.
732 ## FIXME should be changed to an integration test due to the with_controller
733 def test_changeset_limits
735 auth_header = bearer_authorization_header user
737 # create an old changeset to ensure we have the maximum rate limit
738 create(:changeset, :user => user, :created_at => Time.now.utc - 28.days)
740 # open a new changeset
741 xml = "<osm><changeset/></osm>"
742 post api_changesets_path, :params => xml, :headers => auth_header
743 assert_response :success, "can't create a new changeset"
744 changeset_id = @response.body.to_i
746 # start the counter just short of where the changeset should finish.
748 # alter the database to set the counter on the changeset directly,
749 # otherwise it takes about 6 minutes to fill all of them.
750 changeset = Changeset.find(changeset_id)
751 changeset.num_changes = Changeset::MAX_ELEMENTS - offset
754 with_controller(NodesController.new) do
756 xml = "<osm><node changeset='#{changeset_id}' lat='0.0' lon='0.0'/></osm>"
757 post api_nodes_path, :params => xml, :headers => auth_header
758 assert_response :success, "can't create a new node"
759 node_id = @response.body.to_i
761 get api_node_path(node_id)
762 assert_response :success, "can't read back new node"
763 node_doc = XML::Parser.string(@response.body).parse
764 node_xml = node_doc.find("//osm/node").first
766 # loop until we fill the changeset with nodes
768 node_xml["lat"] = rand.to_s
769 node_xml["lon"] = rand.to_s
770 node_xml["version"] = (i + 1).to_s
772 put api_node_path(node_id), :params => node_doc.to_s, :headers => auth_header
773 assert_response :success, "attempt #{i} should have succeeded"
776 # trying again should fail
777 node_xml["lat"] = rand.to_s
778 node_xml["lon"] = rand.to_s
779 node_xml["version"] = offset.to_s
781 put api_node_path(node_id), :params => node_doc.to_s, :headers => auth_header
782 assert_response :conflict, "final attempt should have failed"
785 changeset = Changeset.find(changeset_id)
786 assert_equal Changeset::MAX_ELEMENTS + 1, changeset.num_changes
788 # check that the changeset is now closed as well
789 assert_not(changeset.open?,
790 "changeset should have been auto-closed by exceeding " \
797 # check that the output consists of one specific changeset
798 def assert_single_changeset(changeset, &)
799 assert_dom "> changeset", 1 do
800 assert_dom "> @id", changeset.id.to_s
801 assert_dom "> @created_at", changeset.created_at.xmlschema
803 assert_dom "> @open", "true"
804 assert_dom "> @closed_at", 0
806 assert_dom "> @open", "false"
807 assert_dom "> @closed_at", changeset.closed_at.xmlschema
809 assert_dom "> @comments_count", changeset.comments.length.to_s
810 assert_dom "> @changes_count", changeset.num_changes.to_s
811 yield if block_given?
815 def assert_single_changeset_json(changeset, js)
816 assert_equal changeset.id, js["changeset"]["id"]
817 assert_equal changeset.created_at.xmlschema, js["changeset"]["created_at"]
819 assert js["changeset"]["open"]
820 assert_nil js["changeset"]["closed_at"]
822 assert_not js["changeset"]["open"]
823 assert_equal changeset.closed_at.xmlschema, js["changeset"]["closed_at"]
825 assert_equal changeset.comments.length, js["changeset"]["comments_count"]
826 assert_equal changeset.num_changes, js["changeset"]["changes_count"]
830 # check that certain changesets exist in the output in the specified order
831 def assert_changesets_in_order(changesets)
832 assert_select "osm>changeset", changesets.size
833 changesets.each_with_index do |changeset, index|
834 assert_select "osm>changeset:nth-child(#{index + 1})[id='#{changeset.id}']", 1
839 # build XML for changesets
840 def create_changeset_xml(user: nil, id: nil)
841 root = XML::Document.new
842 root.root = XML::Node.new "osm"
843 changeset = XML::Node.new "changeset"
845 changeset["user"] = user.display_name
846 changeset["uid"] = user.id.to_s
848 changeset["id"] = id.to_s if id
849 root.root << changeset