2 require_relative "elements_test_helper"
5 class NodesControllerTest < ActionDispatch::IntegrationTest
6 include ElementsTestHelper
9 # test all routes which lead to this controller
12 { :path => "/api/0.6/nodes", :method => :get },
13 { :controller => "api/nodes", :action => "index" }
16 { :path => "/api/0.6/nodes.json", :method => :get },
17 { :controller => "api/nodes", :action => "index", :format => "json" }
20 { :path => "/api/0.6/nodes", :method => :post },
21 { :controller => "api/nodes", :action => "create" }
24 { :path => "/api/0.6/node/1", :method => :get },
25 { :controller => "api/nodes", :action => "show", :id => "1" }
28 { :path => "/api/0.6/node/1.json", :method => :get },
29 { :controller => "api/nodes", :action => "show", :id => "1", :format => "json" }
32 { :path => "/api/0.6/node/1", :method => :put },
33 { :controller => "api/nodes", :action => "update", :id => "1" }
36 { :path => "/api/0.6/node/1", :method => :delete },
37 { :controller => "api/nodes", :action => "destroy", :id => "1" }
41 { :controller => "api/nodes", :action => "create" },
42 { :path => "/api/0.6/node/create", :method => :put }
47 # test fetching multiple nodes
50 node2 = create(:node, :deleted)
52 node4 = create(:node, :with_history, :version => 2)
53 node5 = create(:node, :deleted, :with_history, :version => 2)
55 # check error when no parameter provided
57 assert_response :bad_request
59 # check error when no parameter value provided
60 get api_nodes_path(:nodes => "")
61 assert_response :bad_request
64 get api_nodes_path(:nodes => "#{node1.id},#{node2.id},#{node3.id},#{node4.id},#{node5.id}")
65 assert_response :success
66 assert_select "osm" do
67 assert_select "node", :count => 5
68 assert_select "node[id='#{node1.id}'][visible='true']", :count => 1
69 assert_select "node[id='#{node2.id}'][visible='false']", :count => 1
70 assert_select "node[id='#{node3.id}'][visible='true']", :count => 1
71 assert_select "node[id='#{node4.id}'][visible='true']", :count => 1
72 assert_select "node[id='#{node5.id}'][visible='false']", :count => 1
75 # test a working call with json format
76 get api_nodes_path(:nodes => "#{node1.id},#{node2.id},#{node3.id},#{node4.id},#{node5.id}", :format => "json")
78 js = ActiveSupport::JSON.decode(@response.body)
80 assert_equal 5, js["elements"].count
81 assert_equal 5, (js["elements"].count { |a| a["type"] == "node" })
82 assert_equal 1, (js["elements"].count { |a| a["id"] == node1.id && a["visible"].nil? })
83 assert_equal 1, (js["elements"].count { |a| a["id"] == node2.id && a["visible"] == false })
84 assert_equal 1, (js["elements"].count { |a| a["id"] == node3.id && a["visible"].nil? })
85 assert_equal 1, (js["elements"].count { |a| a["id"] == node4.id && a["visible"].nil? })
86 assert_equal 1, (js["elements"].count { |a| a["id"] == node5.id && a["visible"] == false })
88 # check error when a non-existent node is included
89 get api_nodes_path(:nodes => "#{node1.id},#{node2.id},#{node3.id},#{node4.id},#{node5.id},0")
90 assert_response :not_found
93 def test_create_when_unauthorized
94 with_unchanging_request do |_headers, changeset|
95 osm = "<osm><node lat='0' lon='0' changeset='#{changeset.id}'/></osm>"
97 post api_nodes_path, :params => osm
99 assert_response :unauthorized
103 def test_create_by_private_user
104 with_unchanging_request([:data_public => false]) do |headers, changeset|
105 osm = "<osm><node lat='0' lon='0' changeset='#{changeset.id}'/></osm>"
107 post api_nodes_path, :params => osm, :headers => headers
109 assert_require_public_data "node create did not return forbidden status"
114 with_request do |headers, changeset|
115 lat = rand(-50..50) + rand
116 lon = rand(-50..50) + rand
118 assert_difference "Node.count", 1 do
119 osm = "<osm><node lat='#{lat}' lon='#{lon}' changeset='#{changeset.id}'/></osm>"
121 post api_nodes_path, :params => osm, :headers => headers
123 assert_response :success, "node upload did not return success status"
126 created_node_id = @response.body
127 node = Node.find(created_node_id)
128 assert_in_delta lat * 10000000, node.latitude, 1, "saved node does not match requested latitude"
129 assert_in_delta lon * 10000000, node.longitude, 1, "saved node does not match requested longitude"
130 assert_equal changeset.id, node.changeset_id, "saved node does not belong to changeset that it was created in"
131 assert node.visible, "saved node is not visible"
134 assert_equal 1, changeset.num_changes
135 assert_predicate changeset, :num_type_changes_in_sync?
136 assert_equal 1, changeset.num_created_nodes
140 def test_create_with_invalid_osm_structure
141 with_unchanging_request do |headers|
144 post api_nodes_path, :params => osm, :headers => headers
146 assert_response :bad_request, "node upload did not return bad_request status"
147 assert_equal "Cannot parse valid node from xml string <create/>. XML doesn't contain an osm/node element.", @response.body
151 def test_create_without_lat
152 with_unchanging_request do |headers, changeset|
153 osm = "<osm><node lon='3.23' changeset='#{changeset.id}'/></osm>"
155 post api_nodes_path, :params => osm, :headers => headers
157 assert_response :bad_request, "node upload did not return bad_request status"
158 assert_equal "Cannot parse valid node from xml string <node lon=\"3.23\" changeset=\"#{changeset.id}\"/>. lat missing", @response.body
162 def test_create_without_lon
163 with_unchanging_request do |headers, changeset|
164 osm = "<osm><node lat='3.434' changeset='#{changeset.id}'/></osm>"
166 post api_nodes_path, :params => osm, :headers => headers
168 assert_response :bad_request, "node upload did not return bad_request status"
169 assert_equal "Cannot parse valid node from xml string <node lat=\"3.434\" changeset=\"#{changeset.id}\"/>. lon missing", @response.body
173 def test_create_with_non_numeric_lat
174 with_unchanging_request do |headers, changeset|
175 osm = "<osm><node lat='abc' lon='3.23' changeset='#{changeset.id}'/></osm>"
177 post api_nodes_path, :params => osm, :headers => headers
179 assert_response :bad_request, "node upload did not return bad_request status"
180 assert_equal "Cannot parse valid node from xml string <node lat=\"abc\" lon=\"3.23\" changeset=\"#{changeset.id}\"/>. lat not a number", @response.body
184 def test_create_with_non_numeric_lon
185 with_unchanging_request do |headers, changeset|
186 osm = "<osm><node lat='3.434' lon='abc' changeset='#{changeset.id}'/></osm>"
188 post api_nodes_path, :params => osm, :headers => headers
190 assert_response :bad_request, "node upload did not return bad_request status"
191 assert_equal "Cannot parse valid node from xml string <node lat=\"3.434\" lon=\"abc\" changeset=\"#{changeset.id}\"/>. lon not a number", @response.body
195 def test_create_with_tag_too_long
196 with_unchanging_request do |headers, changeset|
197 osm = "<osm><node lat='3.434' lon='3.23' changeset='#{changeset.id}'><tag k='foo' v='#{'x' * 256}'/></node></osm>"
199 post api_nodes_path, :params => osm, :headers => headers
201 assert_response :bad_request, "node upload did not return bad_request status"
202 assert_match(/ v: is too long \(maximum is 255 characters\) /, @response.body)
207 # try and put something into a string that the API might
208 # use unquoted and therefore allow code injection
209 def test_create_with_string_injection_by_private_user
210 with_unchanging_request([:data_public => false]) do |headers, changeset|
213 <node lat='0' lon='0' changeset='#{changeset.id}'>
214 <tag k='\#{@user.inspect}' v='0'/>
219 post api_nodes_path, :params => osm, :headers => headers
221 assert_require_public_data "Shouldn't be able to create with non-public user"
226 # try and put something into a string that the API might
227 # use unquoted and therefore allow code injection
228 def test_create_with_string_injection
229 with_request do |headers, changeset|
230 assert_difference "Node.count", 1 do
233 <node lat='0' lon='0' changeset='#{changeset.id}'>
234 <tag k='\#{@user.inspect}' v='0'/>
239 post api_nodes_path, :params => osm, :headers => headers
241 assert_response :success
244 created_node_id = @response.body
245 db_node = Node.find(created_node_id)
247 get api_node_path(created_node_id)
249 assert_response :success
251 api_node = Node.from_xml(@response.body)
252 assert_not_nil api_node, "downloaded node is nil, but shouldn't be"
253 assert_equal db_node.tags, api_node.tags, "tags are corrupted"
254 assert_includes api_node.tags, "\#{@user.inspect}"
258 def test_show_not_found
260 assert_response :not_found
263 def test_show_deleted
264 get api_node_path(create(:node, :deleted))
265 assert_response :gone
269 node = create(:node, :timestamp => "2021-02-03T00:00:00Z")
271 get api_node_path(node)
273 assert_response :success
274 assert_not_nil @response.header["Last-Modified"]
275 assert_equal "2021-02-03T00:00:00Z", Time.parse(@response.header["Last-Modified"]).utc.xmlschema
278 def test_show_lat_lon_decimal_format
279 node = create(:node, :latitude => (0.00004 * OldNode::SCALE).to_i, :longitude => (0.00008 * OldNode::SCALE).to_i)
281 get api_node_path(node)
283 assert_match(/lat="0.0000400"/, response.body)
284 assert_match(/lon="0.0000800"/, response.body)
287 def test_destroy_when_unauthorized
288 with_unchanging(:node) do |node|
289 delete api_node_path(node)
291 assert_response :unauthorized
295 def test_destroy_in_closed_changeset_by_private_user
296 with_unchanging(:node) do |node|
297 with_unchanging_request([:data_public => false], [:closed]) do |headers, changeset|
298 osm_xml = xml_for_node node
299 osm_xml = update_changeset osm_xml, changeset.id
301 delete api_node_path(node), :params => osm_xml.to_s, :headers => headers
303 assert_require_public_data "non-public user shouldn't be able to delete node"
308 def test_destroy_in_missing_changeset_by_private_user
309 with_unchanging(:node) do |node|
310 with_unchanging_request([:data_public => false]) do |headers|
311 osm_xml = xml_for_node node
312 osm_xml = update_changeset osm_xml, 0
314 delete api_node_path(node), :params => osm_xml.to_s, :headers => headers
316 assert_require_public_data "shouldn't be able to delete node, when user's data is private"
321 def test_destroy_by_private_user
322 with_unchanging(:node) do |node|
323 with_unchanging_request([:data_public => false]) do |headers, changeset|
324 osm_xml = xml_for_node node
325 osm_xml = update_changeset osm_xml, changeset.id
327 delete api_node_path(node), :params => osm_xml.to_s, :headers => headers
329 assert_require_public_data "shouldn't be able to delete node when user's data isn't public'"
334 def test_destroy_deleted_node_by_private_user
335 with_unchanging(:node, :deleted) do |node|
336 with_unchanging_request([:data_public => false]) do |headers, changeset|
337 osm_xml = "<osm><node id='#{node.id}' changeset='#{changeset.id}' version='1' lat='0' lon='0'/></osm>"
339 delete api_node_path(node), :params => osm_xml.to_s, :headers => headers
341 assert_require_public_data
346 def test_destroy_missing_node_by_private_user
347 with_unchanging_request([:data_public => false]) do |headers|
348 delete api_node_path(0), :headers => headers
350 assert_require_public_data
354 def test_destroy_node_in_way_by_private_user
355 with_unchanging(:node) do |node|
356 create(:way_node, :node => node)
358 with_unchanging_request([:data_public => false]) do |headers, changeset|
359 osm_xml = xml_for_node node
360 osm_xml = update_changeset osm_xml, changeset.id
362 delete api_node_path(node), :params => osm_xml.to_s, :headers => headers
364 assert_require_public_data "shouldn't be able to delete a node used in a way (#{@response.body})"
369 def test_destroy_node_in_relation_by_private_user
370 with_unchanging(:node) do |node|
371 create(:relation_member, :member => node)
373 with_unchanging_request([:data_public => false]) do |headers, changeset|
374 osm_xml = xml_for_node node
375 osm_xml = update_changeset osm_xml, changeset.id
377 delete api_node_path(node), :params => osm_xml.to_s, :headers => headers
379 assert_require_public_data "shouldn't be able to delete a node used in a relation (#{@response.body})"
384 def test_destroy_in_closed_changeset
385 with_unchanging(:node) do |node|
386 with_unchanging_request([], [:closed]) do |headers, changeset|
387 osm_xml = xml_for_node node
388 osm_xml = update_changeset osm_xml, changeset.id
390 delete api_node_path(node), :params => osm_xml.to_s, :headers => headers
392 assert_response :conflict
397 def test_destroy_in_missing_changeset
398 with_unchanging(:node) do |node|
399 with_unchanging_request do |headers|
400 osm_xml = xml_for_node node
401 osm_xml = update_changeset osm_xml, 0
403 delete api_node_path(node), :params => osm_xml.to_s, :headers => headers
405 assert_response :conflict
410 def test_destroy_different_node
411 with_unchanging(:node) do |node|
412 with_unchanging(:node) do |other_node|
413 with_unchanging_request do |headers, changeset|
414 osm_xml = xml_for_node other_node
415 osm_xml = update_changeset osm_xml, changeset.id
417 delete api_node_path(node), :params => osm_xml.to_s, :headers => headers
419 assert_response :bad_request, "should not be able to delete a node with a different ID from the XML"
425 def test_destroy_invalid_osm_structure
426 with_unchanging(:node) do |node|
427 with_unchanging_request do |headers|
430 delete api_node_path(node), :params => osm, :headers => headers
432 assert_response :bad_request, "should not be able to delete a node without a valid XML payload"
438 with_request do |headers, changeset|
440 osm_xml = xml_for_node node
441 osm_xml = update_changeset osm_xml, changeset.id
443 delete api_node_path(node), :params => osm_xml.to_s, :headers => headers
445 assert_response :success
447 response_node_version = @response.body.to_i
448 assert_operator response_node_version, :>, node.version, "delete request should return a new version number for node"
450 assert_not_predicate node, :visible?
451 assert_equal response_node_version, node.version
455 def test_destroy_twice
457 node = create(:node, :changeset => create(:changeset, :user => user))
458 osm_xml = xml_for_node node
460 delete api_node_path(node), :params => osm_xml.to_s, :headers => bearer_authorization_header(user)
462 assert_response :success
464 delete api_node_path(node), :params => osm_xml.to_s, :headers => bearer_authorization_header(user)
466 assert_response :gone
469 def test_destroy_deleted_node
470 with_unchanging(:node, :deleted) do |node|
471 with_unchanging_request do |headers, changeset|
472 osm = "<osm><node id='#{node.id}' changeset='#{changeset.id}' version='1' lat='0' lon='0'/></osm>"
474 delete api_node_path(node), :params => osm, :headers => headers
476 assert_response :gone
481 def test_destroy_missing_node
482 with_unchanging_request do |headers|
483 delete api_node_path(0), :headers => headers
485 assert_response :not_found
489 def test_destroy_node_in_ways
490 with_unchanging(:node) do |node|
491 way_node = create(:way_node, :node => node)
492 way_node2 = create(:way_node, :node => node)
494 with_unchanging_request do |headers, changeset|
495 osm_xml = xml_for_node node
496 osm_xml = update_changeset osm_xml, changeset.id
498 delete api_node_path(node), :params => osm_xml.to_s, :headers => headers
500 assert_response :precondition_failed, "shouldn't be able to delete a node used in a way (#{@response.body})"
501 assert_equal "Precondition failed: Node #{node.id} is still used by ways #{way_node.way.id},#{way_node2.way.id}.", @response.body
506 def test_destroy_node_in_relations
507 with_unchanging(:node) do |node|
508 relation_member = create(:relation_member, :member => node)
509 relation_member2 = create(:relation_member, :member => node)
511 with_unchanging_request do |headers, changeset|
512 osm_xml = xml_for_node node
513 osm_xml = update_changeset osm_xml, changeset.id
515 delete api_node_path(node), :params => osm_xml.to_s, :headers => headers
517 assert_response :precondition_failed, "shouldn't be able to delete a node used in a relation (#{@response.body})"
518 assert_equal "Precondition failed: Node #{node.id} is still used by relations #{relation_member.relation.id},#{relation_member2.relation.id}.", @response.body
523 def test_update_when_unauthorized
524 with_unchanging(:node) do |node|
525 osm_xml = xml_for_node node
527 put api_node_path(node), :params => osm_xml.to_s
529 assert_response :unauthorized
533 def test_update_in_changeset_of_other_user_by_private_user
534 with_unchanging(:node) do |node|
535 other_user = create(:user)
537 with_unchanging_request([:data_public => false], [:user => other_user]) do |headers, changeset|
538 osm_xml = xml_for_node node
539 osm_xml = update_changeset osm_xml, changeset.id
541 put api_node_path(node), :params => osm_xml.to_s, :headers => headers
543 assert_require_public_data "update with other user's changeset should be forbidden when data isn't public"
548 def test_update_in_closed_changeset_by_private_user
549 with_unchanging(:node) do |node|
550 with_unchanging_request([:data_public => false], [:closed]) do |headers, changeset|
551 osm_xml = xml_for_node node
552 osm_xml = update_changeset osm_xml, changeset.id
554 put api_node_path(node), :params => osm_xml.to_s, :headers => headers
556 assert_require_public_data "update with closed changeset should be forbidden, when data isn't public"
561 def test_update_in_missing_changeset_by_private_user
562 with_unchanging(:node) do |node|
563 with_unchanging_request([:data_public => false]) do |headers|
564 osm_xml = xml_for_node node
565 osm_xml = update_changeset osm_xml, 0
567 put api_node_path(node), :params => osm_xml.to_s, :headers => headers
569 assert_require_public_data "update with changeset=0 should be forbidden, when data isn't public"
574 def test_update_with_lat_too_large_by_private_user
575 check_update_with_invalid_attr_value "lat", 91.0, :data_public => false
578 def test_update_with_lat_too_small_by_private_user
579 check_update_with_invalid_attr_value "lat", -91.0, :data_public => false
582 def test_update_with_lon_too_large_by_private_user
583 check_update_with_invalid_attr_value "lon", 181.0, :data_public => false
586 def test_update_with_lon_too_small_by_private_user
587 check_update_with_invalid_attr_value "lon", -181.0, :data_public => false
590 def test_update_by_private_user
591 with_unchanging(:node) do |node|
592 with_unchanging_request([:data_public => false]) do |headers, changeset|
593 osm_xml = xml_for_node node
594 osm_xml = update_changeset osm_xml, changeset.id
596 put api_node_path(node), :params => osm_xml.to_s, :headers => headers
598 assert_require_public_data "should have failed with a forbidden when data isn't public"
603 def test_update_in_changeset_of_other_user
604 with_unchanging(:node) do |node|
605 other_user = create(:user)
607 with_unchanging_request([], [:user => other_user]) do |headers, changeset|
608 osm_xml = xml_for_node node
609 osm_xml = update_changeset osm_xml, changeset.id
611 put api_node_path(node), :params => osm_xml.to_s, :headers => headers
613 assert_response :conflict, "update with other user's changeset should be rejected"
618 def test_update_in_closed_changeset
619 with_unchanging(:node) do |node|
620 with_unchanging_request([], [:closed]) do |headers, changeset|
621 osm_xml = xml_for_node node
622 osm_xml = update_changeset osm_xml, changeset.id
624 put api_node_path(node), :params => osm_xml.to_s, :headers => headers
626 assert_response :conflict, "update with closed changeset should be rejected"
631 def test_update_in_missing_changeset
632 with_unchanging(:node) do |node|
633 with_unchanging_request do |headers|
634 osm_xml = xml_for_node node
635 osm_xml = update_changeset osm_xml, 0
637 put api_node_path(node), :params => osm_xml.to_s, :headers => headers
639 assert_response :conflict, "update with changeset=0 should be rejected"
644 def test_update_with_lat_too_large
645 check_update_with_invalid_attr_value "lat", 91.0
648 def test_update_with_lat_too_small
649 check_update_with_invalid_attr_value "lat", -91.0
652 def test_update_with_lon_too_large
653 check_update_with_invalid_attr_value "lon", 181.0
656 def test_update_with_lon_too_small
657 check_update_with_invalid_attr_value "lon", -181.0
660 def test_update_with_version_behind
661 with_unchanging(:node, :version => 2) do |node|
662 with_unchanging_request do |headers, changeset|
663 osm_xml = xml_for_node node
664 osm_xml = xml_attr_rewrite osm_xml, "version", node.version - 1
665 osm_xml = update_changeset osm_xml, changeset.id
667 put api_node_path(node), :params => osm_xml.to_s, :headers => headers
669 assert_response :conflict, "should have failed on old version number"
674 def test_update_with_version_ahead
675 with_unchanging(:node, :version => 2) do |node|
676 with_unchanging_request do |headers, changeset|
677 osm_xml = xml_for_node node
678 osm_xml = xml_attr_rewrite osm_xml, "version", node.version + 1
679 osm_xml = update_changeset osm_xml, changeset.id
681 put api_node_path(node), :params => osm_xml.to_s, :headers => headers
683 assert_response :conflict, "should have failed on skipped version number"
688 def test_update_with_invalid_version
689 with_unchanging(:node) do |node|
690 with_unchanging_request do |headers, changeset|
691 osm_xml = xml_for_node node
692 osm_xml = xml_attr_rewrite osm_xml, "version", "p1r4t3s!"
693 osm_xml = update_changeset osm_xml, changeset.id
695 put api_node_path(node), :params => osm_xml.to_s, :headers => headers
697 assert_response :conflict, "should not be able to put 'p1r4at3s!' in the version field"
702 def test_update_other_node
703 with_unchanging(:node) do |node|
704 with_unchanging(:node) do |other_node|
705 with_unchanging_request do |headers, changeset|
706 osm_xml = xml_for_node other_node
707 osm_xml = update_changeset osm_xml, changeset.id
709 put api_node_path(node), :params => osm_xml.to_s, :headers => headers
711 assert_response :bad_request, "should not be able to update a node with a different ID from the XML"
717 def test_update_with_invalid_osm_structure
718 with_unchanging(:node) do |node|
719 with_unchanging_request do |headers|
722 put api_node_path(node), :params => osm, :headers => headers
724 assert_response :bad_request, "should not be able to update a node with non-OSM XML doc."
730 with_request do |headers, changeset|
732 osm_xml = xml_for_node node
733 osm_xml = update_changeset osm_xml, changeset.id
735 put api_node_path(node), :params => osm_xml.to_s, :headers => headers
737 assert_response :success, "a valid update request failed"
741 def test_update_with_duplicate_tags
742 with_unchanging(:node) do |node|
743 create(:node_tag, :node => node, :k => "key_to_duplicate", :v => "value_to_duplicate")
745 with_unchanging_request do |headers, changeset|
746 tag_xml = XML::Node.new("tag")
747 tag_xml["k"] = "key_to_duplicate"
748 tag_xml["v"] = "value_to_duplicate"
750 osm_xml = xml_for_node node
751 osm_xml.find("//osm/node").first << tag_xml
752 osm_xml = update_changeset osm_xml, changeset.id
754 put api_node_path(node), :params => osm_xml.to_s, :headers => headers
756 assert_response :bad_request, "adding duplicate tags to a node should fail with 'bad request'"
757 assert_equal "Element node/#{node.id} has duplicate tags with key key_to_duplicate", @response.body
763 # test initial rate limit
764 def test_initial_rate_limit
768 # create a changeset that puts us near the initial rate limit
769 changeset = create(:changeset, :user => user,
770 :created_at => Time.now.utc - 5.minutes,
771 :num_changes => Settings.initial_changes_per_hour - 1)
773 # create authentication header
774 auth_header = bearer_authorization_header user
776 # try creating a node
777 xml = "<osm><node lat='0' lon='0' changeset='#{changeset.id}'/></osm>"
778 post api_nodes_path, :params => xml, :headers => auth_header
779 assert_response :success, "node create did not return success status"
781 # get the id of the node we created
782 nodeid = @response.body
784 # try updating the node, which should be rate limited
785 xml = "<osm><node id='#{nodeid}' version='1' lat='1' lon='1' changeset='#{changeset.id}'/></osm>"
786 put api_node_path(nodeid), :params => xml, :headers => auth_header
787 assert_response :too_many_requests, "node update did not hit rate limit"
789 # try deleting the node, which should be rate limited
790 xml = "<osm><node id='#{nodeid}' version='2' lat='1' lon='1' changeset='#{changeset.id}'/></osm>"
791 delete api_node_path(nodeid), :params => xml, :headers => auth_header
792 assert_response :too_many_requests, "node delete did not hit rate limit"
794 # try creating a node, which should be rate limited
795 xml = "<osm><node lat='0' lon='0' changeset='#{changeset.id}'/></osm>"
796 post api_nodes_path, :params => xml, :headers => auth_header
797 assert_response :too_many_requests, "node create did not hit rate limit"
801 # test maximum rate limit
802 def test_maximum_rate_limit
806 # create a changeset to establish our initial edit time
807 changeset = create(:changeset, :user => user,
808 :created_at => Time.now.utc - 28.days)
810 # create changeset to put us near the maximum rate limit
811 total_changes = Settings.max_changes_per_hour - 1
812 while total_changes.positive?
813 changes = [total_changes, Changeset::MAX_ELEMENTS].min
814 changeset = create(:changeset, :user => user,
815 :created_at => Time.now.utc - 5.minutes,
816 :num_changes => changes)
817 total_changes -= changes
820 # create authentication header
821 auth_header = bearer_authorization_header user
823 # try creating a node
824 xml = "<osm><node lat='0' lon='0' changeset='#{changeset.id}'/></osm>"
825 post api_nodes_path, :params => xml, :headers => auth_header
826 assert_response :success, "node create did not return success status"
828 # get the id of the node we created
829 nodeid = @response.body
831 # try updating the node, which should be rate limited
832 xml = "<osm><node id='#{nodeid}' version='1' lat='1' lon='1' changeset='#{changeset.id}'/></osm>"
833 put api_node_path(nodeid), :params => xml, :headers => auth_header
834 assert_response :too_many_requests, "node update did not hit rate limit"
836 # try deleting the node, which should be rate limited
837 xml = "<osm><node id='#{nodeid}' version='2' lat='1' lon='1' changeset='#{changeset.id}'/></osm>"
838 delete api_node_path(nodeid), :params => xml, :headers => auth_header
839 assert_response :too_many_requests, "node delete did not hit rate limit"
841 # try creating a node, which should be rate limited
842 xml = "<osm><node lat='0' lon='0' changeset='#{changeset.id}'/></osm>"
843 post api_nodes_path, :params => xml, :headers => auth_header
844 assert_response :too_many_requests, "node create did not hit rate limit"
849 def check_update_with_invalid_attr_value(name, value, data_public: true)
850 with_unchanging(:node) do |node|
851 with_unchanging_request([:data_public => data_public]) do |headers, changeset|
852 osm_xml = xml_for_node node
853 osm_xml = xml_attr_rewrite osm_xml, name, value
854 osm_xml = update_changeset osm_xml, changeset.id
856 put api_node_path(node), :params => osm_xml.to_s, :headers => headers
859 assert_response :bad_request, "node at #{name}=#{value} should be rejected"
861 assert_require_public_data "node at #{name}=#{value} should be forbidden, when data isn't public"
873 # update an attribute in the node element
874 def xml_attr_rewrite(xml, name, value)
875 xml.find("//osm/node").first[name] = value.to_s