1 # frozen_string_literal: true
4 require_relative "elements_test_helper"
7 class RelationsControllerTest < ActionDispatch::IntegrationTest
8 include ElementsTestHelper
11 # test all routes which lead to this controller
14 { :path => "/api/0.6/relations", :method => :get },
15 { :controller => "api/relations", :action => "index" }
18 { :path => "/api/0.6/relations.json", :method => :get },
19 { :controller => "api/relations", :action => "index", :format => "json" }
22 { :path => "/api/0.6/relations", :method => :post },
23 { :controller => "api/relations", :action => "create" }
26 { :path => "/api/0.6/relation/1", :method => :get },
27 { :controller => "api/relations", :action => "show", :id => "1" }
30 { :path => "/api/0.6/relation/1.json", :method => :get },
31 { :controller => "api/relations", :action => "show", :id => "1", :format => "json" }
34 { :path => "/api/0.6/relation/1/full", :method => :get },
35 { :controller => "api/relations", :action => "show", :full => true, :id => "1" }
38 { :path => "/api/0.6/relation/1/full.json", :method => :get },
39 { :controller => "api/relations", :action => "show", :full => true, :id => "1", :format => "json" }
42 { :path => "/api/0.6/relation/1", :method => :put },
43 { :controller => "api/relations", :action => "update", :id => "1" }
46 { :path => "/api/0.6/relation/1", :method => :delete },
47 { :controller => "api/relations", :action => "destroy", :id => "1" }
51 { :controller => "api/relations", :action => "create" },
52 { :path => "/api/0.6/relation/create", :method => :put }
57 # test fetching multiple relations
59 relation1 = create(:relation)
60 relation2 = create(:relation, :deleted)
61 relation3 = create(:relation, :with_history, :version => 2)
62 relation4 = create(:relation, :with_history, :version => 2)
63 relation4.old_relations.find_by(:version => 1).redact!(create(:redaction))
65 # check error when no parameter provided
66 get api_relations_path
67 assert_response :bad_request
69 # check error when no parameter value provided
70 get api_relations_path(:relations => "")
71 assert_response :bad_request
74 get api_relations_path(:relations => "#{relation1.id},#{relation2.id},#{relation3.id},#{relation4.id}")
75 assert_response :success
76 assert_select "osm" do
77 assert_select "relation", :count => 4
78 assert_select "relation[id='#{relation1.id}'][visible='true']", :count => 1
79 assert_select "relation[id='#{relation2.id}'][visible='false']", :count => 1
80 assert_select "relation[id='#{relation3.id}'][visible='true']", :count => 1
81 assert_select "relation[id='#{relation4.id}'][visible='true']", :count => 1
84 # test a working call with json format
85 get api_relations_path(:relations => "#{relation1.id},#{relation2.id},#{relation3.id},#{relation4.id}", :format => "json")
87 js = ActiveSupport::JSON.decode(@response.body)
89 assert_equal 4, js["elements"].count
90 assert_equal(4, js["elements"].count { |a| a["type"] == "relation" })
91 assert_equal(1, js["elements"].count { |a| a["id"] == relation1.id && a["visible"].nil? })
92 assert_equal(1, js["elements"].count { |a| a["id"] == relation2.id && a["visible"] == false })
93 assert_equal(1, js["elements"].count { |a| a["id"] == relation3.id && a["visible"].nil? })
94 assert_equal(1, js["elements"].count { |a| a["id"] == relation4.id && a["visible"].nil? })
96 # check error when a non-existent relation is included
97 get api_relations_path(:relations => "#{relation1.id},#{relation2.id},#{relation3.id},#{relation4.id},0")
98 assert_response :not_found
101 # -------------------------------------
102 # Test showing relations.
103 # -------------------------------------
105 def test_show_not_found
106 get api_relation_path(0)
107 assert_response :not_found
110 def test_show_deleted
111 get api_relation_path(create(:relation, :deleted))
112 assert_response :gone
116 relation = create(:relation, :timestamp => "2021-02-03T00:00:00Z")
117 node = create(:node, :timestamp => "2021-04-05T00:00:00Z")
118 create(:relation_member, :relation => relation, :member => node)
120 get api_relation_path(relation)
122 assert_response :success
123 assert_not_nil @response.header["Last-Modified"]
124 assert_equal "2021-02-03T00:00:00Z", Time.parse(@response.header["Last-Modified"]).utc.xmlschema
125 assert_dom "node", :count => 0
126 assert_dom "relation", :count => 1 do
127 assert_dom "> @id", :text => relation.id.to_s
131 def test_full_not_found
132 get api_relation_path(999999, :full => true)
133 assert_response :not_found
136 def test_full_deleted
137 get api_relation_path(create(:relation, :deleted), :full => true)
138 assert_response :gone
142 relation = create(:relation)
144 get api_relation_path(relation, :full => true)
146 assert_response :success
147 assert_dom "relation", :count => 1 do
148 assert_dom "> @id", :text => relation.id.to_s
152 def test_full_with_node_member
153 relation = create(:relation)
155 create(:relation_member, :relation => relation, :member => node)
157 get api_relation_path(relation, :full => true)
159 assert_response :success
160 assert_dom "node", :count => 1 do
161 assert_dom "> @id", :text => node.id.to_s
163 assert_dom "relation", :count => 1 do
164 assert_dom "> @id", :text => relation.id.to_s
168 def test_full_with_way_member
169 relation = create(:relation)
170 way = create(:way_with_nodes)
171 create(:relation_member, :relation => relation, :member => way)
173 get api_relation_path(relation, :full => true)
175 assert_response :success
176 assert_dom "node", :count => 1 do
177 assert_dom "> @id", :text => way.nodes[0].id.to_s
179 assert_dom "way", :count => 1 do
180 assert_dom "> @id", :text => way.id.to_s
182 assert_dom "relation", :count => 1 do
183 assert_dom "> @id", :text => relation.id.to_s
187 def test_full_with_node_member_json
188 relation = create(:relation)
190 create(:relation_member, :relation => relation, :member => node)
192 get api_relation_path(relation, :full => true, :format => "json")
194 assert_response :success
195 js = ActiveSupport::JSON.decode(@response.body)
197 assert_equal 2, js["elements"].count
199 js_relations = js["elements"].filter { |e| e["type"] == "relation" }
200 assert_equal 1, js_relations.count
201 assert_equal relation.id, js_relations[0]["id"]
202 assert_equal 1, js_relations[0]["members"].count
203 assert_equal "node", js_relations[0]["members"][0]["type"]
204 assert_equal node.id, js_relations[0]["members"][0]["ref"]
206 js_nodes = js["elements"].filter { |e| e["type"] == "node" }
207 assert_equal 1, js_nodes.count
208 assert_equal node.id, js_nodes[0]["id"]
211 # -------------------------------------
212 # Test creating relations.
213 # -------------------------------------
215 def test_create_without_members_by_private_user
216 with_unchanging_request([:data_public => false]) do |headers, changeset|
219 <relation changeset='#{changeset.id}'>
220 <tag k='test' v='yes' />
225 post api_relations_path, :params => osm, :headers => headers
227 assert_response :forbidden, "relation upload should have failed with forbidden"
231 def test_create_with_node_member_with_role_by_private_user
234 with_unchanging_request([:data_public => false]) do |headers, changeset|
237 <relation changeset='#{changeset.id}'>
238 <member ref='#{node.id}' type='node' role='some'/>
239 <tag k='test' v='yes' />
244 post api_relations_path, :params => osm, :headers => headers
246 assert_response :forbidden, "relation upload did not return forbidden status"
250 def test_create_with_node_member_without_role_by_private_user
253 with_unchanging_request([:data_public => false]) do |headers, changeset|
256 <relation changeset='#{changeset.id}'>
257 <member ref='#{node.id}' type='node'/>
258 <tag k='test' v='yes' />
263 post api_relations_path, :params => osm, :headers => headers
265 assert_response :forbidden, "relation upload did not return forbidden status"
269 def test_create_with_node_and_way_members_by_private_user
271 way = create(:way_with_nodes, :nodes_count => 2)
273 with_unchanging_request([:data_public => false]) do |headers, changeset|
276 <relation changeset='#{changeset.id}'>
277 <member type='node' ref='#{node.id}' role='some'/>
278 <member type='way' ref='#{way.id}' role='other'/>
279 <tag k='test' v='yes' />
284 post api_relations_path, :params => osm, :headers => headers
286 assert_response :forbidden, "relation upload did not return success status"
290 def test_create_without_members
291 with_request do |headers, changeset|
292 assert_difference "Relation.count" => 1,
293 "RelationMember.count" => 0 do
296 <relation changeset='#{changeset.id}'>
297 <tag k='test' v='yes' />
302 post api_relations_path, :params => osm, :headers => headers
304 assert_response :success, "relation upload did not return success status"
307 created_relation_id = @response.body
308 relation = Relation.find(created_relation_id)
309 assert_empty relation.members
310 assert_equal({ "test" => "yes" }, relation.tags)
311 assert_equal changeset.id, relation.changeset_id, "saved relation does not belong in the changeset it was assigned to"
312 assert relation.visible, "saved relation is not visible"
315 assert_equal 1, changeset.num_changes
316 assert_predicate changeset, :num_type_changes_in_sync?
317 assert_equal 1, changeset.num_created_relations
321 def test_create_with_node_member_with_role
324 with_request do |headers, changeset|
325 assert_difference "Relation.count" => 1,
326 "RelationMember.count" => 1 do
329 <relation changeset='#{changeset.id}'>
330 <member ref='#{node.id}' type='node' role='some'/>
331 <tag k='test' v='yes' />
336 post api_relations_path, :params => osm, :headers => headers
338 assert_response :success, "relation upload did not return success status"
341 created_relation_id = @response.body
342 relation = Relation.find(created_relation_id)
343 assert_equal [["Node", node.id, "some"]], relation.members
344 assert_equal({ "test" => "yes" }, relation.tags)
345 assert_equal changeset.id, relation.changeset_id, "saved relation does not belong in the changeset it was assigned to"
346 assert relation.visible, "saved relation is not visible"
349 assert_equal 1, changeset.num_changes
350 assert_predicate changeset, :num_type_changes_in_sync?
351 assert_equal 1, changeset.num_created_relations
355 def test_create_with_node_member_without_role
358 with_request do |headers, changeset|
359 assert_difference "Relation.count" => 1,
360 "RelationMember.count" => 1 do
363 <relation changeset='#{changeset.id}'>
364 <member ref='#{node.id}' type='node'/>
365 <tag k='test' v='yes' />
370 post api_relations_path, :params => osm, :headers => headers
372 assert_response :success, "relation upload did not return success status"
375 created_relation_id = @response.body
376 relation = Relation.find(created_relation_id)
377 assert_equal [["Node", node.id, ""]], relation.members
378 assert_equal({ "test" => "yes" }, relation.tags)
379 assert_equal changeset.id, relation.changeset_id, "saved relation does not belong in the changeset it was assigned to"
380 assert relation.visible, "saved relation is not visible"
383 assert_equal 1, changeset.num_changes
384 assert_predicate changeset, :num_type_changes_in_sync?
385 assert_equal 1, changeset.num_created_relations
389 def test_create_with_node_and_way_members
391 way = create(:way_with_nodes, :nodes_count => 2)
393 with_request do |headers, changeset|
394 assert_difference "Relation.count" => 1,
395 "RelationMember.count" => 2 do
398 <relation changeset='#{changeset.id}'>
399 <member type='node' ref='#{node.id}' role='some'/>
400 <member type='way' ref='#{way.id}' role='other'/>
401 <tag k='test' v='yes' />
406 post api_relations_path, :params => osm, :headers => headers
408 assert_response :success, "relation upload did not return success status"
411 created_relation_id = @response.body
412 relation = Relation.find(created_relation_id)
413 assert_equal [["Node", node.id, "some"],
414 ["Way", way.id, "other"]], relation.members
415 assert_equal({ "test" => "yes" }, relation.tags)
416 assert_equal changeset.id, relation.changeset_id, "saved relation does not belong in the changeset it was assigned to"
417 assert relation.visible, "saved relation is not visible"
420 assert_equal 1, changeset.num_changes
421 assert_predicate changeset, :num_type_changes_in_sync?
422 assert_equal 1, changeset.num_created_relations
426 def test_create_in_missing_changeset
429 with_unchanging_request do |headers|
432 <relation changeset='0'>
433 <member type='node' ref='#{node.id}' role='some'/>
438 post api_relations_path, :params => osm, :headers => headers
440 assert_response :conflict
444 def test_create_with_missing_node_member
445 with_unchanging_request do |headers, changeset|
448 <relation changeset='#{changeset.id}'>
449 <member type='node' ref='0'/>
454 post api_relations_path, :params => osm, :headers => headers
456 assert_response :precondition_failed, "relation upload with invalid node did not return 'precondition failed'"
457 assert_equal "Precondition failed: Relation with id cannot be saved due to Node with id 0", @response.body
461 def test_create_with_invalid_member_type
464 with_unchanging_request do |headers, changeset|
467 <relation changeset='#{changeset.id}'>
468 <member type='type' ref='#{node.id}' role=''/>
473 post api_relations_path, :params => osm, :headers => headers
475 assert_response :bad_request
476 assert_match(/Cannot parse valid relation from xml string/, @response.body)
477 assert_match(/The type is not allowed only, /, @response.body)
481 def test_create_and_show
483 changeset = create(:changeset, :user => user)
487 <relation changeset='#{changeset.id}'/>
491 post api_relations_path, :params => osm, :headers => bearer_authorization_header(user)
493 assert_response :success, "relation upload did not return success status"
495 created_relation_id = @response.body
497 get api_relation_path(created_relation_id)
499 assert_response :success
502 def test_create_race_condition
504 changeset = create(:changeset, :user => user)
506 auth_header = bearer_authorization_header user
507 path = api_relations_path
508 concurrency_level = 16
510 threads = Array.new(concurrency_level) do
514 <relation changeset='#{changeset.id}'>
515 <member type='node' ref='#{node.id}' role=''/>
519 post path, :params => osm, :headers => auth_header
525 assert_equal concurrency_level, changeset.num_changes
526 assert_predicate changeset, :num_type_changes_in_sync?
527 assert_equal concurrency_level, changeset.num_created_relations
530 # ------------------------------------
531 # Test updating relations
532 # ------------------------------------
535 relation = create(:relation)
537 with_request do |headers, changeset|
538 osm_xml = xml_for_relation relation
539 osm_xml = update_changeset osm_xml, changeset.id
541 put api_relation_path(relation), :params => osm_xml.to_s, :headers => headers
543 assert_response :success
546 assert_equal 2, relation.version
549 assert_equal 1, changeset.num_changes
550 assert_predicate changeset, :num_type_changes_in_sync?
551 assert_equal 1, changeset.num_modified_relations
555 def test_update_in_missing_changeset
556 with_unchanging(:relation) do |relation|
557 with_unchanging_request do |headers|
558 osm_xml = xml_for_relation relation
559 osm_xml = update_changeset osm_xml, 0
561 put api_relation_path(relation), :params => osm_xml.to_s, :headers => headers
563 assert_response :conflict, "update with changeset=0 should be rejected"
568 def test_update_other_relation
569 with_unchanging(:relation) do |relation|
570 with_unchanging(:relation) do |other_relation|
571 with_unchanging_request do |headers, changeset|
572 osm_xml = xml_for_relation other_relation
573 osm_xml = update_changeset osm_xml, changeset.id
575 put api_relation_path(relation), :params => osm_xml.to_s, :headers => headers
577 assert_response :bad_request
583 # -------------------------------------
584 # Test deleting relations.
585 # -------------------------------------
587 def test_destroy_when_unauthorized
588 with_unchanging(:relation) do |relation|
589 delete api_relation_path(relation)
591 assert_response :unauthorized
595 def test_destroy_without_payload_by_private_user
596 with_unchanging(:relation) do |relation|
597 with_unchanging_request([:data_public => false]) do |headers|
598 delete api_relation_path(relation), :headers => headers
600 assert_response :forbidden
605 def test_destroy_without_changeset_id_by_private_user
606 with_unchanging(:relation) do |relation|
607 with_unchanging_request([:data_public => false]) do |headers|
608 osm = "<osm><relation id='#{relation.id}' version='#{relation.version}'/></osm>"
610 delete api_relation_path(relation), :params => osm, :headers => headers
612 assert_response :forbidden
617 def test_destroy_in_closed_changeset_by_private_user
618 with_unchanging(:relation) do |relation|
619 with_unchanging_request([:data_public => false], [:closed]) do |headers, changeset|
620 osm_xml = xml_for_relation relation
621 osm_xml = update_changeset osm_xml, changeset.id
623 delete api_relation_path(relation), :params => osm_xml.to_s, :headers => headers
625 assert_response :forbidden
630 def test_destroy_in_missing_changeset_by_private_user
631 with_unchanging(:relation) do |relation|
632 with_unchanging_request([:data_public => false]) do |headers|
633 osm_xml = xml_for_relation relation
634 osm_xml = update_changeset osm_xml, 0
636 delete api_relation_path(relation), :params => osm_xml.to_s, :headers => headers
638 assert_response :forbidden
643 def test_destroy_relation_used_by_other_relation_by_private_user
644 with_unchanging(:relation) do |relation|
645 create(:relation_member, :member => relation)
647 with_unchanging_request([:data_public => false]) do |headers, changeset|
648 osm_xml = xml_for_relation relation
649 osm_xml = update_changeset osm_xml, changeset.id
651 delete api_relation_path(relation), :params => osm_xml.to_s, :headers => headers
653 assert_response :forbidden
658 def test_destroy_by_private_user
659 with_unchanging(:relation) do |relation|
660 with_unchanging_request([:data_public => false]) do |headers, changeset|
661 osm_xml = xml_for_relation relation
662 osm_xml = update_changeset osm_xml, changeset.id
664 delete api_relation_path(relation), :params => osm_xml.to_s, :headers => headers
666 assert_response :forbidden
671 def test_destroy_deleted_relation_by_private_user
672 with_unchanging(:relation, :deleted) do |relation|
673 with_unchanging_request([:data_public => false]) do |headers, changeset|
674 osm_xml = xml_for_relation relation
675 osm_xml = update_changeset osm_xml, changeset.id
677 delete api_relation_path(relation), :params => osm_xml.to_s, :headers => headers
679 assert_response :forbidden
684 def test_destroy_missing_relation_by_private_user
685 with_unchanging_request([:data_public => false]) do |headers|
686 delete api_relation_path(0), :headers => headers
688 assert_response :forbidden
692 def test_destroy_without_payload
693 with_unchanging(:relation) do |relation|
694 with_unchanging_request do |headers|
695 delete api_relation_path(relation), :headers => headers
697 assert_response :bad_request
702 def test_destroy_without_changeset_id
703 with_unchanging(:relation) do |relation|
704 with_unchanging_request do |headers|
705 osm = "<osm><relation id='#{relation.id}' version='#{relation.version}'/></osm>"
707 delete api_relation_path(relation), :params => osm, :headers => headers
709 assert_response :bad_request
710 assert_match(/Changeset id is missing/, @response.body)
715 def test_destroy_in_closed_changeset
716 with_unchanging(:relation) do |relation|
717 with_unchanging_request([], [:closed]) do |headers, changeset|
718 osm_xml = xml_for_relation relation
719 osm_xml = update_changeset osm_xml, changeset.id
721 delete api_relation_path(relation), :params => osm_xml.to_s, :headers => headers
723 assert_response :conflict
728 def test_destroy_in_missing_changeset
729 with_unchanging(:relation) do |relation|
730 with_unchanging_request do |headers|
731 osm_xml = xml_for_relation relation
732 osm_xml = update_changeset osm_xml, 0
734 delete api_relation_path(relation), :params => osm_xml.to_s, :headers => headers
736 assert_response :conflict
741 def test_destroy_in_changeset_of_other_user
742 with_unchanging(:relation) do |relation|
743 other_user = create(:user)
745 with_unchanging_request([], [:user => other_user]) do |headers, changeset|
746 osm_xml = xml_for_relation relation
747 osm_xml = update_changeset osm_xml, changeset.id
749 delete api_relation_path(relation), :params => osm_xml.to_s, :headers => headers
751 assert_response :conflict, "shouldn't be able to delete a relation in a changeset owned by someone else (#{@response.body})"
756 def test_destroy_other_relation
757 with_unchanging(:relation) do |relation|
758 with_unchanging(:relation) do |other_relation|
759 with_unchanging_request do |headers, changeset|
760 osm_xml = xml_for_relation other_relation
761 osm_xml = update_changeset osm_xml, changeset.id
763 delete api_relation_path(relation), :params => osm_xml.to_s, :headers => headers
765 assert_response :bad_request, "shouldn't be able to delete a relation when payload is different to the url"
771 def test_destroy_relation_used_by_other_relation
772 with_unchanging(:relation) do |relation|
773 super_relation = create(:relation)
774 create(:relation_member, :relation => super_relation, :member => relation)
776 with_unchanging_request do |headers, changeset|
777 osm_xml = xml_for_relation relation
778 osm_xml = update_changeset osm_xml, changeset.id
780 delete api_relation_path(relation), :params => osm_xml.to_s, :headers => headers
782 assert_response :precondition_failed, "shouldn't be able to delete a relation used in a relation (#{@response.body})"
783 assert_equal "Precondition failed: The relation #{relation.id} is used in relation #{super_relation.id}.", @response.body
789 relation = create(:relation)
790 create_list(:relation_tag, 4, :relation => relation)
792 with_request do |headers, changeset|
793 osm_xml = xml_for_relation relation
794 osm_xml = update_changeset osm_xml, changeset.id
796 delete api_relation_path(relation), :params => osm_xml.to_s, :headers => headers
798 assert_response :success
799 assert_operator @response.body.to_i, :>, relation.version, "delete request should return a new version number for relation"
802 assert_equal 1, changeset.num_changes
803 assert_predicate changeset, :num_type_changes_in_sync?
804 assert_equal 1, changeset.num_deleted_relations
808 def test_destroy_deleted_relation
809 with_unchanging(:relation, :deleted) do |relation|
810 with_unchanging_request do |headers, changeset|
811 osm_xml = xml_for_relation relation
812 osm_xml = update_changeset osm_xml, changeset.id
814 delete api_relation_path(relation), :params => osm_xml.to_s, :headers => headers
816 assert_response :gone
821 def test_destroy_super_relation_then_used_relation
822 used_relation = create(:relation)
823 super_relation = create(:relation)
824 create(:relation_member, :relation => super_relation, :member => used_relation)
826 with_request do |headers, changeset|
827 osm_xml = xml_for_relation super_relation
828 osm_xml = update_changeset osm_xml, changeset.id
830 delete api_relation_path(super_relation), :params => osm_xml.to_s, :headers => headers
832 assert_response :success
835 with_request do |headers, changeset|
836 osm_xml = xml_for_relation used_relation
837 osm_xml = update_changeset osm_xml, changeset.id
839 delete api_relation_path(used_relation), :params => osm_xml.to_s, :headers => headers
841 assert_response :success, "should be able to delete a relation used in an old relation (#{@response.body})"
845 def test_destroy_missing_relation
846 with_unchanging_request do |headers|
847 delete api_relation_path(0), :headers => headers
849 assert_response :not_found
854 # test initial rate limit
855 def test_initial_rate_limit
860 node1 = create(:node)
861 node2 = create(:node)
863 # create a changeset that puts us near the initial rate limit
864 changeset = create(:changeset, :user => user,
865 :created_at => Time.now.utc - 5.minutes,
866 :num_changes => Settings.initial_changes_per_hour - 1)
868 # create authentication header
869 auth_header = bearer_authorization_header user
871 # try creating a relation
874 <relation changeset='#{changeset.id}'>
875 <member ref='#{node1.id}' type='node' role='some'/>
876 <member ref='#{node2.id}' type='node' role='some'/>
880 post api_relations_path, :params => xml, :headers => auth_header
881 assert_response :success, "relation create did not return success status"
883 # get the id of the relation we created
884 relationid = @response.body
886 # try updating the relation, which should be rate limited
889 <relation id='#{relationid}' version='1' changeset='#{changeset.id}'>
890 <member ref='#{node2.id}' type='node' role='some'/>
891 <member ref='#{node1.id}' type='node' role='some'/>
895 put api_relation_path(relationid), :params => xml, :headers => auth_header
896 assert_response :too_many_requests, "relation update did not hit rate limit"
898 # try deleting the relation, which should be rate limited
899 xml = "<osm><relation id='#{relationid}' version='2' changeset='#{changeset.id}'/></osm>"
900 delete api_relation_path(relationid), :params => xml, :headers => auth_header
901 assert_response :too_many_requests, "relation delete did not hit rate limit"
903 # try creating a relation, which should be rate limited
906 <relation changeset='#{changeset.id}'>
907 <member ref='#{node1.id}' type='node' role='some'/>
908 <member ref='#{node2.id}' type='node' role='some'/>
912 post api_relations_path, :params => xml, :headers => auth_header
913 assert_response :too_many_requests, "relation create did not hit rate limit"
917 # test maximum rate limit
918 def test_maximum_rate_limit
923 node1 = create(:node)
924 node2 = create(:node)
926 # create a changeset to establish our initial edit time
927 changeset = create(:changeset, :user => user,
928 :created_at => Time.now.utc - 28.days)
930 # create changeset to put us near the maximum rate limit
931 total_changes = Settings.max_changes_per_hour - 1
932 while total_changes.positive?
933 changes = [total_changes, Changeset::MAX_ELEMENTS].min
934 changeset = create(:changeset, :user => user,
935 :created_at => Time.now.utc - 5.minutes,
936 :num_changes => changes)
937 total_changes -= changes
940 # create authentication header
941 auth_header = bearer_authorization_header user
943 # try creating a relation
946 <relation changeset='#{changeset.id}'>
947 <member ref='#{node1.id}' type='node' role='some'/>
948 <member ref='#{node2.id}' type='node' role='some'/>
952 post api_relations_path, :params => xml, :headers => auth_header
953 assert_response :success, "relation create did not return success status"
955 # get the id of the relation we created
956 relationid = @response.body
958 # try updating the relation, which should be rate limited
961 <relation id='#{relationid}' version='1' changeset='#{changeset.id}'>
962 <member ref='#{node2.id}' type='node' role='some'/>
963 <member ref='#{node1.id}' type='node' role='some'/>
967 put api_relation_path(relationid), :params => xml, :headers => auth_header
968 assert_response :too_many_requests, "relation update did not hit rate limit"
970 # try deleting the relation, which should be rate limited
971 xml = "<osm><relation id='#{relationid}' version='2' changeset='#{changeset.id}'/></osm>"
972 delete api_relation_path(relationid), :params => xml, :headers => auth_header
973 assert_response :too_many_requests, "relation delete did not hit rate limit"
975 # try creating a relation, which should be rate limited
978 <relation changeset='#{changeset.id}'>
979 <member ref='#{node1.id}' type='node' role='some'/>
980 <member ref='#{node2.id}' type='node' role='some'/>
984 post api_relations_path, :params => xml, :headers => auth_header
985 assert_response :too_many_requests, "relation create did not hit rate limit"
991 [Relation, RelationTag, RelationMember,
992 OldRelation, OldRelationTag, OldRelationMember]
996 # update an attribute in the node element
997 def xml_attr_rewrite(xml, name, value)
998 xml.find("//osm/relation").first[name] = value.to_s