5 class UploadsControllerTest < ActionDispatch::IntegrationTest
7 # test all routes which lead to this controller
10 { :path => "/api/0.6/changeset/1/upload", :method => :post },
11 { :controller => "api/changesets/uploads", :action => "create", :changeset_id => "1" }
15 def test_upload_when_unauthorized
16 changeset = create(:changeset)
17 node = create(:node, :latitude => 0, :longitude => 0)
22 <node id='#{node.id}' lon='1' lat='2' changeset='#{changeset.id}' version='1'/>
27 post api_changeset_upload_path(changeset), :params => diff
29 assert_response :unauthorized
31 assert_no_changes_in changeset
34 assert_equal 1, node.version
35 assert_equal 0, node.latitude
36 assert_equal 0, node.longitude
39 def test_upload_by_private_user
40 user = create(:user, :data_public => false)
41 changeset = create(:changeset, :user => user)
42 node = create(:node, :latitude => 0, :longitude => 0)
47 <node id='#{node.id}' lon='1' lat='2' changeset='#{changeset.id}' version='1'/>
52 auth_header = bearer_authorization_header user
54 post api_changeset_upload_path(changeset), :params => diff, :headers => auth_header
56 assert_response :forbidden
58 assert_no_changes_in changeset
61 assert_equal 1, node.version
62 assert_equal 0, node.latitude
63 assert_equal 0, node.longitude
66 def test_upload_without_required_scope
68 changeset = create(:changeset, :user => user)
69 node = create(:node, :latitude => 0, :longitude => 0)
74 <node id='#{node.id}' lon='1' lat='2' changeset='#{changeset.id}' version='1'/>
79 auth_header = bearer_authorization_header user, :scopes => %w[read_prefs]
81 post api_changeset_upload_path(changeset), :params => diff, :headers => auth_header
83 assert_response :forbidden
85 assert_no_changes_in changeset
88 assert_equal 1, node.version
89 assert_equal 0, node.latitude
90 assert_equal 0, node.longitude
93 def test_upload_with_required_scope
95 changeset = create(:changeset, :user => user)
96 node = create(:node, :latitude => 0, :longitude => 0)
101 <node id='#{node.id}' lon='1' lat='2' changeset='#{changeset.id}' version='1'/>
106 auth_header = bearer_authorization_header user, :scopes => %w[write_api]
108 post api_changeset_upload_path(changeset), :params => diff, :headers => auth_header
110 assert_response :success
112 assert_dom "diffResult[version='#{Settings.api_version}'][generator='#{Settings.generator}']", 1 do
113 assert_dom "> node", 1 do
114 assert_dom "> @old_id", node.id.to_s
115 assert_dom "> @new_id", node.id.to_s
116 assert_dom "> @new_version", "2"
121 assert_equal 1, changeset.num_changes
122 assert_predicate changeset, :num_type_changes_in_sync?
123 assert_equal 1, changeset.num_modified_nodes
126 assert_equal 2, node.version
127 assert_equal 2 * GeoRecord::SCALE, node.latitude
128 assert_equal 1 * GeoRecord::SCALE, node.longitude
132 # try to upload with commands other than create, modify, or delete
133 def test_upload_unknown_action
134 changeset = create(:changeset)
139 <node id='1' lon='1' lat='1' changeset='#{changeset.id}' />
144 auth_header = bearer_authorization_header changeset.user
146 post api_changeset_upload_path(changeset), :params => diff, :headers => auth_header
148 assert_response :bad_request
149 assert_equal "Unknown action ping, choices are create, modify, delete", @response.body
151 assert_no_changes_in changeset
155 # test for issues in https://github.com/openstreetmap/trac-tickets/issues/1568
156 def test_upload_empty_changeset
157 changeset = create(:changeset)
159 auth_header = bearer_authorization_header changeset.user
162 "<osmChange></osmChange>",
163 "<osmChange><modify/></osmChange>",
164 "<osmChange><modify></modify></osmChange>"].each do |diff|
165 post api_changeset_upload_path(changeset), :params => diff, :headers => auth_header
167 assert_response :success
170 assert_no_changes_in changeset
174 # test that the X-Error-Format header works to request XML errors
175 def test_upload_xml_errors
176 changeset = create(:changeset)
178 create(:relation_member, :member => node)
180 # try and delete a node that is in use
181 diff = XML::Document.new
182 diff.root = XML::Node.new "osmChange"
183 delete = XML::Node.new "delete"
185 delete << xml_node_for_node(node)
187 auth_header = bearer_authorization_header changeset.user
188 error_header = error_format_header "xml"
190 post api_changeset_upload_path(changeset), :params => diff.to_s, :headers => auth_header.merge(error_header)
192 assert_response :success
194 assert_dom "osmError[version='#{Settings.api_version}'][generator='#{Settings.generator}']", 1
195 assert_dom "osmError>status", 1
196 assert_dom "osmError>message", 1
199 # -------------------------------------
200 # Test creating elements.
201 # -------------------------------------
203 def test_upload_create_node
205 changeset = create(:changeset, :user => user)
210 <node id='-1' lon='30' lat='60' changeset='#{changeset.id}'>
211 <tag k='amenity' v='bar'/>
212 <tag k='name' v='Foo'/>
218 auth_header = bearer_authorization_header user
220 assert_difference "Node.count" => 1,
221 "OldNode.count" => 1,
222 "NodeTag.count" => 2,
223 "OldNodeTag.count" => 2 do
224 post api_changeset_upload_path(changeset), :params => diff, :headers => auth_header
226 assert_response :success
230 assert_dom "diffResult[version='#{Settings.api_version}'][generator='#{Settings.generator}']", 1 do
231 assert_dom "> node", 1 do |(node_el)|
232 node = Node.find(node_el["new_id"].to_i)
233 assert_dom "> @old_id", "-1"
234 assert_dom "> @new_version", "1"
239 assert_equal 1, changeset.num_changes
240 assert_predicate changeset, :num_type_changes_in_sync?
241 assert_equal 1, changeset.num_created_nodes
243 assert_equal 1, node.version
244 assert_equal changeset, node.changeset
245 assert_predicate node, :visible?
246 assert_equal({ "name" => "Foo", "amenity" => "bar" }, node.tags)
247 assert_equal 60, node.lat
248 assert_equal 30, node.lon
251 def test_upload_create_way
252 node1 = create(:node)
253 node2 = create(:node)
255 changeset = create(:changeset, :user => user)
260 <way id='-1' changeset='#{changeset.id}'>
261 <tag k='highway' v='primary'/>
262 <tag k='name' v='Foo'/>
263 <nd ref='#{node1.id}'/>
264 <nd ref='#{node2.id}'/>
270 auth_header = bearer_authorization_header user
272 assert_difference "Way.count" => 1,
275 "OldWayTag.count" => 2,
276 "WayNode.count" => 2,
277 "OldWayNode.count" => 2 do
278 post api_changeset_upload_path(changeset), :params => diff, :headers => auth_header
280 assert_response :success
284 assert_dom "diffResult[version='#{Settings.api_version}'][generator='#{Settings.generator}']", 1 do
285 assert_dom "> way", 1 do |(way_el)|
286 way = Way.find(way_el["new_id"].to_i)
287 assert_dom "> @old_id", "-1"
288 assert_dom "> @new_version", "1"
293 assert_equal 1, changeset.num_changes
294 assert_predicate changeset, :num_type_changes_in_sync?
295 assert_equal 1, changeset.num_created_ways
297 assert_equal 1, way.version
298 assert_equal changeset, way.changeset
299 assert_predicate way, :visible?
300 assert_equal({ "name" => "Foo", "highway" => "primary" }, way.tags)
301 assert_equal [node1, node2], way.nodes
304 def test_upload_create_relation
305 node1 = create(:node)
306 way1 = create(:way_with_nodes)
307 relation1 = create(:relation)
309 changeset = create(:changeset, :user => user)
314 <relation id='-1' changeset='#{changeset.id}'>
315 <member type='node' role='n_role' ref='#{node1.id}'/>
316 <member type='way' role='w_role' ref='#{way1.id}'/>
317 <member type='relation' role='r_role' ref='#{relation1.id}'/>
318 <tag k='type' v='collection'/>
324 auth_header = bearer_authorization_header user
326 assert_difference "Relation.count" => 1,
327 "OldRelation.count" => 1,
328 "RelationTag.count" => 1,
329 "OldRelationTag.count" => 1,
330 "RelationMember.count" => 3,
331 "OldRelationMember.count" => 3 do
332 post api_changeset_upload_path(changeset), :params => diff, :headers => auth_header
334 assert_response :success
338 assert_dom "diffResult[version='#{Settings.api_version}'][generator='#{Settings.generator}']", 1 do
339 assert_dom "> relation", 1 do |(relation_el)|
340 relation = Relation.find(relation_el["new_id"].to_i)
341 assert_dom "> @old_id", "-1"
342 assert_dom "> @new_version", "1"
347 assert_equal 1, changeset.num_changes
348 assert_predicate changeset, :num_type_changes_in_sync?
349 assert_equal 1, changeset.num_created_relations
351 assert_equal 1, relation.version
352 assert_equal changeset, relation.changeset
353 assert_predicate relation, :visible?
354 assert_equal({ "type" => "collection" }, relation.tags)
355 assert_equal [["Node", node1.id, "n_role"],
356 ["Way", way1.id, "w_role"],
357 ["Relation", relation1.id, "r_role"]], relation.members
360 def test_upload_create_elements
362 changeset = create(:changeset, :user => user)
364 way = create(:way_with_nodes, :nodes_count => 2)
365 relation = create(:relation)
370 <node id='-1' lon='0' lat='0' changeset='#{changeset.id}'>
371 <tag k='foo' v='bar'/>
372 <tag k='baz' v='bat'/>
374 <way id='-1' changeset='#{changeset.id}'>
375 <nd ref='#{node.id}'/>
379 <relation id='-1' changeset='#{changeset.id}'>
380 <member type='way' role='some' ref='#{way.id}'/>
381 <member type='node' role='some' ref='#{node.id}'/>
382 <member type='relation' role='some' ref='#{relation.id}'/>
388 auth_header = bearer_authorization_header user
390 post api_changeset_upload_path(changeset), :params => diff, :headers => auth_header
392 assert_response :success
394 new_node_id, new_way_id, new_rel_id = nil
395 assert_dom "diffResult[version='#{Settings.api_version}'][generator='#{Settings.generator}']", 1 do
396 # inspect the response to find out what the new element IDs are
397 # check the old IDs are all present and negative one
398 # check the versions are present and equal one
399 assert_dom "> node", 1 do |(node_el)|
400 new_node_id = node_el["new_id"].to_i
401 assert_dom "> @old_id", "-1"
402 assert_dom "> @new_version", "1"
404 assert_dom "> way", 1 do |(way_el)|
405 new_way_id = way_el["new_id"].to_i
406 assert_dom "> @old_id", "-1"
407 assert_dom "> @new_version", "1"
409 assert_dom "> relation", 1 do |(rel_el)|
410 new_rel_id = rel_el["new_id"].to_i
411 assert_dom "> @old_id", "-1"
412 assert_dom "> @new_version", "1"
417 assert_equal 3, changeset.num_changes
418 assert_predicate changeset, :num_type_changes_in_sync?
419 assert_equal 1, changeset.num_created_nodes
420 assert_equal 1, changeset.num_created_ways
421 assert_equal 1, changeset.num_created_relations
423 assert_equal 2, Node.find(new_node_id).tags.size, "new node should have two tags"
424 assert_equal 0, Way.find(new_way_id).tags.size, "new way should have no tags"
425 assert_equal 0, Relation.find(new_rel_id).tags.size, "new relation should have no tags"
429 # upload an element with a really long tag value
430 def test_upload_create_node_with_tag_too_long
431 changeset = create(:changeset)
436 <node id='-1' lon='0' lat='0' changeset='#{changeset.id}'>
437 <tag k='foo' v='#{'x' * 256}'/>
443 auth_header = bearer_authorization_header changeset.user
445 assert_no_difference "Node.count" do
446 post api_changeset_upload_path(changeset), :params => diff, :headers => auth_header
448 assert_response :bad_request
451 assert_no_changes_in changeset
454 def test_upload_create_nodes_with_invalid_placeholder_reuse_in_one_action_block
455 changeset = create(:changeset)
460 <node id='-1' lon='0' lat='0' changeset='#{changeset.id}' version='1'/>
461 <node id='-1' lon='1' lat='1' changeset='#{changeset.id}' version='1'/>
466 auth_header = bearer_authorization_header changeset.user
468 assert_no_difference "Node.count" do
469 post api_changeset_upload_path(changeset), :params => diff, :headers => auth_header
471 assert_response :bad_request
474 assert_no_changes_in changeset
477 def test_upload_create_nodes_with_invalid_placeholder_reuse_in_two_action_blocks
478 changeset = create(:changeset)
483 <node id='-1' lon='0' lat='0' changeset='#{changeset.id}' version='1'/>
486 <node id='-1' lon='1' lat='1' changeset='#{changeset.id}' version='1'/>
491 auth_header = bearer_authorization_header changeset.user
493 assert_no_difference "Node.count" do
494 post api_changeset_upload_path(changeset), :params => diff, :headers => auth_header
496 assert_response :bad_request
499 assert_no_changes_in changeset
502 def test_upload_create_way_referring_node_placeholder_defined_later
503 changeset = create(:changeset)
508 <way id="-1" changeset="#{changeset.id}">
511 <node id="-1" lat="1" lon="2" changeset="#{changeset.id}"/>
516 auth_header = bearer_authorization_header changeset.user
518 assert_no_difference "Node.count" do
519 assert_no_difference "Way.count" do
520 post api_changeset_upload_path(changeset), :params => diff, :headers => auth_header
522 assert_response :bad_request
525 assert_equal "Placeholder node not found for reference -1 in way -1", @response.body
527 assert_no_changes_in changeset
530 def test_upload_create_way_referring_undefined_node_placeholder
531 changeset = create(:changeset)
536 <way id="-1" changeset="#{changeset.id}">
543 auth_header = bearer_authorization_header changeset.user
545 assert_no_difference "Way.count" do
546 post api_changeset_upload_path(changeset), :params => diff, :headers => auth_header
548 assert_response :bad_request
550 assert_equal "Placeholder node not found for reference -1 in way -1", @response.body
552 assert_no_changes_in changeset
555 def test_upload_create_existing_way_referring_undefined_node_placeholder
556 changeset = create(:changeset)
562 <way id="#{way.id}" changeset="#{changeset.id}" version="1">
569 auth_header = bearer_authorization_header changeset.user
571 post api_changeset_upload_path(changeset), :params => diff, :headers => auth_header
573 assert_response :bad_request
574 assert_equal "Placeholder node not found for reference -1 in way #{way.id}", @response.body
576 assert_no_changes_in changeset
579 assert_equal 1, way.version
582 def test_upload_create_relation_referring_undefined_node_placeholder
583 changeset = create(:changeset)
588 <relation id="-1" changeset="#{changeset.id}" version="1">
589 <member type="node" role="foo" ref="-1"/>
595 auth_header = bearer_authorization_header changeset.user
597 assert_no_difference "Relation.count" do
598 post api_changeset_upload_path(changeset), :params => diff, :headers => auth_header
600 assert_response :bad_request
602 assert_equal "Placeholder Node not found for reference -1 in relation -1.", @response.body
604 assert_no_changes_in changeset
607 def test_upload_create_existing_relation_referring_undefined_way_placeholder
608 changeset = create(:changeset)
609 relation = create(:relation)
614 <relation id="#{relation.id}" changeset="#{changeset.id}" version="1">
615 <member type="way" role="bar" ref="-1"/>
621 auth_header = bearer_authorization_header changeset.user
623 post api_changeset_upload_path(changeset), :params => diff, :headers => auth_header
625 assert_response :bad_request
626 assert_equal "Placeholder Way not found for reference -1 in relation #{relation.id}.", @response.body
628 assert_no_changes_in changeset
631 assert_equal 1, relation.version
634 def test_upload_create_relations_with_circular_references
635 changeset = create(:changeset)
638 <osmChange version='0.6'>
640 <relation id='-2' version='0' changeset='#{changeset.id}'>
641 <member type='relation' role='' ref='-4' />
642 <tag k='type' v='route' />
643 <tag k='name' v='AtoB' />
645 <relation id='-3' version='0' changeset='#{changeset.id}'>
646 <tag k='type' v='route' />
647 <tag k='name' v='BtoA' />
649 <relation id='-4' version='0' changeset='#{changeset.id}'>
650 <member type='relation' role='' ref='-2' />
651 <member type='relation' role='' ref='-3' />
652 <tag k='type' v='route_master' />
653 <tag k='name' v='master' />
659 auth_header = bearer_authorization_header changeset.user
661 post api_changeset_upload_path(changeset), :params => diff.to_s, :headers => auth_header
663 assert_response :bad_request
664 assert_equal "Placeholder Relation not found for reference -4 in relation -2.", @response.body
666 assert_no_changes_in changeset
669 # -------------------------------------
670 # Test modifying elements.
671 # -------------------------------------
673 def test_upload_modify_node
675 changeset = create(:changeset, :user => user)
676 node = create(:node, :latitude => 0, :longitude => 0)
677 create(:node_tag, :node => node)
682 <node id='#{node.id}' lon='1' lat='2' changeset='#{changeset.id}' version='1'/>
687 auth_header = bearer_authorization_header user
689 assert_difference "Node.count" => 0,
690 "OldNode.count" => 1,
691 "NodeTag.count" => -1,
692 "OldNodeTag.count" => 0 do
693 post api_changeset_upload_path(changeset), :params => diff, :headers => auth_header
695 assert_response :success
698 assert_dom "diffResult[version='#{Settings.api_version}'][generator='#{Settings.generator}']", 1 do
699 assert_dom "> node", 1 do
700 assert_dom "> @old_id", node.id.to_s
701 assert_dom "> @new_id", node.id.to_s
702 assert_dom "> @new_version", "2"
707 assert_equal 1, changeset.num_changes
708 assert_predicate changeset, :num_type_changes_in_sync?
709 assert_equal 1, changeset.num_modified_nodes
712 assert_equal 2, node.version
713 assert_equal 2 * GeoRecord::SCALE, node.latitude
714 assert_equal 1 * GeoRecord::SCALE, node.longitude
715 assert_equal 0, node.tags.size, "node #{node.id} should now have no tags"
718 def test_upload_modify_way
720 changeset = create(:changeset, :user => user)
722 way = create(:way_with_nodes, :nodes_count => 3)
723 create(:way_tag, :way => way)
728 <way id='#{way.id}' changeset='#{changeset.id}' version='1'>
729 <nd ref='#{node.id}'/>
735 auth_header = bearer_authorization_header user
737 assert_difference "Way.count" => 0,
739 "WayTag.count" => -1,
740 "OldWayTag.count" => 0,
741 "WayNode.count" => -2,
742 "OldWayNode.count" => 1 do
743 post api_changeset_upload_path(changeset), :params => diff, :headers => auth_header
745 assert_response :success
748 assert_dom "diffResult[version='#{Settings.api_version}'][generator='#{Settings.generator}']", 1 do
749 assert_dom "> way", 1 do
750 assert_dom "> @old_id", way.id.to_s
751 assert_dom "> @new_id", way.id.to_s
752 assert_dom "> @new_version", "2"
757 assert_equal 1, changeset.num_changes
759 assert_equal 2, way.version
760 assert_equal 0, way.tags.size, "way #{way.id} should now have no tags"
761 assert_equal [node], way.nodes
764 def test_upload_modify_relation
766 changeset = create(:changeset, :user => user)
768 way = create(:way_with_nodes)
769 relation = create(:relation)
770 other_relation = create(:relation)
771 create(:relation_tag, :relation => relation)
776 <relation id='#{relation.id}' changeset='#{changeset.id}' version='1'>
777 <member type='way' role='some' ref='#{way.id}'/>
778 <member type='node' role='some' ref='#{node.id}'/>
779 <member type='relation' role='some' ref='#{other_relation.id}'/>
785 auth_header = bearer_authorization_header user
787 assert_difference "Relation.count" => 0,
788 "OldRelation.count" => 1,
789 "RelationTag.count" => -1,
790 "OldRelationTag.count" => 0,
791 "RelationMember.count" => 3,
792 "OldRelationMember.count" => 3 do
793 post api_changeset_upload_path(changeset), :params => diff, :headers => auth_header
795 assert_response :success
798 assert_dom "diffResult[version='#{Settings.api_version}'][generator='#{Settings.generator}']", 1 do
799 assert_dom "> relation", 1 do
800 assert_dom "> @old_id", relation.id.to_s
801 assert_dom "> @new_id", relation.id.to_s
802 assert_dom "> @new_version", "2"
807 assert_equal 1, changeset.num_changes
809 assert_equal 2, relation.version
810 assert_equal 0, relation.tags.size, "relation #{relation.id} should now have no tags"
811 assert_equal [["Way", way.id, "some"], ["Node", node.id, "some"], ["Relation", other_relation.id, "some"]], relation.members
814 def test_upload_modify_elements
816 changeset = create(:changeset, :user => user)
817 node = create(:node, :latitude => 0, :longitude => 0)
819 relation = create(:relation)
820 other_relation = create(:relation)
822 # create some tags, since we test that they are removed later
823 create(:node_tag, :node => node)
824 create(:way_tag, :way => way)
825 create(:relation_tag, :relation => relation)
827 # simple diff to change a node, way and relation by removing their tags
831 <node id='#{node.id}' lon='1' lat='2' changeset='#{changeset.id}' version='1'/>
832 <way id='#{way.id}' changeset='#{changeset.id}' version='1'>
833 <nd ref='#{node.id}'/>
837 <relation id='#{relation.id}' changeset='#{changeset.id}' version='1'>
838 <member type='way' role='some' ref='#{way.id}'/>
839 <member type='node' role='some' ref='#{node.id}'/>
840 <member type='relation' role='some' ref='#{other_relation.id}'/>
846 auth_header = bearer_authorization_header user
848 post api_changeset_upload_path(changeset), :params => diff, :headers => auth_header
850 assert_response :success
852 assert_dom "diffResult[version='#{Settings.api_version}'][generator='#{Settings.generator}']", 1 do
853 assert_dom "> node", 1 do
854 assert_dom "> @old_id", node.id.to_s
855 assert_dom "> @new_id", node.id.to_s
856 assert_dom "> @new_version", "2"
858 assert_dom "> way", 1 do
859 assert_dom "> @old_id", way.id.to_s
860 assert_dom "> @new_id", way.id.to_s
861 assert_dom "> @new_version", "2"
863 assert_dom "> relation", 1 do
864 assert_dom "> @old_id", relation.id.to_s
865 assert_dom "> @new_id", relation.id.to_s
866 assert_dom "> @new_version", "2"
871 assert_equal 3, changeset.num_changes
873 assert_equal 2, node.version
874 assert_equal 2 * GeoRecord::SCALE, node.latitude
875 assert_equal 1 * GeoRecord::SCALE, node.longitude
876 assert_equal 0, node.tags.size, "node #{node.id} should now have no tags"
878 assert_equal 2, way.version
879 assert_equal 0, way.tags.size, "way #{way.id} should now have no tags"
880 assert_equal [node], way.nodes
882 assert_equal 2, relation.version
883 assert_equal 0, relation.tags.size, "relation #{relation.id} should now have no tags"
884 assert_equal [["Way", way.id, "some"], ["Node", node.id, "some"], ["Relation", other_relation.id, "some"]], relation.members
888 # upload multiple versions of the same element in the same diff.
889 def test_upload_modify_multiple_node_versions
891 changeset = create(:changeset)
893 # change the location of a node multiple times, each time referencing
894 # the last version. doesn't this depend on version numbers being
899 <node id='#{node.id}' lon='0.0' lat='0.0' changeset='#{changeset.id}' version='1'/>
900 <node id='#{node.id}' lon='0.1' lat='0.0' changeset='#{changeset.id}' version='2'/>
901 <node id='#{node.id}' lon='0.1' lat='0.1' changeset='#{changeset.id}' version='3'/>
902 <node id='#{node.id}' lon='0.1' lat='0.2' changeset='#{changeset.id}' version='4'/>
903 <node id='#{node.id}' lon='0.2' lat='0.2' changeset='#{changeset.id}' version='5'/>
904 <node id='#{node.id}' lon='0.3' lat='0.2' changeset='#{changeset.id}' version='6'/>
905 <node id='#{node.id}' lon='0.3' lat='0.3' changeset='#{changeset.id}' version='7'/>
906 <node id='#{node.id}' lon='0.9' lat='0.9' changeset='#{changeset.id}' version='8'/>
911 auth_header = bearer_authorization_header changeset.user
913 post api_changeset_upload_path(changeset), :params => diff, :headers => auth_header
915 assert_response :success
917 assert_dom "diffResult>node", 8
920 assert_equal 8, changeset.num_changes
921 assert_predicate changeset, :num_type_changes_in_sync?
922 assert_equal 8, changeset.num_modified_nodes
925 assert_equal 9, node.version
926 assert_equal 0.9 * GeoRecord::SCALE, node.latitude
927 assert_equal 0.9 * GeoRecord::SCALE, node.longitude
931 # upload multiple versions of the same element in the same diff, but
932 # keep the version numbers the same.
933 def test_upload_modify_duplicate_node_versions
934 node = create(:node, :latitude => 0, :longitude => 0)
935 changeset = create(:changeset)
940 <node id='#{node.id}' lon='1' lat='1' changeset='#{changeset.id}' version='1'/>
941 <node id='#{node.id}' lon='2' lat='2' changeset='#{changeset.id}' version='1'/>
946 auth_header = bearer_authorization_header changeset.user
948 post api_changeset_upload_path(changeset), :params => diff, :headers => auth_header
950 assert_response :conflict
952 assert_no_changes_in changeset
955 assert_equal 1, node.version
956 assert_equal 0, node.latitude
957 assert_equal 0, node.longitude
961 # try to upload some elements without specifying the version
962 def test_upload_modify_missing_node_version
963 node = create(:node, :latitude => 0, :longitude => 0)
964 changeset = create(:changeset)
969 <node id='#{node.id}' lon='1' lat='1' changeset='#{changeset.id}'/>
974 auth_header = bearer_authorization_header changeset.user
976 post api_changeset_upload_path(changeset), :params => diff, :headers => auth_header
978 assert_response :bad_request
980 assert_no_changes_in changeset
983 assert_equal 1, node.version
984 assert_equal 0, node.latitude
985 assert_equal 0, node.longitude
989 # create a diff which references several changesets, which should cause
990 # a rollback and none of the diff gets committed
991 def test_upload_modify_with_references_to_different_changesets
992 changeset1 = create(:changeset)
993 changeset2 = create(:changeset, :user => changeset1.user)
994 node1 = create(:node)
995 node2 = create(:node)
997 # simple diff to create a node way and relation using placeholders
1001 <node id='#{node1.id}' lon='0' lat='0' changeset='#{changeset1.id}' version='1'/>
1004 <node id='#{node2.id}' lon='0' lat='0' changeset='#{changeset2.id}' version='1'/>
1009 auth_header = bearer_authorization_header changeset1.user
1011 post api_changeset_upload_path(changeset1), :params => diff, :headers => auth_header
1013 assert_response :conflict
1015 assert_no_changes_in changeset1
1016 assert_no_changes_in changeset2
1018 assert_nodes_are_equal(node1, Node.find(node1.id))
1019 assert_nodes_are_equal(node2, Node.find(node2.id))
1023 # upload a valid changeset which has a mixture of whitespace
1024 # to check a bug https://github.com/openstreetmap/trac-tickets/issues/1565
1025 def test_upload_modify_with_mixed_whitespace
1026 changeset = create(:changeset)
1027 node = create(:node)
1028 way = create(:way_with_nodes, :nodes_count => 2)
1029 relation = create(:relation)
1030 other_relation = create(:relation)
1031 create(:relation_tag, :relation => relation)
1035 <modify><node id='#{node.id}' lon='0' lat='0' changeset='#{changeset.id}'
1037 <node id='#{node.id}' lon='1' lat='1' changeset='#{changeset.id}' version='2'><tag k='k' v='v'/></node></modify>
1039 <relation id='#{relation.id}' changeset='#{changeset.id}' version='1'><member
1040 type='way' role='some' ref='#{way.id}'/><member
1041 type='node' role='some' ref='#{node.id}'/>
1042 <member type='relation' role='some' ref='#{other_relation.id}'/>
1044 </modify></osmChange>
1047 auth_header = bearer_authorization_header changeset.user
1049 post api_changeset_upload_path(changeset), :params => diff, :headers => auth_header
1051 assert_response :success
1053 assert_dom "diffResult>node", 2
1054 assert_dom "diffResult>relation", 1
1056 assert_equal 1, Node.find(node.id).tags.size, "node #{node.id} should now have one tag"
1057 assert_equal 0, Relation.find(relation.id).tags.size, "relation #{relation.id} should now have no tags"
1060 def test_upload_modify_unknown_node_placeholder
1061 check_upload_results_in_not_found do |changeset|
1062 "<modify><node id='-1' lon='0' lat='0' changeset='#{changeset.id}' version='1'/></modify>"
1066 def test_upload_modify_unknown_way_placeholder
1067 check_upload_results_in_not_found do |changeset|
1068 "<modify><way id='-1' changeset='#{changeset.id}' version='1'/></modify>"
1072 def test_upload_modify_unknown_relation_placeholder
1073 check_upload_results_in_not_found do |changeset|
1074 "<modify><relation id='-1' changeset='#{changeset.id}' version='1'/></modify>"
1078 # -------------------------------------
1079 # Test deleting elements.
1080 # -------------------------------------
1082 def test_upload_delete_node
1083 changeset = create(:changeset)
1084 node = create(:node, :lat => 0, :lon => 0)
1085 create(:node_tag, :node => node)
1090 <node id='#{node.id}' changeset='#{changeset.id}' version='1' lat='0' lon='0'/>
1095 auth_header = bearer_authorization_header changeset.user
1097 assert_difference "Node.count" => 0,
1098 "OldNode.count" => 1,
1099 "NodeTag.count" => -1,
1100 "OldNodeTag.count" => 0 do
1101 post api_changeset_upload_path(changeset), :params => diff, :headers => auth_header
1103 assert_response :success
1106 assert_dom "diffResult", 1 do
1107 assert_dom "> node", 1 do
1108 assert_dom "> @old_id", node.id.to_s
1113 assert_not_predicate node, :visible?
1116 def test_upload_delete_way
1117 changeset = create(:changeset)
1118 way = create(:way_with_nodes, :nodes_count => 3)
1119 create(:way_tag, :way => way)
1124 <way id='#{way.id}' changeset='#{changeset.id}' version='1'/>
1129 auth_header = bearer_authorization_header changeset.user
1131 assert_difference "Way.count" => 0,
1132 "OldWay.count" => 1,
1133 "WayTag.count" => -1,
1134 "OldWayTag.count" => 0,
1135 "WayNode.count" => -3,
1136 "OldWayNode.count" => 0 do
1137 post api_changeset_upload_path(changeset), :params => diff, :headers => auth_header
1139 assert_response :success
1142 assert_dom "diffResult", 1 do
1143 assert_dom "> way", 1 do
1144 assert_dom "> @old_id", way.id.to_s
1149 assert_not_predicate way, :visible?
1152 def test_upload_delete_relation
1153 changeset = create(:changeset)
1154 relation = create(:relation)
1155 create(:relation_member, :relation => relation, :member => create(:node))
1156 create(:relation_tag, :relation => relation)
1161 <relation id='#{relation.id}' changeset='#{changeset.id}' version='1'/>
1166 auth_header = bearer_authorization_header changeset.user
1168 assert_difference "Relation.count" => 0,
1169 "OldRelation.count" => 1,
1170 "RelationTag.count" => -1,
1171 "OldRelationTag.count" => 0,
1172 "RelationMember.count" => -1,
1173 "OldRelationMember.count" => 0 do
1174 post api_changeset_upload_path(changeset), :params => diff, :headers => auth_header
1176 assert_response :success
1179 assert_dom "diffResult", 1 do
1180 assert_dom "> relation", 1 do
1181 assert_dom "> @old_id", relation.id.to_s
1186 assert_not_predicate relation, :visible?
1190 # test a complex delete where we delete elements which rely on each other
1191 # in the same transaction.
1192 def test_upload_delete_elements
1193 changeset = create(:changeset)
1194 super_relation = create(:relation)
1195 used_relation = create(:relation)
1196 used_way = create(:way)
1197 used_node = create(:node)
1198 create(:relation_member, :relation => super_relation, :member => used_relation)
1199 create(:relation_member, :relation => super_relation, :member => used_way)
1200 create(:relation_member, :relation => super_relation, :member => used_node)
1202 diff = XML::Document.new
1203 diff.root = XML::Node.new "osmChange"
1204 delete = XML::Node.new "delete"
1206 delete << xml_node_for_relation(super_relation)
1207 delete << xml_node_for_relation(used_relation)
1208 delete << xml_node_for_way(used_way)
1209 delete << xml_node_for_node(used_node)
1210 %w[node way relation].each do |type|
1211 delete.find("//osmChange/delete/#{type}").each do |n|
1212 n["changeset"] = changeset.id.to_s
1216 auth_header = bearer_authorization_header changeset.user
1218 post api_changeset_upload_path(changeset), :params => diff.to_s, :headers => auth_header
1220 assert_response :success
1222 assert_dom "diffResult", 1 do
1223 assert_dom "> node", 1
1224 assert_dom "> way", 1
1225 assert_dom "> relation", 2
1228 assert_not Node.find(used_node.id).visible
1229 assert_not Way.find(used_way.id).visible
1230 assert_not Relation.find(super_relation.id).visible
1231 assert_not Relation.find(used_relation.id).visible
1235 # test uploading a delete with no lat/lon, as they are optional in the osmChange spec.
1236 def test_upload_delete_node_without_latlon
1237 node = create(:node)
1238 changeset = create(:changeset)
1240 diff = "<osmChange><delete><node id='#{node.id}' version='#{node.version}' changeset='#{changeset.id}'/></delete></osmChange>"
1242 auth_header = bearer_authorization_header changeset.user
1244 post api_changeset_upload_path(changeset), :params => diff, :headers => auth_header
1246 assert_response :success
1248 assert_dom "diffResult", 1 do
1249 assert_dom "> node", 1 do
1250 assert_dom "> @old_id", node.id.to_s
1251 assert_dom "> @new_id", 0
1252 assert_dom "> @new_version", 0
1257 assert_not node.visible
1261 # test that deleting stuff in a transaction doesn't bypass the checks
1262 # to ensure that used elements are not deleted.
1263 def test_upload_delete_referenced_elements
1264 changeset = create(:changeset)
1265 relation = create(:relation)
1266 other_relation = create(:relation)
1267 used_way = create(:way)
1268 used_node = create(:node)
1269 create(:relation_member, :relation => relation, :member => used_way)
1270 create(:relation_member, :relation => relation, :member => used_node)
1272 diff = XML::Document.new
1273 diff.root = XML::Node.new "osmChange"
1274 delete = XML::Node.new "delete"
1276 delete << xml_node_for_relation(other_relation)
1277 delete << xml_node_for_way(used_way)
1278 delete << xml_node_for_node(used_node)
1279 %w[node way relation].each do |type|
1280 delete.find("//osmChange/delete/#{type}").each do |n|
1281 n["changeset"] = changeset.id.to_s
1285 auth_header = bearer_authorization_header changeset.user
1287 post api_changeset_upload_path(changeset), :params => diff.to_s, :headers => auth_header
1289 assert_response :precondition_failed
1290 assert_equal "Precondition failed: Way #{used_way.id} is still used by relations #{relation.id}.", @response.body
1292 assert_no_changes_in changeset
1294 assert Node.find(used_node.id).visible
1295 assert Way.find(used_way.id).visible
1296 assert Relation.find(relation.id).visible
1297 assert Relation.find(other_relation.id).visible
1301 # test that a conditional delete of an in use object works.
1302 def test_upload_delete_if_unused
1303 changeset = create(:changeset)
1304 super_relation = create(:relation)
1305 used_relation = create(:relation)
1306 used_way = create(:way)
1307 used_node = create(:node)
1308 create(:relation_member, :relation => super_relation, :member => used_relation)
1309 create(:relation_member, :relation => super_relation, :member => used_way)
1310 create(:relation_member, :relation => super_relation, :member => used_node)
1312 diff = XML::Document.new
1313 diff.root = XML::Node.new "osmChange"
1314 delete = XML::Node.new "delete"
1316 delete["if-unused"] = ""
1317 delete << xml_node_for_relation(used_relation)
1318 delete << xml_node_for_way(used_way)
1319 delete << xml_node_for_node(used_node)
1320 %w[node way relation].each do |type|
1321 delete.find("//osmChange/delete/#{type}").each do |n|
1322 n["changeset"] = changeset.id.to_s
1326 auth_header = bearer_authorization_header changeset.user
1328 post api_changeset_upload_path(changeset), :params => diff.to_s, :headers => auth_header
1330 assert_response :success
1332 assert_dom "diffResult[version='#{Settings.api_version}'][generator='#{Settings.generator}']", 1 do
1333 assert_dom "> node", 1 do
1334 assert_dom "> @old_id", used_node.id.to_s
1335 assert_dom "> @new_id", used_node.id.to_s
1336 assert_dom "> @new_version", used_node.version.to_s
1338 assert_dom "> way", 1 do
1339 assert_dom "> @old_id", used_way.id.to_s
1340 assert_dom "> @new_id", used_way.id.to_s
1341 assert_dom "> @new_version", used_way.version.to_s
1343 assert_dom "> relation", 1 do
1344 assert_dom "> @old_id", used_relation.id.to_s
1345 assert_dom "> @new_id", used_relation.id.to_s
1346 assert_dom "> @new_version", used_relation.version.to_s
1350 assert_no_changes_in changeset
1352 assert Node.find(used_node.id).visible
1353 assert Way.find(used_way.id).visible
1354 assert Relation.find(used_relation.id).visible
1357 def test_upload_delete_with_multiple_blocks_and_if_unused
1358 changeset = create(:changeset)
1359 node = create(:node)
1361 create(:way_node, :way => way, :node => node)
1362 alone_node = create(:node)
1365 <osmChange version='0.6'>
1366 <delete version="0.6">
1367 <node id="#{node.id}" version="#{node.version}" changeset="#{changeset.id}"/>
1369 <delete version="0.6" if-unused="true">
1370 <node id="#{alone_node.id}" version="#{alone_node.version}" changeset="#{changeset.id}"/>
1375 auth_header = bearer_authorization_header changeset.user
1377 post api_changeset_upload_path(changeset), :params => diff.to_s, :headers => auth_header
1379 assert_response :precondition_failed
1380 assert_equal "Precondition failed: Node #{node.id} is still used by ways #{way.id}.", @response.body
1382 assert_no_changes_in changeset
1385 def test_upload_delete_unknown_node_placeholder
1386 check_upload_results_in_not_found do |changeset|
1387 "<delete><node id='-1' changeset='#{changeset.id}' version='1'/></delete>"
1391 def test_upload_delete_unknown_way_placeholder
1392 check_upload_results_in_not_found do |changeset|
1393 "<delete><way id='-1' changeset='#{changeset.id}' version='1'/></delete>"
1397 def test_upload_delete_unknown_relation_placeholder
1398 check_upload_results_in_not_found do |changeset|
1399 "<delete><relation id='-1' changeset='#{changeset.id}' version='1'/></delete>"
1403 # -------------------------------------
1404 # Test combined element changes.
1405 # -------------------------------------
1408 # upload something which creates new objects and inserts them into
1409 # existing containers using placeholders.
1410 def test_upload_create_and_insert_elements
1412 node = create(:node)
1413 relation = create(:relation)
1414 create(:way_node, :way => way, :node => node)
1415 changeset = create(:changeset)
1420 <node id='-1' lon='0' lat='0' changeset='#{changeset.id}'>
1421 <tag k='foo' v='bar'/>
1422 <tag k='baz' v='bat'/>
1426 <way id='#{way.id}' changeset='#{changeset.id}' version='1'>
1428 <nd ref='#{node.id}'/>
1430 <relation id='#{relation.id}' changeset='#{changeset.id}' version='1'>
1431 <member type='way' role='some' ref='#{way.id}'/>
1432 <member type='node' role='some' ref='-1'/>
1433 <member type='relation' role='some' ref='#{relation.id}'/>
1439 auth_header = bearer_authorization_header changeset.user
1441 post api_changeset_upload_path(changeset), :params => diff, :headers => auth_header
1443 assert_response :success
1446 assert_dom "diffResult[version='#{Settings.api_version}'][generator='#{Settings.generator}']", 1 do
1447 assert_dom "> node", 1 do |(node_el)|
1448 new_node_id = node_el["new_id"].to_i
1450 assert_dom "> way", 1
1451 assert_dom "> relation", 1
1454 assert_equal 2, Node.find(new_node_id).tags.size, "new node should have two tags"
1455 assert_equal [new_node_id, node.id], Way.find(way.id).nds, "way nodes should match"
1456 Relation.find(relation.id).members.each do |type, id, _role|
1457 assert_equal new_node_id, id, "relation should contain new node" if type == "node"
1462 # test that a placeholder can be reused within the same upload.
1463 def test_upload_create_modify_delete_node_reusing_placeholder
1464 changeset = create(:changeset)
1469 <node id='-1' lon='0' lat='0' changeset='#{changeset.id}'>
1470 <tag k="foo" v="bar"/>
1474 <node id='-1' lon='1' lat='1' changeset='#{changeset.id}' version='1'/>
1477 <node id='-1' lon='2' lat='2' changeset='#{changeset.id}' version='2'/>
1482 auth_header = bearer_authorization_header changeset.user
1484 assert_difference "Node.count", 1 do
1485 post api_changeset_upload_path(changeset), :params => diff, :headers => auth_header
1487 assert_response :success
1490 assert_dom "diffResult>node", 3
1491 assert_dom "diffResult>node[old_id='-1']", 3
1494 assert_equal 3, node.version
1495 assert_not node.visible
1498 def test_upload_create_and_duplicate_delete
1499 changeset = create(:changeset)
1504 <node id="-1" lat="39" lon="116" changeset="#{changeset.id}" />
1507 <node id="-1" version="1" changeset="#{changeset.id}" />
1508 <node id="-1" version="1" changeset="#{changeset.id}" />
1513 auth_header = bearer_authorization_header changeset.user
1515 assert_no_difference "Node.count" do
1516 post api_changeset_upload_path(changeset), :params => diff, :headers => auth_header
1518 assert_response :gone
1521 assert_no_changes_in changeset
1524 def test_upload_create_and_duplicate_delete_if_unused
1525 changeset = create(:changeset)
1530 <node id="-1" lat="39" lon="116" changeset="#{changeset.id}" />
1532 <delete if-unused="true">
1533 <node id="-1" version="1" changeset="#{changeset.id}" />
1534 <node id="-1" version="1" changeset="#{changeset.id}" />
1539 auth_header = bearer_authorization_header changeset.user
1541 assert_difference "Node.count", 1 do
1542 post api_changeset_upload_path(changeset), :params => diff, :headers => auth_header
1544 assert_response :success
1547 assert_dom "diffResult>node", 3
1548 assert_dom "diffResult>node[old_id='-1']", 3
1549 assert_dom "diffResult>node[new_version='1']", 1
1550 assert_dom "diffResult>node[new_version='2']", 1
1553 assert_equal 2, node.version
1554 assert_not node.visible
1557 # -------------------------------------
1558 # Test bounding boxes.
1559 # -------------------------------------
1561 def test_upload_bbox_of_widely_spaced_nodes
1562 user = create(:user)
1564 # create an old changeset to ensure we have the maximum rate limit
1565 create(:changeset, :user => user, :created_at => Time.now.utc - 28.days)
1567 changeset = create(:changeset, :user => user)
1569 # upload some widely-spaced nodes, spiralling positive and negative
1573 <node id='-1' lon='-20' lat='-10' changeset='#{changeset.id}'/>
1574 <node id='-10' lon='20' lat='10' changeset='#{changeset.id}'/>
1575 <node id='-2' lon='-40' lat='-20' changeset='#{changeset.id}'/>
1576 <node id='-11' lon='40' lat='20' changeset='#{changeset.id}'/>
1577 <node id='-3' lon='-60' lat='-30' changeset='#{changeset.id}'/>
1578 <node id='-12' lon='60' lat='30' changeset='#{changeset.id}'/>
1579 <node id='-4' lon='-80' lat='-40' changeset='#{changeset.id}'/>
1580 <node id='-13' lon='80' lat='40' changeset='#{changeset.id}'/>
1581 <node id='-5' lon='-100' lat='-50' changeset='#{changeset.id}'/>
1582 <node id='-14' lon='100' lat='50' changeset='#{changeset.id}'/>
1583 <node id='-6' lon='-120' lat='-60' changeset='#{changeset.id}'/>
1584 <node id='-15' lon='120' lat='60' changeset='#{changeset.id}'/>
1585 <node id='-7' lon='-140' lat='-70' changeset='#{changeset.id}'/>
1586 <node id='-16' lon='140' lat='70' changeset='#{changeset.id}'/>
1587 <node id='-8' lon='-160' lat='-80' changeset='#{changeset.id}'/>
1588 <node id='-17' lon='160' lat='80' changeset='#{changeset.id}'/>
1589 <node id='-9' lon='-179.9' lat='-89.9' changeset='#{changeset.id}'/>
1590 <node id='-18' lon='179.9' lat='89.9' changeset='#{changeset.id}'/>
1595 auth_header = bearer_authorization_header user
1597 post api_changeset_upload_path(changeset), :params => diff, :headers => auth_header
1599 assert_response :success
1602 assert_equal 18, changeset.num_changes
1603 assert_predicate changeset, :num_type_changes_in_sync?
1604 assert_equal 18, changeset.num_created_nodes
1606 # check that the changeset bbox is within bounds
1607 assert_operator changeset.min_lon, :>=, -180 * GeoRecord::SCALE, "Minimum longitude (#{changeset.min_lon / GeoRecord::SCALE}) should be >= -180 to be valid."
1608 assert_operator changeset.max_lon, :<=, 180 * GeoRecord::SCALE, "Maximum longitude (#{changeset.max_lon / GeoRecord::SCALE}) should be <= 180 to be valid."
1609 assert_operator changeset.min_lat, :>=, -90 * GeoRecord::SCALE, "Minimum latitude (#{changeset.min_lat / GeoRecord::SCALE}) should be >= -90 to be valid."
1610 assert_operator changeset.max_lat, :<=, 90 * GeoRecord::SCALE, "Maximum latitude (#{changeset.max_lat / GeoRecord::SCALE}) should be <= 90 to be valid."
1613 def test_upload_bbox_of_moved_node
1614 changeset = create(:changeset)
1615 node = create(:node, :lat => 1.0, :lon => 2.0)
1620 <node id='#{node.id}' lat='1.1' lon='2.1' changeset='#{changeset.id}' version='1'/>
1625 auth_header = bearer_authorization_header changeset.user
1627 post api_changeset_upload_path(changeset), :params => diff, :headers => auth_header
1629 assert_response :success
1632 assert_equal 1, changeset.num_changes
1633 assert_predicate changeset, :num_type_changes_in_sync?
1634 assert_equal 1, changeset.num_modified_nodes
1637 assert_equal 1.0 * GeoRecord::SCALE, changeset.min_lat, "min_lat should be 1.0 degrees"
1638 assert_equal 2.0 * GeoRecord::SCALE, changeset.min_lon, "min_lon should be 2.0 degrees"
1639 assert_equal 1.1 * GeoRecord::SCALE, changeset.max_lat, "max_lat should be 1.1 degrees"
1640 assert_equal 2.1 * GeoRecord::SCALE, changeset.max_lon, "max_lon should be 2.1 degrees"
1643 def test_upload_bbox_of_extended_way
1645 initial_node = create(:node, :lat => 1.1, :lon => 2.1)
1646 create(:way_node, :way => way, :node => initial_node)
1647 added_node = create(:node, :lat => 1.3, :lon => 2.3)
1648 changeset = create(:changeset)
1653 <way id='#{way.id}' changeset='#{changeset.id}' version='1'>
1654 <nd ref='#{initial_node.id}'/>
1655 <nd ref='#{added_node.id}'/>
1661 auth_header = bearer_authorization_header changeset.user
1663 post api_changeset_upload_path(changeset), :params => diff, :headers => auth_header
1665 assert_response :success
1669 assert_equal 1.1 * GeoRecord::SCALE, changeset.min_lat, "min_lat should be 1.1 degrees"
1670 assert_equal 2.1 * GeoRecord::SCALE, changeset.min_lon, "min_lon should be 2.1 degrees"
1671 assert_equal 1.3 * GeoRecord::SCALE, changeset.max_lat, "max_lat should be 1.3 degrees"
1672 assert_equal 2.3 * GeoRecord::SCALE, changeset.max_lon, "max_lon should be 2.3 degrees"
1675 # -------------------------------------
1676 # Test upload rate/size limits.
1677 # -------------------------------------
1679 def test_upload_initial_rate_limit
1680 user = create(:user)
1681 node = create(:node)
1682 way = create(:way_with_nodes, :nodes_count => 2)
1683 relation = create(:relation)
1685 # create a changeset that puts us near the initial rate limit
1686 num_changes = Settings.initial_changes_per_hour - 2
1687 changeset = create(:changeset, :user => user,
1688 :created_at => Time.now.utc - 5.minutes,
1689 :num_changes => num_changes,
1690 :num_created_nodes => num_changes)
1695 <node id='-1' lon='0' lat='0' changeset='#{changeset.id}'>
1696 <tag k='foo' v='bar'/>
1697 <tag k='baz' v='bat'/>
1699 <way id='-1' changeset='#{changeset.id}'>
1700 <nd ref='#{node.id}'/>
1704 <relation id='-1' changeset='#{changeset.id}'>
1705 <member type='way' role='some' ref='#{way.id}'/>
1706 <member type='node' role='some' ref='#{node.id}'/>
1707 <member type='relation' role='some' ref='#{relation.id}'/>
1713 auth_header = bearer_authorization_header user
1715 post api_changeset_upload_path(changeset), :params => diff, :headers => auth_header
1717 assert_response :too_many_requests, "upload did not hit rate limit"
1720 assert_equal num_changes, changeset.num_changes
1721 assert_predicate changeset, :num_type_changes_in_sync?
1724 def test_upload_maximum_rate_limit
1725 user = create(:user)
1726 node = create(:node)
1727 way = create(:way_with_nodes, :nodes_count => 2)
1728 relation = create(:relation)
1730 # create a changeset to establish our initial edit time
1731 changeset = create(:changeset, :user => user,
1732 :created_at => Time.now.utc - 28.days)
1734 # create changeset to put us near the maximum rate limit
1735 remaining_num_changes = Settings.max_changes_per_hour - 2
1737 while remaining_num_changes.positive?
1738 num_changes = [remaining_num_changes, Changeset::MAX_ELEMENTS].min
1739 changeset = create(:changeset, :user => user,
1740 :created_at => Time.now.utc - 5.minutes,
1741 :num_changes => num_changes,
1742 :num_created_nodes => num_changes)
1743 remaining_num_changes -= num_changes
1749 <node id='-1' lon='0' lat='0' changeset='#{changeset.id}'>
1750 <tag k='foo' v='bar'/>
1751 <tag k='baz' v='bat'/>
1753 <way id='-1' changeset='#{changeset.id}'>
1754 <nd ref='#{node.id}'/>
1758 <relation id='-1' changeset='#{changeset.id}'>
1759 <member type='way' role='some' ref='#{way.id}'/>
1760 <member type='node' role='some' ref='#{node.id}'/>
1761 <member type='relation' role='some' ref='#{relation.id}'/>
1767 auth_header = bearer_authorization_header user
1769 post api_changeset_upload_path(changeset), :params => diff, :headers => auth_header
1771 assert_response :too_many_requests, "upload did not hit rate limit"
1774 assert_equal num_changes, changeset.num_changes
1775 assert_predicate changeset, :num_type_changes_in_sync?
1778 def test_upload_initial_size_limit
1779 user = create(:user)
1781 # create a changeset that puts us near the initial size limit
1782 changeset = create(:changeset, :user => user,
1783 :min_lat => (-0.5 * GeoRecord::SCALE).round, :min_lon => (0.5 * GeoRecord::SCALE).round,
1784 :max_lat => (0.5 * GeoRecord::SCALE).round, :max_lon => (2.5 * GeoRecord::SCALE).round)
1789 <node id='-1' lon='0.9' lat='2.9' changeset='#{changeset.id}'>
1790 <tag k='foo' v='bar'/>
1791 <tag k='baz' v='bat'/>
1797 auth_header = bearer_authorization_header user
1799 post api_changeset_upload_path(changeset), :params => diff, :headers => auth_header
1801 assert_response :payload_too_large, "upload did not hit size limit"
1803 assert_no_changes_in changeset
1806 def test_upload_size_limit_after_one_week
1807 user = create(:user)
1809 # create a changeset to establish our initial edit time
1810 create(:changeset, :user => user, :created_at => Time.now.utc - 7.days)
1812 # create a changeset that puts us near the initial size limit
1813 changeset = create(:changeset, :user => user, :bbox => [0.5, -0.5, 2.5, 0.5])
1818 <node id='-1' lon='35' lat='35' changeset='#{changeset.id}'>
1819 <tag k='foo' v='bar'/>
1820 <tag k='baz' v='bat'/>
1826 auth_header = bearer_authorization_header user
1828 post api_changeset_upload_path(changeset), :params => diff, :headers => auth_header
1830 assert_response :payload_too_large, "upload did not hit size limit"
1832 assert_no_changes_in changeset
1837 def check_upload_results_in_not_found(&)
1838 changeset = create(:changeset)
1839 diff = "<osmChange>#{yield changeset}</osmChange>"
1840 auth_header = bearer_authorization_header changeset.user
1842 post api_changeset_upload_path(changeset), :params => diff, :headers => auth_header
1844 assert_response :not_found
1846 assert_no_changes_in changeset
1849 def assert_no_changes_in(changeset)
1851 assert_equal 0, changeset.num_changes
1852 assert_predicate changeset, :num_type_changes_in_sync?