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
454 assert_equal 1, changeset.num_changes
455 assert_predicate changeset, :num_type_changes_in_sync?
456 assert_equal 1, changeset.num_deleted_nodes
460 def test_destroy_twice
462 node = create(:node, :changeset => create(:changeset, :user => user))
463 osm_xml = xml_for_node node
465 delete api_node_path(node), :params => osm_xml.to_s, :headers => bearer_authorization_header(user)
467 assert_response :success
469 delete api_node_path(node), :params => osm_xml.to_s, :headers => bearer_authorization_header(user)
471 assert_response :gone
474 def test_destroy_deleted_node
475 with_unchanging(:node, :deleted) do |node|
476 with_unchanging_request do |headers, changeset|
477 osm = "<osm><node id='#{node.id}' changeset='#{changeset.id}' version='1' lat='0' lon='0'/></osm>"
479 delete api_node_path(node), :params => osm, :headers => headers
481 assert_response :gone
486 def test_destroy_missing_node
487 with_unchanging_request do |headers|
488 delete api_node_path(0), :headers => headers
490 assert_response :not_found
494 def test_destroy_node_in_ways
495 with_unchanging(:node) do |node|
496 way_node = create(:way_node, :node => node)
497 way_node2 = create(:way_node, :node => node)
499 with_unchanging_request do |headers, changeset|
500 osm_xml = xml_for_node node
501 osm_xml = update_changeset osm_xml, changeset.id
503 delete api_node_path(node), :params => osm_xml.to_s, :headers => headers
505 assert_response :precondition_failed, "shouldn't be able to delete a node used in a way (#{@response.body})"
506 assert_equal "Precondition failed: Node #{node.id} is still used by ways #{way_node.way.id},#{way_node2.way.id}.", @response.body
511 def test_destroy_node_in_relations
512 with_unchanging(:node) do |node|
513 relation_member = create(:relation_member, :member => node)
514 relation_member2 = create(:relation_member, :member => node)
516 with_unchanging_request do |headers, changeset|
517 osm_xml = xml_for_node node
518 osm_xml = update_changeset osm_xml, changeset.id
520 delete api_node_path(node), :params => osm_xml.to_s, :headers => headers
522 assert_response :precondition_failed, "shouldn't be able to delete a node used in a relation (#{@response.body})"
523 assert_equal "Precondition failed: Node #{node.id} is still used by relations #{relation_member.relation.id},#{relation_member2.relation.id}.", @response.body
528 def test_update_when_unauthorized
529 with_unchanging(:node) do |node|
530 osm_xml = xml_for_node node
532 put api_node_path(node), :params => osm_xml.to_s
534 assert_response :unauthorized
538 def test_update_in_changeset_of_other_user_by_private_user
539 with_unchanging(:node) do |node|
540 other_user = create(:user)
542 with_unchanging_request([:data_public => false], [:user => other_user]) do |headers, changeset|
543 osm_xml = xml_for_node node
544 osm_xml = update_changeset osm_xml, changeset.id
546 put api_node_path(node), :params => osm_xml.to_s, :headers => headers
548 assert_require_public_data "update with other user's changeset should be forbidden when data isn't public"
553 def test_update_in_closed_changeset_by_private_user
554 with_unchanging(:node) do |node|
555 with_unchanging_request([:data_public => false], [:closed]) do |headers, changeset|
556 osm_xml = xml_for_node node
557 osm_xml = update_changeset osm_xml, changeset.id
559 put api_node_path(node), :params => osm_xml.to_s, :headers => headers
561 assert_require_public_data "update with closed changeset should be forbidden, when data isn't public"
566 def test_update_in_missing_changeset_by_private_user
567 with_unchanging(:node) do |node|
568 with_unchanging_request([:data_public => false]) do |headers|
569 osm_xml = xml_for_node node
570 osm_xml = update_changeset osm_xml, 0
572 put api_node_path(node), :params => osm_xml.to_s, :headers => headers
574 assert_require_public_data "update with changeset=0 should be forbidden, when data isn't public"
579 def test_update_with_lat_too_large_by_private_user
580 check_update_with_invalid_attr_value "lat", 91.0, :data_public => false
583 def test_update_with_lat_too_small_by_private_user
584 check_update_with_invalid_attr_value "lat", -91.0, :data_public => false
587 def test_update_with_lon_too_large_by_private_user
588 check_update_with_invalid_attr_value "lon", 181.0, :data_public => false
591 def test_update_with_lon_too_small_by_private_user
592 check_update_with_invalid_attr_value "lon", -181.0, :data_public => false
595 def test_update_by_private_user
596 with_unchanging(:node) do |node|
597 with_unchanging_request([:data_public => false]) do |headers, changeset|
598 osm_xml = xml_for_node node
599 osm_xml = update_changeset osm_xml, changeset.id
601 put api_node_path(node), :params => osm_xml.to_s, :headers => headers
603 assert_require_public_data "should have failed with a forbidden when data isn't public"
608 def test_update_in_changeset_of_other_user
609 with_unchanging(:node) do |node|
610 other_user = create(:user)
612 with_unchanging_request([], [:user => other_user]) do |headers, changeset|
613 osm_xml = xml_for_node node
614 osm_xml = update_changeset osm_xml, changeset.id
616 put api_node_path(node), :params => osm_xml.to_s, :headers => headers
618 assert_response :conflict, "update with other user's changeset should be rejected"
623 def test_update_in_closed_changeset
624 with_unchanging(:node) do |node|
625 with_unchanging_request([], [:closed]) do |headers, changeset|
626 osm_xml = xml_for_node node
627 osm_xml = update_changeset osm_xml, changeset.id
629 put api_node_path(node), :params => osm_xml.to_s, :headers => headers
631 assert_response :conflict, "update with closed changeset should be rejected"
636 def test_update_in_missing_changeset
637 with_unchanging(:node) do |node|
638 with_unchanging_request do |headers|
639 osm_xml = xml_for_node node
640 osm_xml = update_changeset osm_xml, 0
642 put api_node_path(node), :params => osm_xml.to_s, :headers => headers
644 assert_response :conflict, "update with changeset=0 should be rejected"
649 def test_update_with_lat_too_large
650 check_update_with_invalid_attr_value "lat", 91.0
653 def test_update_with_lat_too_small
654 check_update_with_invalid_attr_value "lat", -91.0
657 def test_update_with_lon_too_large
658 check_update_with_invalid_attr_value "lon", 181.0
661 def test_update_with_lon_too_small
662 check_update_with_invalid_attr_value "lon", -181.0
665 def test_update_with_version_behind
666 with_unchanging(:node, :version => 2) do |node|
667 with_unchanging_request do |headers, changeset|
668 osm_xml = xml_for_node node
669 osm_xml = xml_attr_rewrite osm_xml, "version", node.version - 1
670 osm_xml = update_changeset osm_xml, changeset.id
672 put api_node_path(node), :params => osm_xml.to_s, :headers => headers
674 assert_response :conflict, "should have failed on old version number"
679 def test_update_with_version_ahead
680 with_unchanging(:node, :version => 2) do |node|
681 with_unchanging_request do |headers, changeset|
682 osm_xml = xml_for_node node
683 osm_xml = xml_attr_rewrite osm_xml, "version", node.version + 1
684 osm_xml = update_changeset osm_xml, changeset.id
686 put api_node_path(node), :params => osm_xml.to_s, :headers => headers
688 assert_response :conflict, "should have failed on skipped version number"
693 def test_update_with_invalid_version
694 with_unchanging(:node) do |node|
695 with_unchanging_request do |headers, changeset|
696 osm_xml = xml_for_node node
697 osm_xml = xml_attr_rewrite osm_xml, "version", "p1r4t3s!"
698 osm_xml = update_changeset osm_xml, changeset.id
700 put api_node_path(node), :params => osm_xml.to_s, :headers => headers
702 assert_response :conflict, "should not be able to put 'p1r4at3s!' in the version field"
707 def test_update_other_node
708 with_unchanging(:node) do |node|
709 with_unchanging(:node) do |other_node|
710 with_unchanging_request do |headers, changeset|
711 osm_xml = xml_for_node other_node
712 osm_xml = update_changeset osm_xml, changeset.id
714 put api_node_path(node), :params => osm_xml.to_s, :headers => headers
716 assert_response :bad_request, "should not be able to update a node with a different ID from the XML"
722 def test_update_with_invalid_osm_structure
723 with_unchanging(:node) do |node|
724 with_unchanging_request do |headers|
727 put api_node_path(node), :params => osm, :headers => headers
729 assert_response :bad_request, "should not be able to update a node with non-OSM XML doc."
735 with_request do |headers, changeset|
737 osm_xml = xml_for_node node
738 osm_xml = update_changeset osm_xml, changeset.id
740 put api_node_path(node), :params => osm_xml.to_s, :headers => headers
742 assert_response :success, "a valid update request failed"
745 assert_equal 1, changeset.num_changes
746 assert_predicate changeset, :num_type_changes_in_sync?
747 assert_equal 1, changeset.num_modified_nodes
751 def test_update_with_duplicate_tags
752 with_unchanging(:node) do |node|
753 create(:node_tag, :node => node, :k => "key_to_duplicate", :v => "value_to_duplicate")
755 with_unchanging_request do |headers, changeset|
756 tag_xml = XML::Node.new("tag")
757 tag_xml["k"] = "key_to_duplicate"
758 tag_xml["v"] = "value_to_duplicate"
760 osm_xml = xml_for_node node
761 osm_xml.find("//osm/node").first << tag_xml
762 osm_xml = update_changeset osm_xml, changeset.id
764 put api_node_path(node), :params => osm_xml.to_s, :headers => headers
766 assert_response :bad_request, "adding duplicate tags to a node should fail with 'bad request'"
767 assert_equal "Element node/#{node.id} has duplicate tags with key key_to_duplicate", @response.body
773 # test initial rate limit
774 def test_initial_rate_limit
778 # create a changeset that puts us near the initial rate limit
779 changeset = create(:changeset, :user => user,
780 :created_at => Time.now.utc - 5.minutes,
781 :num_changes => Settings.initial_changes_per_hour - 1)
783 # create authentication header
784 auth_header = bearer_authorization_header user
786 # try creating a node
787 xml = "<osm><node lat='0' lon='0' changeset='#{changeset.id}'/></osm>"
788 post api_nodes_path, :params => xml, :headers => auth_header
789 assert_response :success, "node create did not return success status"
791 # get the id of the node we created
792 nodeid = @response.body
794 # try updating the node, which should be rate limited
795 xml = "<osm><node id='#{nodeid}' version='1' lat='1' lon='1' changeset='#{changeset.id}'/></osm>"
796 put api_node_path(nodeid), :params => xml, :headers => auth_header
797 assert_response :too_many_requests, "node update did not hit rate limit"
799 # try deleting the node, which should be rate limited
800 xml = "<osm><node id='#{nodeid}' version='2' lat='1' lon='1' changeset='#{changeset.id}'/></osm>"
801 delete api_node_path(nodeid), :params => xml, :headers => auth_header
802 assert_response :too_many_requests, "node delete did not hit rate limit"
804 # try creating a node, which should be rate limited
805 xml = "<osm><node lat='0' lon='0' changeset='#{changeset.id}'/></osm>"
806 post api_nodes_path, :params => xml, :headers => auth_header
807 assert_response :too_many_requests, "node create did not hit rate limit"
811 # test maximum rate limit
812 def test_maximum_rate_limit
816 # create a changeset to establish our initial edit time
817 changeset = create(:changeset, :user => user,
818 :created_at => Time.now.utc - 28.days)
820 # create changeset to put us near the maximum rate limit
821 total_changes = Settings.max_changes_per_hour - 1
822 while total_changes.positive?
823 changes = [total_changes, Changeset::MAX_ELEMENTS].min
824 changeset = create(:changeset, :user => user,
825 :created_at => Time.now.utc - 5.minutes,
826 :num_changes => changes)
827 total_changes -= changes
830 # create authentication header
831 auth_header = bearer_authorization_header user
833 # try creating a node
834 xml = "<osm><node lat='0' lon='0' changeset='#{changeset.id}'/></osm>"
835 post api_nodes_path, :params => xml, :headers => auth_header
836 assert_response :success, "node create did not return success status"
838 # get the id of the node we created
839 nodeid = @response.body
841 # try updating the node, which should be rate limited
842 xml = "<osm><node id='#{nodeid}' version='1' lat='1' lon='1' changeset='#{changeset.id}'/></osm>"
843 put api_node_path(nodeid), :params => xml, :headers => auth_header
844 assert_response :too_many_requests, "node update did not hit rate limit"
846 # try deleting the node, which should be rate limited
847 xml = "<osm><node id='#{nodeid}' version='2' lat='1' lon='1' changeset='#{changeset.id}'/></osm>"
848 delete api_node_path(nodeid), :params => xml, :headers => auth_header
849 assert_response :too_many_requests, "node delete did not hit rate limit"
851 # try creating a node, which should be rate limited
852 xml = "<osm><node lat='0' lon='0' changeset='#{changeset.id}'/></osm>"
853 post api_nodes_path, :params => xml, :headers => auth_header
854 assert_response :too_many_requests, "node create did not hit rate limit"
859 def check_update_with_invalid_attr_value(name, value, data_public: true)
860 with_unchanging(:node) do |node|
861 with_unchanging_request([:data_public => data_public]) do |headers, changeset|
862 osm_xml = xml_for_node node
863 osm_xml = xml_attr_rewrite osm_xml, name, value
864 osm_xml = update_changeset osm_xml, changeset.id
866 put api_node_path(node), :params => osm_xml.to_s, :headers => headers
869 assert_response :bad_request, "node at #{name}=#{value} should be rejected"
871 assert_require_public_data "node at #{name}=#{value} should be forbidden, when data isn't public"
883 # update an attribute in the node element
884 def xml_attr_rewrite(xml, name, value)
885 xml.find("//osm/node").first[name] = value.to_s