2 require_relative "elements_test_helper"
5 class WaysControllerTest < ActionDispatch::IntegrationTest
6 include ElementsTestHelper
9 # test all routes which lead to this controller
12 { :path => "/api/0.6/ways", :method => :get },
13 { :controller => "api/ways", :action => "index" }
16 { :path => "/api/0.6/ways.json", :method => :get },
17 { :controller => "api/ways", :action => "index", :format => "json" }
20 { :path => "/api/0.6/ways", :method => :post },
21 { :controller => "api/ways", :action => "create" }
24 { :path => "/api/0.6/way/1", :method => :get },
25 { :controller => "api/ways", :action => "show", :id => "1" }
28 { :path => "/api/0.6/way/1.json", :method => :get },
29 { :controller => "api/ways", :action => "show", :id => "1", :format => "json" }
32 { :path => "/api/0.6/way/1/full", :method => :get },
33 { :controller => "api/ways", :action => "show", :full => true, :id => "1" }
36 { :path => "/api/0.6/way/1/full.json", :method => :get },
37 { :controller => "api/ways", :action => "show", :full => true, :id => "1", :format => "json" }
40 { :path => "/api/0.6/way/1", :method => :put },
41 { :controller => "api/ways", :action => "update", :id => "1" }
44 { :path => "/api/0.6/way/1", :method => :delete },
45 { :controller => "api/ways", :action => "destroy", :id => "1" }
49 { :controller => "api/ways", :action => "create" },
50 { :path => "/api/0.6/way/create", :method => :put }
55 # test fetching multiple ways
58 way2 = create(:way, :deleted)
62 # check error when no parameter provided
64 assert_response :bad_request
66 # check error when no parameter value provided
67 get api_ways_path(:ways => "")
68 assert_response :bad_request
71 get api_ways_path(:ways => "#{way1.id},#{way2.id},#{way3.id},#{way4.id}")
72 assert_response :success
73 assert_select "osm" do
74 assert_select "way", :count => 4
75 assert_select "way[id='#{way1.id}'][visible='true']", :count => 1
76 assert_select "way[id='#{way2.id}'][visible='false']", :count => 1
77 assert_select "way[id='#{way3.id}'][visible='true']", :count => 1
78 assert_select "way[id='#{way4.id}'][visible='true']", :count => 1
81 # test a working call with json format
82 get api_ways_path(:ways => "#{way1.id},#{way2.id},#{way3.id},#{way4.id}", :format => "json")
84 js = ActiveSupport::JSON.decode(@response.body)
86 assert_equal 4, js["elements"].count
87 assert_equal 4, (js["elements"].count { |a| a["type"] == "way" })
88 assert_equal 1, (js["elements"].count { |a| a["id"] == way1.id && a["visible"].nil? })
89 assert_equal 1, (js["elements"].count { |a| a["id"] == way2.id && a["visible"] == false })
90 assert_equal 1, (js["elements"].count { |a| a["id"] == way3.id && a["visible"].nil? })
91 assert_equal 1, (js["elements"].count { |a| a["id"] == way4.id && a["visible"].nil? })
93 # check error when a non-existent way is included
94 get api_ways_path(:ways => "#{way1.id},#{way2.id},#{way3.id},#{way4.id},0")
95 assert_response :not_found
98 # -------------------------------------
100 # -------------------------------------
102 def test_show_not_found
104 assert_response :not_found
107 def test_show_deleted
108 get api_way_path(create(:way, :deleted))
109 assert_response :gone
113 way = create(:way, :timestamp => "2021-02-03T00:00:00Z")
114 node = create(:node, :timestamp => "2021-04-05T00:00:00Z")
115 create(:way_node, :way => way, :node => node)
117 get api_way_path(way)
119 assert_response :success
120 assert_not_nil @response.header["Last-Modified"]
121 assert_equal "2021-02-03T00:00:00Z", Time.parse(@response.header["Last-Modified"]).utc.xmlschema
125 way = create(:way_with_nodes, :nodes_count => 3)
127 get api_way_path(way, :format => "json")
129 assert_response :success
131 js = ActiveSupport::JSON.decode(@response.body)
133 assert_equal 1, js["elements"].count
134 js_ways = js["elements"].filter { |e| e["type"] == "way" }
135 assert_equal 1, js_ways.count
136 assert_equal way.id, js_ways[0]["id"]
137 assert_equal 1, js_ways[0]["version"]
141 # check the "full" mode
143 way = create(:way_with_nodes, :nodes_count => 3)
145 get api_way_path(way, :full => true)
147 assert_response :success
149 # Check the way is correctly returned
150 assert_select "osm way[id='#{way.id}'][version='1'][visible='true']", 1
152 # check that each node in the way appears once in the output as a
153 # reference and as the node element.
154 way.nodes.each do |n|
155 assert_select "osm way nd[ref='#{n.id}']", 1
156 assert_select "osm node[id='#{n.id}'][version='1'][lat='#{format('%<lat>.7f', :lat => n.lat)}'][lon='#{format('%<lon>.7f', :lon => n.lon)}']", 1
160 def test_show_full_json
161 way = create(:way_with_nodes, :nodes_count => 3)
163 get api_way_path(way, :full => true, :format => "json")
165 assert_response :success
167 # Check the way is correctly returned
168 js = ActiveSupport::JSON.decode(@response.body)
170 assert_equal 4, js["elements"].count
171 js_ways = js["elements"].filter { |e| e["type"] == "way" }
172 assert_equal 1, js_ways.count
173 assert_equal way.id, js_ways[0]["id"]
174 assert_equal 1, js_ways[0]["version"]
176 # check that each node in the way appears once in the output as a
177 # reference and as the node element.
178 js_nodes = js["elements"].filter { |e| e["type"] == "node" }
179 assert_equal 3, js_nodes.count
181 way.nodes.each_with_index do |n, i|
182 assert_equal n.id, js_ways[0]["nodes"][i]
183 js_nodes_with_id = js_nodes.filter { |e| e["id"] == n.id }
184 assert_equal 1, js_nodes_with_id.count
185 assert_equal n.id, js_nodes_with_id[0]["id"]
186 assert_equal 1, js_nodes_with_id[0]["version"]
187 assert_equal n.lat, js_nodes_with_id[0]["lat"]
188 assert_equal n.lon, js_nodes_with_id[0]["lon"]
192 def test_show_full_deleted
193 way = create(:way, :deleted)
195 get api_way_path(way, :full => true)
197 assert_response :gone
200 # -------------------------------------
201 # Test simple way creation.
202 # -------------------------------------
205 node1 = create(:node)
206 node2 = create(:node)
207 private_user = create(:user, :data_public => false)
208 private_changeset = create(:changeset, :user => private_user)
210 changeset = create(:changeset, :user => user)
212 ## First check that it fails when creating a way using a non-public user
213 auth_header = bearer_authorization_header private_user
215 # use the first user's open changeset
216 changeset_id = private_changeset.id
218 # create a way with pre-existing nodes
221 <way changeset='#{changeset_id}'>
222 <nd ref='#{node1.id}'/>
223 <nd ref='#{node2.id}'/>
224 <tag k='test' v='yes' />
228 post api_ways_path, :params => xml, :headers => auth_header
230 assert_response :forbidden,
231 "way upload did not return forbidden status"
233 ## Now use a public user
234 auth_header = bearer_authorization_header user
236 # use the first user's open changeset
237 changeset_id = changeset.id
239 # create a way with pre-existing nodes
242 <way changeset='#{changeset_id}'>
243 <nd ref='#{node1.id}'/>
244 <nd ref='#{node2.id}'/>
245 <tag k='test' v='yes' />
249 post api_ways_path, :params => xml, :headers => auth_header
251 assert_response :success,
252 "way upload did not return success status"
253 # read id of created way and search for it
254 wayid = @response.body
255 checkway = Way.find(wayid)
256 assert_not_nil checkway,
257 "uploaded way not found in data base after upload"
259 assert_equal(2, checkway.nds.length, "saved way does not contain exactly one node")
260 assert_equal checkway.nds[0], node1.id,
261 "saved way does not contain the right node on pos 0"
262 assert_equal checkway.nds[1], node2.id,
263 "saved way does not contain the right node on pos 1"
264 assert_equal checkway.changeset_id, changeset_id,
265 "saved way does not belong to the correct changeset"
266 assert_equal user.id, checkway.changeset.user_id,
267 "saved way does not belong to user that created it"
268 assert checkway.visible,
269 "saved way is not visible"
272 # -------------------------------------
273 # Test creating some invalid ways.
274 # -------------------------------------
276 def test_create_invalid
278 private_user = create(:user, :data_public => false)
279 private_open_changeset = create(:changeset, :user => private_user)
280 private_closed_changeset = create(:changeset, :closed, :user => private_user)
282 open_changeset = create(:changeset, :user => user)
283 closed_changeset = create(:changeset, :closed, :user => user)
285 ## First test with a private user to make sure that they are not authorized
286 auth_header = bearer_authorization_header private_user
288 # use the first user's open changeset
289 # create a way with non-existing node
292 <way changeset='#{private_open_changeset.id}'>
297 post api_ways_path, :params => xml, :headers => auth_header
299 assert_response :forbidden,
300 "way upload with invalid node using a private user did not return 'forbidden'"
302 # create a way with no nodes
305 <way changeset='#{private_open_changeset.id}'>
309 post api_ways_path, :params => xml, :headers => auth_header
311 assert_response :forbidden,
312 "way upload with no node using a private userdid not return 'forbidden'"
314 # create a way inside a closed changeset
317 <way changeset='#{private_closed_changeset.id}'>
318 <nd ref='#{node.id}'/>
322 post api_ways_path, :params => xml, :headers => auth_header
324 assert_response :forbidden,
325 "way upload to closed changeset with a private user did not return 'forbidden'"
327 ## Now test with a public user
328 auth_header = bearer_authorization_header user
330 # use the first user's open changeset
331 # create a way with non-existing node
334 <way changeset='#{open_changeset.id}'>
339 post api_ways_path, :params => xml, :headers => auth_header
341 assert_response :precondition_failed,
342 "way upload with invalid node did not return 'precondition failed'"
343 assert_equal "Precondition failed: Way requires the nodes with id in (0), which either do not exist, or are not visible.", @response.body
345 # create a way with no nodes
348 <way changeset='#{open_changeset.id}'>
352 post api_ways_path, :params => xml, :headers => auth_header
354 assert_response :precondition_failed,
355 "way upload with no node did not return 'precondition failed'"
356 assert_equal "Precondition failed: Cannot create way: data is invalid.", @response.body
358 # create a way inside a closed changeset
361 <way changeset='#{closed_changeset.id}'>
362 <nd ref='#{node.id}'/>
366 post api_ways_path, :params => xml, :headers => auth_header
368 assert_response :conflict,
369 "way upload to closed changeset did not return 'conflict'"
371 # create a way with a tag which is too long
374 <way changeset='#{open_changeset.id}'>
375 <nd ref='#{node.id}'/>
376 <tag k='foo' v='#{'x' * 256}'/>
380 post api_ways_path, :params => xml, :headers => auth_header
382 assert_response :bad_request,
383 "way upload to with too long tag did not return 'bad_request'"
386 # -------------------------------------
387 # Test deleting ways.
388 # -------------------------------------
391 private_user = create(:user, :data_public => false)
392 private_open_changeset = create(:changeset, :user => private_user)
393 private_closed_changeset = create(:changeset, :closed, :user => private_user)
394 private_way = create(:way, :changeset => private_open_changeset)
395 private_deleted_way = create(:way, :deleted, :changeset => private_open_changeset)
396 private_used_way = create(:way, :changeset => private_open_changeset)
397 create(:relation_member, :member => private_used_way)
399 open_changeset = create(:changeset, :user => user)
400 closed_changeset = create(:changeset, :closed, :user => user)
401 way = create(:way, :changeset => open_changeset)
402 deleted_way = create(:way, :deleted, :changeset => open_changeset)
403 used_way = create(:way, :changeset => open_changeset)
404 relation_member = create(:relation_member, :member => used_way)
405 relation = relation_member.relation
407 # first try to delete way without auth
408 delete api_way_path(way)
409 assert_response :unauthorized
411 # now set auth using the private user
412 auth_header = bearer_authorization_header private_user
414 # this shouldn't work as with the 0.6 api we need pay load to delete
415 delete api_way_path(private_way), :headers => auth_header
416 assert_response :forbidden
418 # Now try without having a changeset
419 xml = "<osm><way id='#{private_way.id}'/></osm>"
420 delete api_way_path(private_way), :params => xml.to_s, :headers => auth_header
421 assert_response :forbidden
423 # try to delete with an invalid (closed) changeset
424 xml = update_changeset(xml_for_way(private_way), private_closed_changeset.id)
425 delete api_way_path(private_way), :params => xml.to_s, :headers => auth_header
426 assert_response :forbidden
428 # try to delete with an invalid (non-existent) changeset
429 xml = update_changeset(xml_for_way(private_way), 0)
430 delete api_way_path(private_way), :params => xml.to_s, :headers => auth_header
431 assert_response :forbidden
433 # Now try with a valid changeset
434 xml = xml_for_way(private_way)
435 delete api_way_path(private_way), :params => xml.to_s, :headers => auth_header
436 assert_response :forbidden
438 # check the returned value - should be the new version number
439 # valid delete should return the new version number, which should
440 # be greater than the old version number
441 # assert @response.body.to_i > current_ways(:visible_way).version,
442 # "delete request should return a new version number for way"
444 # this won't work since the way is already deleted
445 xml = xml_for_way(private_deleted_way)
446 delete api_way_path(private_deleted_way), :params => xml.to_s, :headers => auth_header
447 assert_response :forbidden
449 # this shouldn't work as the way is used in a relation
450 xml = xml_for_way(private_used_way)
451 delete api_way_path(private_used_way), :params => xml.to_s, :headers => auth_header
452 assert_response :forbidden,
453 "shouldn't be able to delete a way used in a relation (#{@response.body}), when done by a private user"
455 # this won't work since the way never existed
456 delete api_way_path(0), :headers => auth_header
457 assert_response :forbidden
459 ### Now check with a public user
461 auth_header = bearer_authorization_header user
463 # this shouldn't work as with the 0.6 api we need pay load to delete
464 delete api_way_path(way), :headers => auth_header
465 assert_response :bad_request
467 # Now try without having a changeset
468 xml = "<osm><way id='#{way.id}'/></osm>"
469 delete api_way_path(way), :params => xml.to_s, :headers => auth_header
470 assert_response :bad_request
472 # try to delete with an invalid (closed) changeset
473 xml = update_changeset(xml_for_way(way), closed_changeset.id)
474 delete api_way_path(way), :params => xml.to_s, :headers => auth_header
475 assert_response :conflict
477 # try to delete with an invalid (non-existent) changeset
478 xml = update_changeset(xml_for_way(way), 0)
479 delete api_way_path(way), :params => xml.to_s, :headers => auth_header
480 assert_response :conflict
482 # Now try with a valid changeset
483 xml = xml_for_way(way)
484 delete api_way_path(way), :params => xml.to_s, :headers => auth_header
485 assert_response :success
487 # check the returned value - should be the new version number
488 # valid delete should return the new version number, which should
489 # be greater than the old version number
490 assert_operator @response.body.to_i, :>, way.version, "delete request should return a new version number for way"
492 # this won't work since the way is already deleted
493 xml = xml_for_way(deleted_way)
494 delete api_way_path(deleted_way), :params => xml.to_s, :headers => auth_header
495 assert_response :gone
497 # this shouldn't work as the way is used in a relation
498 xml = xml_for_way(used_way)
499 delete api_way_path(used_way), :params => xml.to_s, :headers => auth_header
500 assert_response :precondition_failed,
501 "shouldn't be able to delete a way used in a relation (#{@response.body})"
502 assert_equal "Precondition failed: Way #{used_way.id} is still used by relations #{relation.id}.", @response.body
504 # this won't work since the way never existed
505 delete api_way_path(0), :params => xml.to_s, :headers => auth_header
506 assert_response :not_found
510 # tests whether the API works and prevents incorrect use while trying
513 private_user = create(:user, :data_public => false)
514 private_way = create(:way, :changeset => create(:changeset, :user => private_user))
516 way = create(:way, :changeset => create(:changeset, :user => user))
518 create(:way_node, :way => private_way, :node => node)
519 create(:way_node, :way => way, :node => node)
521 ## First test with no user credentials
522 # try and update a way without authorisation
523 xml = xml_for_way(way)
524 put api_way_path(way), :params => xml.to_s
525 assert_response :unauthorized
527 ## Second test with the private user
530 auth_header = bearer_authorization_header private_user
532 ## trying to break changesets
534 # try and update in someone else's changeset
535 xml = update_changeset(xml_for_way(private_way),
536 create(:changeset).id)
537 put api_way_path(private_way), :params => xml.to_s, :headers => auth_header
538 assert_require_public_data "update with other user's changeset should be forbidden when date isn't public"
540 # try and update in a closed changeset
541 xml = update_changeset(xml_for_way(private_way),
542 create(:changeset, :closed, :user => private_user).id)
543 put api_way_path(private_way), :params => xml.to_s, :headers => auth_header
544 assert_require_public_data "update with closed changeset should be forbidden, when data isn't public"
546 # try and update in a non-existant changeset
547 xml = update_changeset(xml_for_way(private_way), 0)
548 put api_way_path(private_way), :params => xml.to_s, :headers => auth_header
549 assert_require_public_data("update with changeset=0 should be forbidden, when data isn't public")
551 ## try and submit invalid updates
552 xml = xml_replace_node(xml_for_way(private_way), node.id, 9999)
553 put api_way_path(private_way), :params => xml.to_s, :headers => auth_header
554 assert_require_public_data "way with non-existent node should be forbidden, when data isn't public"
556 xml = xml_replace_node(xml_for_way(private_way), node.id, create(:node, :deleted).id)
557 put api_way_path(private_way), :params => xml.to_s, :headers => auth_header
558 assert_require_public_data "way with deleted node should be forbidden, when data isn't public"
560 ## finally, produce a good request which will still not work
561 xml = xml_for_way(private_way)
562 put api_way_path(private_way), :params => xml.to_s, :headers => auth_header
563 assert_require_public_data "should have failed with a forbidden when data isn't public"
565 ## Finally test with the public user
568 auth_header = bearer_authorization_header user
570 ## trying to break changesets
572 # try and update in someone else's changeset
573 xml = update_changeset(xml_for_way(way),
574 create(:changeset).id)
575 put api_way_path(way), :params => xml.to_s, :headers => auth_header
576 assert_response :conflict, "update with other user's changeset should be rejected"
578 # try and update in a closed changeset
579 xml = update_changeset(xml_for_way(way),
580 create(:changeset, :closed, :user => user).id)
581 put api_way_path(way), :params => xml.to_s, :headers => auth_header
582 assert_response :conflict, "update with closed changeset should be rejected"
584 # try and update in a non-existant changeset
585 xml = update_changeset(xml_for_way(way), 0)
586 put api_way_path(way), :params => xml.to_s, :headers => auth_header
587 assert_response :conflict, "update with changeset=0 should be rejected"
589 ## try and submit invalid updates
590 xml = xml_replace_node(xml_for_way(way), node.id, 9999)
591 put api_way_path(way), :params => xml.to_s, :headers => auth_header
592 assert_response :precondition_failed, "way with non-existent node should be rejected"
594 xml = xml_replace_node(xml_for_way(way), node.id, create(:node, :deleted).id)
595 put api_way_path(way), :params => xml.to_s, :headers => auth_header
596 assert_response :precondition_failed, "way with deleted node should be rejected"
598 ## next, attack the versioning
599 current_way_version = way.version
601 # try and submit a version behind
602 xml = xml_attr_rewrite(xml_for_way(way),
603 "version", current_way_version - 1)
604 put api_way_path(way), :params => xml.to_s, :headers => auth_header
605 assert_response :conflict, "should have failed on old version number"
607 # try and submit a version ahead
608 xml = xml_attr_rewrite(xml_for_way(way),
609 "version", current_way_version + 1)
610 put api_way_path(way), :params => xml.to_s, :headers => auth_header
611 assert_response :conflict, "should have failed on skipped version number"
613 # try and submit total crap in the version field
614 xml = xml_attr_rewrite(xml_for_way(way),
615 "version", "p1r4t3s!")
616 put api_way_path(way), :params => xml.to_s, :headers => auth_header
617 assert_response :conflict,
618 "should not be able to put 'p1r4at3s!' in the version field"
620 ## try an update with the wrong ID
621 xml = xml_for_way(create(:way))
622 put api_way_path(way), :params => xml.to_s, :headers => auth_header
623 assert_response :bad_request,
624 "should not be able to update a way with a different ID from the XML"
626 ## try an update with a minimal valid XML doc which isn't a well-formed OSM doc.
628 put api_way_path(way), :params => xml.to_s, :headers => auth_header
629 assert_response :bad_request,
630 "should not be able to update a way with non-OSM XML doc."
632 ## finally, produce a good request which should work
633 xml = xml_for_way(way)
634 put api_way_path(way), :params => xml.to_s, :headers => auth_header
635 assert_response :success, "a valid update request failed"
638 # ------------------------------------------------------------
640 # ------------------------------------------------------------
643 # Try adding a new tag to a way
645 private_user = create(:user, :data_public => false)
646 private_way = create(:way_with_nodes, :nodes_count => 2, :changeset => create(:changeset, :user => private_user))
648 way = create(:way_with_nodes, :nodes_count => 2, :changeset => create(:changeset, :user => user))
650 ## Try with the non-public user
652 auth_header = bearer_authorization_header private_user
654 # add an identical tag to the way
655 tag_xml = XML::Node.new("tag")
659 # add the tag into the existing xml
660 way_xml = xml_for_way(private_way)
661 way_xml.find("//osm/way").first << tag_xml
664 put api_way_path(private_way), :params => way_xml.to_s, :headers => auth_header
665 assert_response :forbidden,
666 "adding a duplicate tag to a way for a non-public should fail with 'forbidden'"
668 ## Now try with the public user
670 auth_header = bearer_authorization_header user
672 # add an identical tag to the way
673 tag_xml = XML::Node.new("tag")
677 # add the tag into the existing xml
678 way_xml = xml_for_way(way)
679 way_xml.find("//osm/way").first << tag_xml
682 put api_way_path(way), :params => way_xml.to_s, :headers => auth_header
683 assert_response :success,
684 "adding a new tag to a way should succeed"
685 assert_equal way.version + 1, @response.body.to_i
689 # Try adding a duplicate of an existing tag to a way
690 def test_add_duplicate_tags
691 private_user = create(:user, :data_public => false)
692 private_way = create(:way, :changeset => create(:changeset, :user => private_user))
693 private_existing_tag = create(:way_tag, :way => private_way)
695 way = create(:way, :changeset => create(:changeset, :user => user))
696 existing_tag = create(:way_tag, :way => way)
698 ## Try with the non-public user
700 auth_header = bearer_authorization_header private_user
702 # add an identical tag to the way
703 tag_xml = XML::Node.new("tag")
704 tag_xml["k"] = private_existing_tag.k
705 tag_xml["v"] = private_existing_tag.v
707 # add the tag into the existing xml
708 way_xml = xml_for_way(private_way)
709 way_xml.find("//osm/way").first << tag_xml
712 put api_way_path(private_way), :params => way_xml.to_s, :headers => auth_header
713 assert_response :forbidden,
714 "adding a duplicate tag to a way for a non-public should fail with 'forbidden'"
716 ## Now try with the public user
718 auth_header = bearer_authorization_header user
720 # add an identical tag to the way
721 tag_xml = XML::Node.new("tag")
722 tag_xml["k"] = existing_tag.k
723 tag_xml["v"] = existing_tag.v
725 # add the tag into the existing xml
726 way_xml = xml_for_way(way)
727 way_xml.find("//osm/way").first << tag_xml
730 put api_way_path(way), :params => way_xml.to_s, :headers => auth_header
731 assert_response :bad_request,
732 "adding a duplicate tag to a way should fail with 'bad request'"
733 assert_equal "Element way/#{way.id} has duplicate tags with key #{existing_tag.k}", @response.body
737 # Try adding a new duplicate tags to a way
738 def test_new_duplicate_tags
739 private_user = create(:user, :data_public => false)
740 private_way = create(:way, :changeset => create(:changeset, :user => private_user))
742 way = create(:way, :changeset => create(:changeset, :user => user))
744 ## First test with the non-public user so should be rejected
746 auth_header = bearer_authorization_header private_user
748 # create duplicate tag
749 tag_xml = XML::Node.new("tag")
750 tag_xml["k"] = "i_am_a_duplicate"
751 tag_xml["v"] = "foobar"
753 # add the tag into the existing xml
754 way_xml = xml_for_way(private_way)
756 # add two copies of the tag
757 way_xml.find("//osm/way").first << tag_xml.copy(true) << tag_xml
760 put api_way_path(private_way), :params => way_xml.to_s, :headers => auth_header
761 assert_response :forbidden,
762 "adding new duplicate tags to a way using a non-public user should fail with 'forbidden'"
764 ## Now test with the public user
766 auth_header = bearer_authorization_header user
768 # create duplicate tag
769 tag_xml = XML::Node.new("tag")
770 tag_xml["k"] = "i_am_a_duplicate"
771 tag_xml["v"] = "foobar"
773 # add the tag into the existing xml
774 way_xml = xml_for_way(way)
776 # add two copies of the tag
777 way_xml.find("//osm/way").first << tag_xml.copy(true) << tag_xml
780 put api_way_path(way), :params => way_xml.to_s, :headers => auth_header
781 assert_response :bad_request,
782 "adding new duplicate tags to a way should fail with 'bad request'"
783 assert_equal "Element way/#{way.id} has duplicate tags with key i_am_a_duplicate", @response.body
787 # Try adding a new duplicate tags to a way.
788 # But be a bit subtle - use unicode decoding ambiguities to use different
789 # binary strings which have the same decoding.
790 def test_invalid_duplicate_tags
791 private_user = create(:user, :data_public => false)
792 private_changeset = create(:changeset, :user => private_user)
794 changeset = create(:changeset, :user => user)
796 ## First make sure that you can't with a non-public user
798 auth_header = bearer_authorization_header private_user
800 # add the tag into the existing xml
803 <way changeset='#{private_changeset.id}'>
804 <tag k='addr:housenumber' v='1'/>
805 <tag k='addr:housenumber' v='2'/>
811 post api_ways_path, :params => way_str, :headers => auth_header
812 assert_response :forbidden,
813 "adding new duplicate tags to a way with a non-public user should fail with 'forbidden'"
815 ## Now do it with a public user
817 auth_header = bearer_authorization_header user
819 # add the tag into the existing xml
822 <way changeset='#{changeset.id}'>
823 <tag k='addr:housenumber' v='1'/>
824 <tag k='addr:housenumber' v='2'/>
830 post api_ways_path, :params => way_str, :headers => auth_header
831 assert_response :bad_request,
832 "adding new duplicate tags to a way should fail with 'bad request'"
833 assert_equal "Element way/ has duplicate tags with key addr:housenumber", @response.body
837 # test initial rate limit
838 def test_initial_rate_limit
843 node1 = create(:node)
844 node2 = create(:node)
846 # create a changeset that puts us near the initial rate limit
847 changeset = create(:changeset, :user => user,
848 :created_at => Time.now.utc - 5.minutes,
849 :num_changes => Settings.initial_changes_per_hour - 1)
851 # create authentication header
852 auth_header = bearer_authorization_header user
857 <way changeset='#{changeset.id}'>
858 <nd ref='#{node1.id}'/>
859 <nd ref='#{node2.id}'/>
863 post api_ways_path, :params => xml, :headers => auth_header
864 assert_response :success, "way create did not return success status"
866 # get the id of the way we created
867 wayid = @response.body
869 # try updating the way, which should be rate limited
872 <way id='#{wayid}' version='1' changeset='#{changeset.id}'>
873 <nd ref='#{node2.id}'/>
874 <nd ref='#{node1.id}'/>
878 put api_way_path(wayid), :params => xml, :headers => auth_header
879 assert_response :too_many_requests, "way update did not hit rate limit"
881 # try deleting the way, which should be rate limited
882 xml = "<osm><way id='#{wayid}' version='2' changeset='#{changeset.id}'/></osm>"
883 delete api_way_path(wayid), :params => xml, :headers => auth_header
884 assert_response :too_many_requests, "way delete did not hit rate limit"
886 # try creating a way, which should be rate limited
889 <way changeset='#{changeset.id}'>
890 <nd ref='#{node1.id}'/>
891 <nd ref='#{node2.id}'/>
895 post api_ways_path, :params => xml, :headers => auth_header
896 assert_response :too_many_requests, "way create did not hit rate limit"
900 # test maximum rate limit
901 def test_maximum_rate_limit
906 node1 = create(:node)
907 node2 = create(:node)
909 # create a changeset to establish our initial edit time
910 changeset = create(:changeset, :user => user,
911 :created_at => Time.now.utc - 28.days)
913 # create changeset to put us near the maximum rate limit
914 total_changes = Settings.max_changes_per_hour - 1
915 while total_changes.positive?
916 changes = [total_changes, Changeset::MAX_ELEMENTS].min
917 changeset = create(:changeset, :user => user,
918 :created_at => Time.now.utc - 5.minutes,
919 :num_changes => changes)
920 total_changes -= changes
923 # create authentication header
924 auth_header = bearer_authorization_header user
929 <way changeset='#{changeset.id}'>
930 <nd ref='#{node1.id}'/>
931 <nd ref='#{node2.id}'/>
935 post api_ways_path, :params => xml, :headers => auth_header
936 assert_response :success, "way create did not return success status"
938 # get the id of the way we created
939 wayid = @response.body
941 # try updating the way, which should be rate limited
944 <way id='#{wayid}' version='1' changeset='#{changeset.id}'>
945 <nd ref='#{node2.id}'/>
946 <nd ref='#{node1.id}'/>
950 put api_way_path(wayid), :params => xml, :headers => auth_header
951 assert_response :too_many_requests, "way update did not hit rate limit"
953 # try deleting the way, which should be rate limited
954 xml = "<osm><way id='#{wayid}' version='2' changeset='#{changeset.id}'/></osm>"
955 delete api_way_path(wayid), :params => xml, :headers => auth_header
956 assert_response :too_many_requests, "way delete did not hit rate limit"
958 # try creating a way, which should be rate limited
961 <way changeset='#{changeset.id}'>
962 <nd ref='#{node1.id}'/>
963 <nd ref='#{node2.id}'/>
967 post api_ways_path, :params => xml, :headers => auth_header
968 assert_response :too_many_requests, "way create did not hit rate limit"
974 # update an attribute in the way element
975 def xml_attr_rewrite(xml, name, value)
976 xml.find("//osm/way").first[name] = value.to_s
981 # replace a node in a way element
982 def xml_replace_node(xml, old_node, new_node)
983 xml.find("//osm/way/nd[@ref='#{old_node}']").first["ref"] = new_node.to_s