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"
135 def test_create_with_invalid_osm_structure
136 with_unchanging_request do |headers|
139 post api_nodes_path, :params => osm, :headers => headers
141 assert_response :bad_request, "node upload did not return bad_request status"
142 assert_equal "Cannot parse valid node from xml string <create/>. XML doesn't contain an osm/node element.", @response.body
146 def test_create_without_lat
147 with_unchanging_request do |headers, changeset|
148 osm = "<osm><node lon='3.23' changeset='#{changeset.id}'/></osm>"
150 post api_nodes_path, :params => osm, :headers => headers
152 assert_response :bad_request, "node upload did not return bad_request status"
153 assert_equal "Cannot parse valid node from xml string <node lon=\"3.23\" changeset=\"#{changeset.id}\"/>. lat missing", @response.body
157 def test_create_without_lon
158 with_unchanging_request do |headers, changeset|
159 osm = "<osm><node lat='3.434' changeset='#{changeset.id}'/></osm>"
161 post api_nodes_path, :params => osm, :headers => headers
163 assert_response :bad_request, "node upload did not return bad_request status"
164 assert_equal "Cannot parse valid node from xml string <node lat=\"3.434\" changeset=\"#{changeset.id}\"/>. lon missing", @response.body
168 def test_create_with_non_numeric_lat
169 with_unchanging_request do |headers, changeset|
170 osm = "<osm><node lat='abc' lon='3.23' changeset='#{changeset.id}'/></osm>"
172 post api_nodes_path, :params => osm, :headers => headers
174 assert_response :bad_request, "node upload did not return bad_request status"
175 assert_equal "Cannot parse valid node from xml string <node lat=\"abc\" lon=\"3.23\" changeset=\"#{changeset.id}\"/>. lat not a number", @response.body
179 def test_create_with_non_numeric_lon
180 with_unchanging_request do |headers, changeset|
181 osm = "<osm><node lat='3.434' lon='abc' changeset='#{changeset.id}'/></osm>"
183 post api_nodes_path, :params => osm, :headers => headers
185 assert_response :bad_request, "node upload did not return bad_request status"
186 assert_equal "Cannot parse valid node from xml string <node lat=\"3.434\" lon=\"abc\" changeset=\"#{changeset.id}\"/>. lon not a number", @response.body
190 def test_create_with_tag_too_long
191 with_unchanging_request do |headers, changeset|
192 osm = "<osm><node lat='3.434' lon='3.23' changeset='#{changeset.id}'><tag k='foo' v='#{'x' * 256}'/></node></osm>"
194 post api_nodes_path, :params => osm, :headers => headers
196 assert_response :bad_request, "node upload did not return bad_request status"
197 assert_match(/ v: is too long \(maximum is 255 characters\) /, @response.body)
202 # try and put something into a string that the API might
203 # use unquoted and therefore allow code injection
204 def test_create_with_string_injection_by_private_user
205 with_unchanging_request([:data_public => false]) do |headers, changeset|
208 <node lat='0' lon='0' changeset='#{changeset.id}'>
209 <tag k='\#{@user.inspect}' v='0'/>
214 post api_nodes_path, :params => osm, :headers => headers
216 assert_require_public_data "Shouldn't be able to create with non-public user"
221 # try and put something into a string that the API might
222 # use unquoted and therefore allow code injection
223 def test_create_with_string_injection
224 with_request do |headers, changeset|
225 assert_difference "Node.count", 1 do
228 <node lat='0' lon='0' changeset='#{changeset.id}'>
229 <tag k='\#{@user.inspect}' v='0'/>
234 post api_nodes_path, :params => osm, :headers => headers
236 assert_response :success
239 created_node_id = @response.body
240 db_node = Node.find(created_node_id)
242 get api_node_path(created_node_id)
244 assert_response :success
246 api_node = Node.from_xml(@response.body)
247 assert_not_nil api_node, "downloaded node is nil, but shouldn't be"
248 assert_equal db_node.tags, api_node.tags, "tags are corrupted"
249 assert_includes api_node.tags, "\#{@user.inspect}"
253 def test_show_not_found
255 assert_response :not_found
258 def test_show_deleted
259 get api_node_path(create(:node, :deleted))
260 assert_response :gone
264 node = create(:node, :timestamp => "2021-02-03T00:00:00Z")
266 get api_node_path(node)
268 assert_response :success
269 assert_not_nil @response.header["Last-Modified"]
270 assert_equal "2021-02-03T00:00:00Z", Time.parse(@response.header["Last-Modified"]).utc.xmlschema
273 def test_show_lat_lon_decimal_format
274 node = create(:node, :latitude => (0.00004 * OldNode::SCALE).to_i, :longitude => (0.00008 * OldNode::SCALE).to_i)
276 get api_node_path(node)
278 assert_match(/lat="0.0000400"/, response.body)
279 assert_match(/lon="0.0000800"/, response.body)
282 def test_destroy_when_unauthorized
283 with_unchanging(:node) do |node|
284 delete api_node_path(node)
286 assert_response :unauthorized
290 def test_destroy_in_closed_changeset_by_private_user
291 with_unchanging(:node) do |node|
292 with_unchanging_request([:data_public => false], [:closed]) do |headers, changeset|
293 osm_xml = xml_for_node node
294 osm_xml = update_changeset osm_xml, changeset.id
296 delete api_node_path(node), :params => osm_xml.to_s, :headers => headers
298 assert_require_public_data "non-public user shouldn't be able to delete node"
303 def test_destroy_in_missing_changeset_by_private_user
304 with_unchanging(:node) do |node|
305 with_unchanging_request([:data_public => false]) do |headers|
306 osm_xml = xml_for_node node
307 osm_xml = update_changeset osm_xml, 0
309 delete api_node_path(node), :params => osm_xml.to_s, :headers => headers
311 assert_require_public_data "shouldn't be able to delete node, when user's data is private"
316 def test_destroy_by_private_user
317 with_unchanging(:node) do |node|
318 with_unchanging_request([:data_public => false]) do |headers, changeset|
319 osm_xml = xml_for_node node
320 osm_xml = update_changeset osm_xml, changeset.id
322 delete api_node_path(node), :params => osm_xml.to_s, :headers => headers
324 assert_require_public_data "shouldn't be able to delete node when user's data isn't public'"
329 def test_destroy_deleted_node_by_private_user
330 with_unchanging(:node, :deleted) do |node|
331 with_unchanging_request([:data_public => false]) do |headers, changeset|
332 osm_xml = "<osm><node id='#{node.id}' changeset='#{changeset.id}' version='1' lat='0' lon='0'/></osm>"
334 delete api_node_path(node), :params => osm_xml.to_s, :headers => headers
336 assert_require_public_data
341 def test_destroy_missing_node_by_private_user
342 with_unchanging_request([:data_public => false]) do |headers|
343 delete api_node_path(0), :headers => headers
345 assert_require_public_data
349 def test_destroy_node_in_way_by_private_user
350 with_unchanging(:node) do |node|
351 create(:way_node, :node => node)
353 with_unchanging_request([:data_public => false]) do |headers, changeset|
354 osm_xml = xml_for_node node
355 osm_xml = update_changeset osm_xml, changeset.id
357 delete api_node_path(node), :params => osm_xml.to_s, :headers => headers
359 assert_require_public_data "shouldn't be able to delete a node used in a way (#{@response.body})"
364 def test_destroy_node_in_relation_by_private_user
365 with_unchanging(:node) do |node|
366 create(:relation_member, :member => node)
368 with_unchanging_request([:data_public => false]) do |headers, changeset|
369 osm_xml = xml_for_node node
370 osm_xml = update_changeset osm_xml, changeset.id
372 delete api_node_path(node), :params => osm_xml.to_s, :headers => headers
374 assert_require_public_data "shouldn't be able to delete a node used in a relation (#{@response.body})"
379 def test_destroy_in_closed_changeset
380 with_unchanging(:node) do |node|
381 with_unchanging_request([], [:closed]) do |headers, changeset|
382 osm_xml = xml_for_node node
383 osm_xml = update_changeset osm_xml, changeset.id
385 delete api_node_path(node), :params => osm_xml.to_s, :headers => headers
387 assert_response :conflict
392 def test_destroy_in_missing_changeset
393 with_unchanging(:node) do |node|
394 with_unchanging_request do |headers|
395 osm_xml = xml_for_node node
396 osm_xml = update_changeset osm_xml, 0
398 delete api_node_path(node), :params => osm_xml.to_s, :headers => headers
400 assert_response :conflict
405 def test_destroy_different_node
406 with_unchanging(:node) do |node|
407 with_unchanging(:node) do |other_node|
408 with_unchanging_request do |headers, changeset|
409 osm_xml = xml_for_node other_node
410 osm_xml = update_changeset osm_xml, changeset.id
412 delete api_node_path(node), :params => osm_xml.to_s, :headers => headers
414 assert_response :bad_request, "should not be able to delete a node with a different ID from the XML"
420 def test_destroy_invalid_osm_structure
421 with_unchanging(:node) do |node|
422 with_unchanging_request do |headers|
425 delete api_node_path(node), :params => osm, :headers => headers
427 assert_response :bad_request, "should not be able to delete a node without a valid XML payload"
433 with_request do |headers, changeset|
435 osm_xml = xml_for_node node
436 osm_xml = update_changeset osm_xml, changeset.id
438 delete api_node_path(node), :params => osm_xml.to_s, :headers => headers
440 assert_response :success
442 response_node_version = @response.body.to_i
443 assert_operator response_node_version, :>, node.version, "delete request should return a new version number for node"
445 assert_not_predicate node, :visible?
446 assert_equal response_node_version, node.version
450 def test_destroy_twice
452 node = create(:node, :changeset => create(:changeset, :user => user))
453 osm_xml = xml_for_node node
455 delete api_node_path(node), :params => osm_xml.to_s, :headers => bearer_authorization_header(user)
457 assert_response :success
459 delete api_node_path(node), :params => osm_xml.to_s, :headers => bearer_authorization_header(user)
461 assert_response :gone
464 def test_destroy_deleted_node
465 with_unchanging(:node, :deleted) do |node|
466 with_unchanging_request do |headers, changeset|
467 osm = "<osm><node id='#{node.id}' changeset='#{changeset.id}' version='1' lat='0' lon='0'/></osm>"
469 delete api_node_path(node), :params => osm, :headers => headers
471 assert_response :gone
476 def test_destroy_missing_node
477 with_unchanging_request do |headers|
478 delete api_node_path(0), :headers => headers
480 assert_response :not_found
484 def test_destroy_node_in_ways
485 with_unchanging(:node) do |node|
486 way_node = create(:way_node, :node => node)
487 way_node2 = create(:way_node, :node => node)
489 with_unchanging_request do |headers, changeset|
490 osm_xml = xml_for_node node
491 osm_xml = update_changeset osm_xml, changeset.id
493 delete api_node_path(node), :params => osm_xml.to_s, :headers => headers
495 assert_response :precondition_failed, "shouldn't be able to delete a node used in a way (#{@response.body})"
496 assert_equal "Precondition failed: Node #{node.id} is still used by ways #{way_node.way.id},#{way_node2.way.id}.", @response.body
501 def test_destroy_node_in_relations
502 with_unchanging(:node) do |node|
503 relation_member = create(:relation_member, :member => node)
504 relation_member2 = create(:relation_member, :member => node)
506 with_unchanging_request do |headers, changeset|
507 osm_xml = xml_for_node node
508 osm_xml = update_changeset osm_xml, changeset.id
510 delete api_node_path(node), :params => osm_xml.to_s, :headers => headers
512 assert_response :precondition_failed, "shouldn't be able to delete a node used in a relation (#{@response.body})"
513 assert_equal "Precondition failed: Node #{node.id} is still used by relations #{relation_member.relation.id},#{relation_member2.relation.id}.", @response.body
518 def test_update_when_unauthorized
519 with_unchanging(:node) do |node|
520 osm_xml = xml_for_node node
522 put api_node_path(node), :params => osm_xml.to_s
524 assert_response :unauthorized
528 def test_update_in_changeset_of_other_user_by_private_user
529 with_unchanging(:node) do |node|
530 other_user = create(:user)
532 with_unchanging_request([:data_public => false], [:user => other_user]) do |headers, changeset|
533 osm_xml = xml_for_node node
534 osm_xml = update_changeset osm_xml, changeset.id
536 put api_node_path(node), :params => osm_xml.to_s, :headers => headers
538 assert_require_public_data "update with other user's changeset should be forbidden when data isn't public"
543 def test_update_in_closed_changeset_by_private_user
544 with_unchanging(:node) do |node|
545 with_unchanging_request([:data_public => false], [:closed]) do |headers, changeset|
546 osm_xml = xml_for_node node
547 osm_xml = update_changeset osm_xml, changeset.id
549 put api_node_path(node), :params => osm_xml.to_s, :headers => headers
551 assert_require_public_data "update with closed changeset should be forbidden, when data isn't public"
556 def test_update_in_missing_changeset_by_private_user
557 with_unchanging(:node) do |node|
558 with_unchanging_request([:data_public => false]) do |headers|
559 osm_xml = xml_for_node node
560 osm_xml = update_changeset osm_xml, 0
562 put api_node_path(node), :params => osm_xml.to_s, :headers => headers
564 assert_require_public_data "update with changeset=0 should be forbidden, when data isn't public"
569 def test_update_with_lat_too_large_by_private_user
570 check_update_with_invalid_attr_value "lat", 91.0, :data_public => false
573 def test_update_with_lat_too_small_by_private_user
574 check_update_with_invalid_attr_value "lat", -91.0, :data_public => false
577 def test_update_with_lon_too_large_by_private_user
578 check_update_with_invalid_attr_value "lon", 181.0, :data_public => false
581 def test_update_with_lon_too_small_by_private_user
582 check_update_with_invalid_attr_value "lon", -181.0, :data_public => false
585 def test_update_by_private_user
586 with_unchanging(:node) do |node|
587 with_unchanging_request([:data_public => false]) do |headers, changeset|
588 osm_xml = xml_for_node node
589 osm_xml = update_changeset osm_xml, changeset.id
591 put api_node_path(node), :params => osm_xml.to_s, :headers => headers
593 assert_require_public_data "should have failed with a forbidden when data isn't public"
598 def test_update_in_changeset_of_other_user
599 with_unchanging(:node) do |node|
600 other_user = create(:user)
602 with_unchanging_request([], [:user => other_user]) do |headers, changeset|
603 osm_xml = xml_for_node node
604 osm_xml = update_changeset osm_xml, changeset.id
606 put api_node_path(node), :params => osm_xml.to_s, :headers => headers
608 assert_response :conflict, "update with other user's changeset should be rejected"
613 def test_update_in_closed_changeset
614 with_unchanging(:node) do |node|
615 with_unchanging_request([], [:closed]) do |headers, changeset|
616 osm_xml = xml_for_node node
617 osm_xml = update_changeset osm_xml, changeset.id
619 put api_node_path(node), :params => osm_xml.to_s, :headers => headers
621 assert_response :conflict, "update with closed changeset should be rejected"
626 def test_update_in_missing_changeset
627 with_unchanging(:node) do |node|
628 with_unchanging_request do |headers|
629 osm_xml = xml_for_node node
630 osm_xml = update_changeset osm_xml, 0
632 put api_node_path(node), :params => osm_xml.to_s, :headers => headers
634 assert_response :conflict, "update with changeset=0 should be rejected"
639 def test_update_with_lat_too_large
640 check_update_with_invalid_attr_value "lat", 91.0
643 def test_update_with_lat_too_small
644 check_update_with_invalid_attr_value "lat", -91.0
647 def test_update_with_lon_too_large
648 check_update_with_invalid_attr_value "lon", 181.0
651 def test_update_with_lon_too_small
652 check_update_with_invalid_attr_value "lon", -181.0
655 def test_update_with_version_behind
656 with_unchanging(:node, :version => 2) do |node|
657 with_unchanging_request do |headers, changeset|
658 osm_xml = xml_for_node node
659 osm_xml = xml_attr_rewrite osm_xml, "version", node.version - 1
660 osm_xml = update_changeset osm_xml, changeset.id
662 put api_node_path(node), :params => osm_xml.to_s, :headers => headers
664 assert_response :conflict, "should have failed on old version number"
669 def test_update_with_version_ahead
670 with_unchanging(:node, :version => 2) do |node|
671 with_unchanging_request do |headers, changeset|
672 osm_xml = xml_for_node node
673 osm_xml = xml_attr_rewrite osm_xml, "version", node.version + 1
674 osm_xml = update_changeset osm_xml, changeset.id
676 put api_node_path(node), :params => osm_xml.to_s, :headers => headers
678 assert_response :conflict, "should have failed on skipped version number"
683 def test_update_with_invalid_version
684 with_unchanging(:node) do |node|
685 with_unchanging_request do |headers, changeset|
686 osm_xml = xml_for_node node
687 osm_xml = xml_attr_rewrite osm_xml, "version", "p1r4t3s!"
688 osm_xml = update_changeset osm_xml, changeset.id
690 put api_node_path(node), :params => osm_xml.to_s, :headers => headers
692 assert_response :conflict, "should not be able to put 'p1r4at3s!' in the version field"
697 def test_update_other_node
698 with_unchanging(:node) do |node|
699 with_unchanging(:node) do |other_node|
700 with_unchanging_request do |headers, changeset|
701 osm_xml = xml_for_node other_node
702 osm_xml = update_changeset osm_xml, changeset.id
704 put api_node_path(node), :params => osm_xml.to_s, :headers => headers
706 assert_response :bad_request, "should not be able to update a node with a different ID from the XML"
712 def test_update_with_invalid_osm_structure
713 with_unchanging(:node) do |node|
714 with_unchanging_request do |headers|
717 put api_node_path(node), :params => osm, :headers => headers
719 assert_response :bad_request, "should not be able to update a node with non-OSM XML doc."
725 with_request do |headers, changeset|
727 osm_xml = xml_for_node node
728 osm_xml = update_changeset osm_xml, changeset.id
730 put api_node_path(node), :params => osm_xml.to_s, :headers => headers
732 assert_response :success, "a valid update request failed"
736 def test_update_with_duplicate_tags
737 with_unchanging(:node) do |node|
738 create(:node_tag, :node => node, :k => "key_to_duplicate", :v => "value_to_duplicate")
740 with_unchanging_request do |headers, changeset|
741 tag_xml = XML::Node.new("tag")
742 tag_xml["k"] = "key_to_duplicate"
743 tag_xml["v"] = "value_to_duplicate"
745 osm_xml = xml_for_node node
746 osm_xml.find("//osm/node").first << tag_xml
747 osm_xml = update_changeset osm_xml, changeset.id
749 put api_node_path(node), :params => osm_xml.to_s, :headers => headers
751 assert_response :bad_request, "adding duplicate tags to a node should fail with 'bad request'"
752 assert_equal "Element node/#{node.id} has duplicate tags with key key_to_duplicate", @response.body
758 # test initial rate limit
759 def test_initial_rate_limit
763 # create a changeset that puts us near the initial rate limit
764 changeset = create(:changeset, :user => user,
765 :created_at => Time.now.utc - 5.minutes,
766 :num_changes => Settings.initial_changes_per_hour - 1)
768 # create authentication header
769 auth_header = bearer_authorization_header user
771 # try creating a node
772 xml = "<osm><node lat='0' lon='0' changeset='#{changeset.id}'/></osm>"
773 post api_nodes_path, :params => xml, :headers => auth_header
774 assert_response :success, "node create did not return success status"
776 # get the id of the node we created
777 nodeid = @response.body
779 # try updating the node, which should be rate limited
780 xml = "<osm><node id='#{nodeid}' version='1' lat='1' lon='1' changeset='#{changeset.id}'/></osm>"
781 put api_node_path(nodeid), :params => xml, :headers => auth_header
782 assert_response :too_many_requests, "node update did not hit rate limit"
784 # try deleting the node, which should be rate limited
785 xml = "<osm><node id='#{nodeid}' version='2' lat='1' lon='1' changeset='#{changeset.id}'/></osm>"
786 delete api_node_path(nodeid), :params => xml, :headers => auth_header
787 assert_response :too_many_requests, "node delete did not hit rate limit"
789 # try creating a node, which should be rate limited
790 xml = "<osm><node lat='0' lon='0' changeset='#{changeset.id}'/></osm>"
791 post api_nodes_path, :params => xml, :headers => auth_header
792 assert_response :too_many_requests, "node create did not hit rate limit"
796 # test maximum rate limit
797 def test_maximum_rate_limit
801 # create a changeset to establish our initial edit time
802 changeset = create(:changeset, :user => user,
803 :created_at => Time.now.utc - 28.days)
805 # create changeset to put us near the maximum rate limit
806 total_changes = Settings.max_changes_per_hour - 1
807 while total_changes.positive?
808 changes = [total_changes, Changeset::MAX_ELEMENTS].min
809 changeset = create(:changeset, :user => user,
810 :created_at => Time.now.utc - 5.minutes,
811 :num_changes => changes)
812 total_changes -= changes
815 # create authentication header
816 auth_header = bearer_authorization_header user
818 # try creating a node
819 xml = "<osm><node lat='0' lon='0' changeset='#{changeset.id}'/></osm>"
820 post api_nodes_path, :params => xml, :headers => auth_header
821 assert_response :success, "node create did not return success status"
823 # get the id of the node we created
824 nodeid = @response.body
826 # try updating the node, which should be rate limited
827 xml = "<osm><node id='#{nodeid}' version='1' lat='1' lon='1' changeset='#{changeset.id}'/></osm>"
828 put api_node_path(nodeid), :params => xml, :headers => auth_header
829 assert_response :too_many_requests, "node update did not hit rate limit"
831 # try deleting the node, which should be rate limited
832 xml = "<osm><node id='#{nodeid}' version='2' lat='1' lon='1' changeset='#{changeset.id}'/></osm>"
833 delete api_node_path(nodeid), :params => xml, :headers => auth_header
834 assert_response :too_many_requests, "node delete did not hit rate limit"
836 # try creating a node, which should be rate limited
837 xml = "<osm><node lat='0' lon='0' changeset='#{changeset.id}'/></osm>"
838 post api_nodes_path, :params => xml, :headers => auth_header
839 assert_response :too_many_requests, "node create did not hit rate limit"
844 def check_update_with_invalid_attr_value(name, value, data_public: true)
845 with_unchanging(:node) do |node|
846 with_unchanging_request([:data_public => data_public]) do |headers, changeset|
847 osm_xml = xml_for_node node
848 osm_xml = xml_attr_rewrite osm_xml, name, value
849 osm_xml = update_changeset osm_xml, changeset.id
851 put api_node_path(node), :params => osm_xml.to_s, :headers => headers
854 assert_response :bad_request, "node at #{name}=#{value} should be rejected"
856 assert_require_public_data "node at #{name}=#{value} should be forbidden, when data isn't public"
868 # update an attribute in the node element
869 def xml_attr_rewrite(xml, name, value)
870 xml.find("//osm/node").first[name] = value.to_s