2 require_relative "elements_test_helper"
5 class RelationsControllerTest < ActionDispatch::IntegrationTest
6 include ElementsTestHelper
9 # test all routes which lead to this controller
12 { :path => "/api/0.6/relations", :method => :get },
13 { :controller => "api/relations", :action => "index" }
16 { :path => "/api/0.6/relations.json", :method => :get },
17 { :controller => "api/relations", :action => "index", :format => "json" }
20 { :path => "/api/0.6/relations", :method => :post },
21 { :controller => "api/relations", :action => "create" }
24 { :path => "/api/0.6/relation/1", :method => :get },
25 { :controller => "api/relations", :action => "show", :id => "1" }
28 { :path => "/api/0.6/relation/1.json", :method => :get },
29 { :controller => "api/relations", :action => "show", :id => "1", :format => "json" }
32 { :path => "/api/0.6/relation/1/full", :method => :get },
33 { :controller => "api/relations", :action => "show", :full => true, :id => "1" }
36 { :path => "/api/0.6/relation/1/full.json", :method => :get },
37 { :controller => "api/relations", :action => "show", :full => true, :id => "1", :format => "json" }
40 { :path => "/api/0.6/relation/1", :method => :put },
41 { :controller => "api/relations", :action => "update", :id => "1" }
44 { :path => "/api/0.6/relation/1", :method => :delete },
45 { :controller => "api/relations", :action => "destroy", :id => "1" }
49 { :controller => "api/relations", :action => "create" },
50 { :path => "/api/0.6/relation/create", :method => :put }
55 # test fetching multiple relations
57 relation1 = create(:relation)
58 relation2 = create(:relation, :deleted)
59 relation3 = create(:relation, :with_history, :version => 2)
60 relation4 = create(:relation, :with_history, :version => 2)
61 relation4.old_relations.find_by(:version => 1).redact!(create(:redaction))
63 # check error when no parameter provided
64 get api_relations_path
65 assert_response :bad_request
67 # check error when no parameter value provided
68 get api_relations_path(:relations => "")
69 assert_response :bad_request
72 get api_relations_path(:relations => "#{relation1.id},#{relation2.id},#{relation3.id},#{relation4.id}")
73 assert_response :success
74 assert_select "osm" do
75 assert_select "relation", :count => 4
76 assert_select "relation[id='#{relation1.id}'][visible='true']", :count => 1
77 assert_select "relation[id='#{relation2.id}'][visible='false']", :count => 1
78 assert_select "relation[id='#{relation3.id}'][visible='true']", :count => 1
79 assert_select "relation[id='#{relation4.id}'][visible='true']", :count => 1
82 # test a working call with json format
83 get api_relations_path(:relations => "#{relation1.id},#{relation2.id},#{relation3.id},#{relation4.id}", :format => "json")
85 js = ActiveSupport::JSON.decode(@response.body)
87 assert_equal 4, js["elements"].count
88 assert_equal(4, js["elements"].count { |a| a["type"] == "relation" })
89 assert_equal(1, js["elements"].count { |a| a["id"] == relation1.id && a["visible"].nil? })
90 assert_equal(1, js["elements"].count { |a| a["id"] == relation2.id && a["visible"] == false })
91 assert_equal(1, js["elements"].count { |a| a["id"] == relation3.id && a["visible"].nil? })
92 assert_equal(1, js["elements"].count { |a| a["id"] == relation4.id && a["visible"].nil? })
94 # check error when a non-existent relation is included
95 get api_relations_path(:relations => "#{relation1.id},#{relation2.id},#{relation3.id},#{relation4.id},0")
96 assert_response :not_found
99 # -------------------------------------
100 # Test showing relations.
101 # -------------------------------------
103 def test_show_not_found
104 get api_relation_path(0)
105 assert_response :not_found
108 def test_show_deleted
109 get api_relation_path(create(:relation, :deleted))
110 assert_response :gone
114 relation = create(:relation, :timestamp => "2021-02-03T00:00:00Z")
115 node = create(:node, :timestamp => "2021-04-05T00:00:00Z")
116 create(:relation_member, :relation => relation, :member => node)
118 get api_relation_path(relation)
120 assert_response :success
121 assert_not_nil @response.header["Last-Modified"]
122 assert_equal "2021-02-03T00:00:00Z", Time.parse(@response.header["Last-Modified"]).utc.xmlschema
123 assert_dom "node", :count => 0
124 assert_dom "relation", :count => 1 do
125 assert_dom "> @id", :text => relation.id.to_s
129 def test_full_not_found
130 get api_relation_path(999999, :full => true)
131 assert_response :not_found
134 def test_full_deleted
135 get api_relation_path(create(:relation, :deleted), :full => true)
136 assert_response :gone
140 relation = create(:relation)
142 get api_relation_path(relation, :full => true)
144 assert_response :success
145 assert_dom "relation", :count => 1 do
146 assert_dom "> @id", :text => relation.id.to_s
150 def test_full_with_node_member
151 relation = create(:relation)
153 create(:relation_member, :relation => relation, :member => node)
155 get api_relation_path(relation, :full => true)
157 assert_response :success
158 assert_dom "node", :count => 1 do
159 assert_dom "> @id", :text => node.id.to_s
161 assert_dom "relation", :count => 1 do
162 assert_dom "> @id", :text => relation.id.to_s
166 def test_full_with_way_member
167 relation = create(:relation)
168 way = create(:way_with_nodes)
169 create(:relation_member, :relation => relation, :member => way)
171 get api_relation_path(relation, :full => true)
173 assert_response :success
174 assert_dom "node", :count => 1 do
175 assert_dom "> @id", :text => way.nodes[0].id.to_s
177 assert_dom "way", :count => 1 do
178 assert_dom "> @id", :text => way.id.to_s
180 assert_dom "relation", :count => 1 do
181 assert_dom "> @id", :text => relation.id.to_s
185 def test_full_with_node_member_json
186 relation = create(:relation)
188 create(:relation_member, :relation => relation, :member => node)
190 get api_relation_path(relation, :full => true, :format => "json")
192 assert_response :success
193 js = ActiveSupport::JSON.decode(@response.body)
195 assert_equal 2, js["elements"].count
197 js_relations = js["elements"].filter { |e| e["type"] == "relation" }
198 assert_equal 1, js_relations.count
199 assert_equal relation.id, js_relations[0]["id"]
200 assert_equal 1, js_relations[0]["members"].count
201 assert_equal "node", js_relations[0]["members"][0]["type"]
202 assert_equal node.id, js_relations[0]["members"][0]["ref"]
204 js_nodes = js["elements"].filter { |e| e["type"] == "node" }
205 assert_equal 1, js_nodes.count
206 assert_equal node.id, js_nodes[0]["id"]
209 # -------------------------------------
210 # Test creating relations.
211 # -------------------------------------
213 def test_create_without_members_by_private_user
214 with_unchanging_request([:data_public => false]) do |headers, changeset|
217 <relation changeset='#{changeset.id}'>
218 <tag k='test' v='yes' />
223 post api_relations_path, :params => osm, :headers => headers
225 assert_response :forbidden, "relation upload should have failed with forbidden"
229 def test_create_with_node_member_with_role_by_private_user
232 with_unchanging_request([:data_public => false]) do |headers, changeset|
235 <relation changeset='#{changeset.id}'>
236 <member ref='#{node.id}' type='node' role='some'/>
237 <tag k='test' v='yes' />
242 post api_relations_path, :params => osm, :headers => headers
244 assert_response :forbidden, "relation upload did not return forbidden status"
248 def test_create_with_node_member_without_role_by_private_user
251 with_unchanging_request([:data_public => false]) do |headers, changeset|
254 <relation changeset='#{changeset.id}'>
255 <member ref='#{node.id}' type='node'/>
256 <tag k='test' v='yes' />
261 post api_relations_path, :params => osm, :headers => headers
263 assert_response :forbidden, "relation upload did not return forbidden status"
267 def test_create_with_node_and_way_members_by_private_user
269 way = create(:way_with_nodes, :nodes_count => 2)
271 with_unchanging_request([:data_public => false]) do |headers, changeset|
274 <relation changeset='#{changeset.id}'>
275 <member type='node' ref='#{node.id}' role='some'/>
276 <member type='way' ref='#{way.id}' role='other'/>
277 <tag k='test' v='yes' />
282 post api_relations_path, :params => osm, :headers => headers
284 assert_response :forbidden, "relation upload did not return success status"
288 def test_create_without_members
289 with_request do |headers, changeset|
290 assert_difference "Relation.count" => 1,
291 "RelationMember.count" => 0 do
294 <relation changeset='#{changeset.id}'>
295 <tag k='test' v='yes' />
300 post api_relations_path, :params => osm, :headers => headers
302 assert_response :success, "relation upload did not return success status"
305 created_relation_id = @response.body
306 relation = Relation.find(created_relation_id)
307 assert_empty relation.members
308 assert_equal({ "test" => "yes" }, relation.tags)
309 assert_equal changeset.id, relation.changeset_id, "saved relation does not belong in the changeset it was assigned to"
310 assert relation.visible, "saved relation is not visible"
313 assert_equal 1, changeset.num_changes
314 assert_predicate changeset, :num_type_changes_in_sync?
315 assert_equal 1, changeset.num_created_relations
319 def test_create_with_node_member_with_role
322 with_request do |headers, changeset|
323 assert_difference "Relation.count" => 1,
324 "RelationMember.count" => 1 do
327 <relation changeset='#{changeset.id}'>
328 <member ref='#{node.id}' type='node' role='some'/>
329 <tag k='test' v='yes' />
334 post api_relations_path, :params => osm, :headers => headers
336 assert_response :success, "relation upload did not return success status"
339 created_relation_id = @response.body
340 relation = Relation.find(created_relation_id)
341 assert_equal [["Node", node.id, "some"]], relation.members
342 assert_equal({ "test" => "yes" }, relation.tags)
343 assert_equal changeset.id, relation.changeset_id, "saved relation does not belong in the changeset it was assigned to"
344 assert relation.visible, "saved relation is not visible"
347 assert_equal 1, changeset.num_changes
348 assert_predicate changeset, :num_type_changes_in_sync?
349 assert_equal 1, changeset.num_created_relations
353 def test_create_with_node_member_without_role
356 with_request do |headers, changeset|
357 assert_difference "Relation.count" => 1,
358 "RelationMember.count" => 1 do
361 <relation changeset='#{changeset.id}'>
362 <member ref='#{node.id}' type='node'/>
363 <tag k='test' v='yes' />
368 post api_relations_path, :params => osm, :headers => headers
370 assert_response :success, "relation upload did not return success status"
373 created_relation_id = @response.body
374 relation = Relation.find(created_relation_id)
375 assert_equal [["Node", node.id, ""]], relation.members
376 assert_equal({ "test" => "yes" }, relation.tags)
377 assert_equal changeset.id, relation.changeset_id, "saved relation does not belong in the changeset it was assigned to"
378 assert relation.visible, "saved relation is not visible"
381 assert_equal 1, changeset.num_changes
382 assert_predicate changeset, :num_type_changes_in_sync?
383 assert_equal 1, changeset.num_created_relations
387 def test_create_with_node_and_way_members
389 way = create(:way_with_nodes, :nodes_count => 2)
391 with_request do |headers, changeset|
392 assert_difference "Relation.count" => 1,
393 "RelationMember.count" => 2 do
396 <relation changeset='#{changeset.id}'>
397 <member type='node' ref='#{node.id}' role='some'/>
398 <member type='way' ref='#{way.id}' role='other'/>
399 <tag k='test' v='yes' />
404 post api_relations_path, :params => osm, :headers => headers
406 assert_response :success, "relation upload did not return success status"
409 created_relation_id = @response.body
410 relation = Relation.find(created_relation_id)
411 assert_equal [["Node", node.id, "some"],
412 ["Way", way.id, "other"]], relation.members
413 assert_equal({ "test" => "yes" }, relation.tags)
414 assert_equal changeset.id, relation.changeset_id, "saved relation does not belong in the changeset it was assigned to"
415 assert relation.visible, "saved relation is not visible"
418 assert_equal 1, changeset.num_changes
419 assert_predicate changeset, :num_type_changes_in_sync?
420 assert_equal 1, changeset.num_created_relations
424 def test_create_in_missing_changeset
427 with_unchanging_request do |headers|
430 <relation changeset='0'>
431 <member type='node' ref='#{node.id}' role='some'/>
436 post api_relations_path, :params => osm, :headers => headers
438 assert_response :conflict
442 def test_create_with_missing_node_member
443 with_unchanging_request do |headers, changeset|
446 <relation changeset='#{changeset.id}'>
447 <member type='node' ref='0'/>
452 post api_relations_path, :params => osm, :headers => headers
454 assert_response :precondition_failed, "relation upload with invalid node did not return 'precondition failed'"
455 assert_equal "Precondition failed: Relation with id cannot be saved due to Node with id 0", @response.body
459 def test_create_with_invalid_member_type
462 with_unchanging_request do |headers, changeset|
465 <relation changeset='#{changeset.id}'>
466 <member type='type' ref='#{node.id}' role=''/>
471 post api_relations_path, :params => osm, :headers => headers
473 assert_response :bad_request
474 assert_match(/Cannot parse valid relation from xml string/, @response.body)
475 assert_match(/The type is not allowed only, /, @response.body)
479 def test_create_and_show
481 changeset = create(:changeset, :user => user)
485 <relation changeset='#{changeset.id}'/>
489 post api_relations_path, :params => osm, :headers => bearer_authorization_header(user)
491 assert_response :success, "relation upload did not return success status"
493 created_relation_id = @response.body
495 get api_relation_path(created_relation_id)
497 assert_response :success
500 def test_create_race_condition
502 changeset = create(:changeset, :user => user)
504 auth_header = bearer_authorization_header user
505 path = api_relations_path
506 concurrency_level = 16
508 threads = Array.new(concurrency_level) do
512 <relation changeset='#{changeset.id}'>
513 <member type='node' ref='#{node.id}' role=''/>
517 post path, :params => osm, :headers => auth_header
523 assert_equal concurrency_level, changeset.num_changes
524 assert_predicate changeset, :num_type_changes_in_sync?
525 assert_equal concurrency_level, changeset.num_created_relations
528 # ------------------------------------
529 # Test updating relations
530 # ------------------------------------
533 relation = create(:relation)
535 with_request do |headers, changeset|
536 osm_xml = xml_for_relation relation
537 osm_xml = update_changeset osm_xml, changeset.id
539 put api_relation_path(relation), :params => osm_xml.to_s, :headers => headers
541 assert_response :success
544 assert_equal 2, relation.version
547 assert_equal 1, changeset.num_changes
548 assert_predicate changeset, :num_type_changes_in_sync?
549 assert_equal 1, changeset.num_modified_relations
553 def test_update_in_missing_changeset
554 with_unchanging(:relation) do |relation|
555 with_unchanging_request do |headers|
556 osm_xml = xml_for_relation relation
557 osm_xml = update_changeset osm_xml, 0
559 put api_relation_path(relation), :params => osm_xml.to_s, :headers => headers
561 assert_response :conflict, "update with changeset=0 should be rejected"
566 def test_update_other_relation
567 with_unchanging(:relation) do |relation|
568 with_unchanging(:relation) do |other_relation|
569 with_unchanging_request do |headers, changeset|
570 osm_xml = xml_for_relation other_relation
571 osm_xml = update_changeset osm_xml, changeset.id
573 put api_relation_path(relation), :params => osm_xml.to_s, :headers => headers
575 assert_response :bad_request
581 # -------------------------------------
582 # Test deleting relations.
583 # -------------------------------------
585 def test_destroy_when_unauthorized
586 with_unchanging(:relation) do |relation|
587 delete api_relation_path(relation)
589 assert_response :unauthorized
593 def test_destroy_without_payload_by_private_user
594 with_unchanging(:relation) do |relation|
595 with_unchanging_request([:data_public => false]) do |headers|
596 delete api_relation_path(relation), :headers => headers
598 assert_response :forbidden
603 def test_destroy_without_changeset_id_by_private_user
604 with_unchanging(:relation) do |relation|
605 with_unchanging_request([:data_public => false]) do |headers|
606 osm = "<osm><relation id='#{relation.id}' version='#{relation.version}'/></osm>"
608 delete api_relation_path(relation), :params => osm, :headers => headers
610 assert_response :forbidden
615 def test_destroy_in_closed_changeset_by_private_user
616 with_unchanging(:relation) do |relation|
617 with_unchanging_request([:data_public => false], [:closed]) do |headers, changeset|
618 osm_xml = xml_for_relation relation
619 osm_xml = update_changeset osm_xml, changeset.id
621 delete api_relation_path(relation), :params => osm_xml.to_s, :headers => headers
623 assert_response :forbidden
628 def test_destroy_in_missing_changeset_by_private_user
629 with_unchanging(:relation) do |relation|
630 with_unchanging_request([:data_public => false]) do |headers|
631 osm_xml = xml_for_relation relation
632 osm_xml = update_changeset osm_xml, 0
634 delete api_relation_path(relation), :params => osm_xml.to_s, :headers => headers
636 assert_response :forbidden
641 def test_destroy_relation_used_by_other_relation_by_private_user
642 with_unchanging(:relation) do |relation|
643 create(:relation_member, :member => relation)
645 with_unchanging_request([:data_public => false]) do |headers, changeset|
646 osm_xml = xml_for_relation relation
647 osm_xml = update_changeset osm_xml, changeset.id
649 delete api_relation_path(relation), :params => osm_xml.to_s, :headers => headers
651 assert_response :forbidden
656 def test_destroy_by_private_user
657 with_unchanging(:relation) do |relation|
658 with_unchanging_request([:data_public => false]) do |headers, changeset|
659 osm_xml = xml_for_relation relation
660 osm_xml = update_changeset osm_xml, changeset.id
662 delete api_relation_path(relation), :params => osm_xml.to_s, :headers => headers
664 assert_response :forbidden
669 def test_destroy_deleted_relation_by_private_user
670 with_unchanging(:relation, :deleted) do |relation|
671 with_unchanging_request([:data_public => false]) do |headers, changeset|
672 osm_xml = xml_for_relation relation
673 osm_xml = update_changeset osm_xml, changeset.id
675 delete api_relation_path(relation), :params => osm_xml.to_s, :headers => headers
677 assert_response :forbidden
682 def test_destroy_missing_relation_by_private_user
683 with_unchanging_request([:data_public => false]) do |headers|
684 delete api_relation_path(0), :headers => headers
686 assert_response :forbidden
690 def test_destroy_without_payload
691 with_unchanging(:relation) do |relation|
692 with_unchanging_request do |headers|
693 delete api_relation_path(relation), :headers => headers
695 assert_response :bad_request
700 def test_destroy_without_changeset_id
701 with_unchanging(:relation) do |relation|
702 with_unchanging_request do |headers|
703 osm = "<osm><relation id='#{relation.id}' version='#{relation.version}'/></osm>"
705 delete api_relation_path(relation), :params => osm, :headers => headers
707 assert_response :bad_request
708 assert_match(/Changeset id is missing/, @response.body)
713 def test_destroy_in_closed_changeset
714 with_unchanging(:relation) do |relation|
715 with_unchanging_request([], [:closed]) do |headers, changeset|
716 osm_xml = xml_for_relation relation
717 osm_xml = update_changeset osm_xml, changeset.id
719 delete api_relation_path(relation), :params => osm_xml.to_s, :headers => headers
721 assert_response :conflict
726 def test_destroy_in_missing_changeset
727 with_unchanging(:relation) do |relation|
728 with_unchanging_request do |headers|
729 osm_xml = xml_for_relation relation
730 osm_xml = update_changeset osm_xml, 0
732 delete api_relation_path(relation), :params => osm_xml.to_s, :headers => headers
734 assert_response :conflict
739 def test_destroy_in_changeset_of_other_user
740 with_unchanging(:relation) do |relation|
741 other_user = create(:user)
743 with_unchanging_request([], [:user => other_user]) do |headers, changeset|
744 osm_xml = xml_for_relation relation
745 osm_xml = update_changeset osm_xml, changeset.id
747 delete api_relation_path(relation), :params => osm_xml.to_s, :headers => headers
749 assert_response :conflict, "shouldn't be able to delete a relation in a changeset owned by someone else (#{@response.body})"
754 def test_destroy_other_relation
755 with_unchanging(:relation) do |relation|
756 with_unchanging(:relation) do |other_relation|
757 with_unchanging_request do |headers, changeset|
758 osm_xml = xml_for_relation other_relation
759 osm_xml = update_changeset osm_xml, changeset.id
761 delete api_relation_path(relation), :params => osm_xml.to_s, :headers => headers
763 assert_response :bad_request, "shouldn't be able to delete a relation when payload is different to the url"
769 def test_destroy_relation_used_by_other_relation
770 with_unchanging(:relation) do |relation|
771 super_relation = create(:relation)
772 create(:relation_member, :relation => super_relation, :member => relation)
774 with_unchanging_request do |headers, changeset|
775 osm_xml = xml_for_relation relation
776 osm_xml = update_changeset osm_xml, changeset.id
778 delete api_relation_path(relation), :params => osm_xml.to_s, :headers => headers
780 assert_response :precondition_failed, "shouldn't be able to delete a relation used in a relation (#{@response.body})"
781 assert_equal "Precondition failed: The relation #{relation.id} is used in relation #{super_relation.id}.", @response.body
787 relation = create(:relation)
788 create_list(:relation_tag, 4, :relation => relation)
790 with_request do |headers, changeset|
791 osm_xml = xml_for_relation relation
792 osm_xml = update_changeset osm_xml, changeset.id
794 delete api_relation_path(relation), :params => osm_xml.to_s, :headers => headers
796 assert_response :success
797 assert_operator @response.body.to_i, :>, relation.version, "delete request should return a new version number for relation"
800 assert_equal 1, changeset.num_changes
801 assert_predicate changeset, :num_type_changes_in_sync?
802 assert_equal 1, changeset.num_deleted_relations
806 def test_destroy_deleted_relation
807 with_unchanging(:relation, :deleted) do |relation|
808 with_unchanging_request do |headers, changeset|
809 osm_xml = xml_for_relation relation
810 osm_xml = update_changeset osm_xml, changeset.id
812 delete api_relation_path(relation), :params => osm_xml.to_s, :headers => headers
814 assert_response :gone
819 def test_destroy_super_relation_then_used_relation
820 used_relation = create(:relation)
821 super_relation = create(:relation)
822 create(:relation_member, :relation => super_relation, :member => used_relation)
824 with_request do |headers, changeset|
825 osm_xml = xml_for_relation super_relation
826 osm_xml = update_changeset osm_xml, changeset.id
828 delete api_relation_path(super_relation), :params => osm_xml.to_s, :headers => headers
830 assert_response :success
833 with_request do |headers, changeset|
834 osm_xml = xml_for_relation used_relation
835 osm_xml = update_changeset osm_xml, changeset.id
837 delete api_relation_path(used_relation), :params => osm_xml.to_s, :headers => headers
839 assert_response :success, "should be able to delete a relation used in an old relation (#{@response.body})"
843 def test_destroy_missing_relation
844 with_unchanging_request do |headers|
845 delete api_relation_path(0), :headers => headers
847 assert_response :not_found
852 # test initial rate limit
853 def test_initial_rate_limit
858 node1 = create(:node)
859 node2 = create(:node)
861 # create a changeset that puts us near the initial rate limit
862 changeset = create(:changeset, :user => user,
863 :created_at => Time.now.utc - 5.minutes,
864 :num_changes => Settings.initial_changes_per_hour - 1)
866 # create authentication header
867 auth_header = bearer_authorization_header user
869 # try creating a relation
872 <relation changeset='#{changeset.id}'>
873 <member ref='#{node1.id}' type='node' role='some'/>
874 <member ref='#{node2.id}' type='node' role='some'/>
878 post api_relations_path, :params => xml, :headers => auth_header
879 assert_response :success, "relation create did not return success status"
881 # get the id of the relation we created
882 relationid = @response.body
884 # try updating the relation, which should be rate limited
887 <relation id='#{relationid}' version='1' changeset='#{changeset.id}'>
888 <member ref='#{node2.id}' type='node' role='some'/>
889 <member ref='#{node1.id}' type='node' role='some'/>
893 put api_relation_path(relationid), :params => xml, :headers => auth_header
894 assert_response :too_many_requests, "relation update did not hit rate limit"
896 # try deleting the relation, which should be rate limited
897 xml = "<osm><relation id='#{relationid}' version='2' changeset='#{changeset.id}'/></osm>"
898 delete api_relation_path(relationid), :params => xml, :headers => auth_header
899 assert_response :too_many_requests, "relation delete did not hit rate limit"
901 # try creating a relation, which should be rate limited
904 <relation changeset='#{changeset.id}'>
905 <member ref='#{node1.id}' type='node' role='some'/>
906 <member ref='#{node2.id}' type='node' role='some'/>
910 post api_relations_path, :params => xml, :headers => auth_header
911 assert_response :too_many_requests, "relation create did not hit rate limit"
915 # test maximum rate limit
916 def test_maximum_rate_limit
921 node1 = create(:node)
922 node2 = create(:node)
924 # create a changeset to establish our initial edit time
925 changeset = create(:changeset, :user => user,
926 :created_at => Time.now.utc - 28.days)
928 # create changeset to put us near the maximum rate limit
929 total_changes = Settings.max_changes_per_hour - 1
930 while total_changes.positive?
931 changes = [total_changes, Changeset::MAX_ELEMENTS].min
932 changeset = create(:changeset, :user => user,
933 :created_at => Time.now.utc - 5.minutes,
934 :num_changes => changes)
935 total_changes -= changes
938 # create authentication header
939 auth_header = bearer_authorization_header user
941 # try creating a relation
944 <relation changeset='#{changeset.id}'>
945 <member ref='#{node1.id}' type='node' role='some'/>
946 <member ref='#{node2.id}' type='node' role='some'/>
950 post api_relations_path, :params => xml, :headers => auth_header
951 assert_response :success, "relation create did not return success status"
953 # get the id of the relation we created
954 relationid = @response.body
956 # try updating the relation, which should be rate limited
959 <relation id='#{relationid}' version='1' changeset='#{changeset.id}'>
960 <member ref='#{node2.id}' type='node' role='some'/>
961 <member ref='#{node1.id}' type='node' role='some'/>
965 put api_relation_path(relationid), :params => xml, :headers => auth_header
966 assert_response :too_many_requests, "relation update did not hit rate limit"
968 # try deleting the relation, which should be rate limited
969 xml = "<osm><relation id='#{relationid}' version='2' changeset='#{changeset.id}'/></osm>"
970 delete api_relation_path(relationid), :params => xml, :headers => auth_header
971 assert_response :too_many_requests, "relation delete did not hit rate limit"
973 # try creating a relation, which should be rate limited
976 <relation changeset='#{changeset.id}'>
977 <member ref='#{node1.id}' type='node' role='some'/>
978 <member ref='#{node2.id}' type='node' role='some'/>
982 post api_relations_path, :params => xml, :headers => auth_header
983 assert_response :too_many_requests, "relation create did not hit rate limit"
989 [Relation, RelationTag, RelationMember,
990 OldRelation, OldRelationTag, OldRelationMember]
994 # update an attribute in the node element
995 def xml_attr_rewrite(xml, name, value)
996 xml.find("//osm/relation").first[name] = value.to_s