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
758 assert_predicate changeset, :num_type_changes_in_sync?
759 assert_equal 1, changeset.num_modified_ways
762 assert_equal 2, way.version
763 assert_equal 0, way.tags.size, "way #{way.id} should now have no tags"
764 assert_equal [node], way.nodes
767 def test_upload_modify_relation
769 changeset = create(:changeset, :user => user)
771 way = create(:way_with_nodes)
772 relation = create(:relation)
773 other_relation = create(:relation)
774 create(:relation_tag, :relation => relation)
779 <relation id='#{relation.id}' changeset='#{changeset.id}' version='1'>
780 <member type='way' role='some' ref='#{way.id}'/>
781 <member type='node' role='some' ref='#{node.id}'/>
782 <member type='relation' role='some' ref='#{other_relation.id}'/>
788 auth_header = bearer_authorization_header user
790 assert_difference "Relation.count" => 0,
791 "OldRelation.count" => 1,
792 "RelationTag.count" => -1,
793 "OldRelationTag.count" => 0,
794 "RelationMember.count" => 3,
795 "OldRelationMember.count" => 3 do
796 post api_changeset_upload_path(changeset), :params => diff, :headers => auth_header
798 assert_response :success
801 assert_dom "diffResult[version='#{Settings.api_version}'][generator='#{Settings.generator}']", 1 do
802 assert_dom "> relation", 1 do
803 assert_dom "> @old_id", relation.id.to_s
804 assert_dom "> @new_id", relation.id.to_s
805 assert_dom "> @new_version", "2"
810 assert_equal 1, changeset.num_changes
812 assert_equal 2, relation.version
813 assert_equal 0, relation.tags.size, "relation #{relation.id} should now have no tags"
814 assert_equal [["Way", way.id, "some"], ["Node", node.id, "some"], ["Relation", other_relation.id, "some"]], relation.members
817 def test_upload_modify_elements
819 changeset = create(:changeset, :user => user)
820 node = create(:node, :latitude => 0, :longitude => 0)
822 relation = create(:relation)
823 other_relation = create(:relation)
825 # create some tags, since we test that they are removed later
826 create(:node_tag, :node => node)
827 create(:way_tag, :way => way)
828 create(:relation_tag, :relation => relation)
830 # simple diff to change a node, way and relation by removing their tags
834 <node id='#{node.id}' lon='1' lat='2' changeset='#{changeset.id}' version='1'/>
835 <way id='#{way.id}' changeset='#{changeset.id}' version='1'>
836 <nd ref='#{node.id}'/>
840 <relation id='#{relation.id}' changeset='#{changeset.id}' version='1'>
841 <member type='way' role='some' ref='#{way.id}'/>
842 <member type='node' role='some' ref='#{node.id}'/>
843 <member type='relation' role='some' ref='#{other_relation.id}'/>
849 auth_header = bearer_authorization_header user
851 post api_changeset_upload_path(changeset), :params => diff, :headers => auth_header
853 assert_response :success
855 assert_dom "diffResult[version='#{Settings.api_version}'][generator='#{Settings.generator}']", 1 do
856 assert_dom "> node", 1 do
857 assert_dom "> @old_id", node.id.to_s
858 assert_dom "> @new_id", node.id.to_s
859 assert_dom "> @new_version", "2"
861 assert_dom "> way", 1 do
862 assert_dom "> @old_id", way.id.to_s
863 assert_dom "> @new_id", way.id.to_s
864 assert_dom "> @new_version", "2"
866 assert_dom "> relation", 1 do
867 assert_dom "> @old_id", relation.id.to_s
868 assert_dom "> @new_id", relation.id.to_s
869 assert_dom "> @new_version", "2"
874 assert_equal 3, changeset.num_changes
876 assert_equal 2, node.version
877 assert_equal 2 * GeoRecord::SCALE, node.latitude
878 assert_equal 1 * GeoRecord::SCALE, node.longitude
879 assert_equal 0, node.tags.size, "node #{node.id} should now have no tags"
881 assert_equal 2, way.version
882 assert_equal 0, way.tags.size, "way #{way.id} should now have no tags"
883 assert_equal [node], way.nodes
885 assert_equal 2, relation.version
886 assert_equal 0, relation.tags.size, "relation #{relation.id} should now have no tags"
887 assert_equal [["Way", way.id, "some"], ["Node", node.id, "some"], ["Relation", other_relation.id, "some"]], relation.members
891 # upload multiple versions of the same element in the same diff.
892 def test_upload_modify_multiple_node_versions
894 changeset = create(:changeset)
896 # change the location of a node multiple times, each time referencing
897 # the last version. doesn't this depend on version numbers being
902 <node id='#{node.id}' lon='0.0' lat='0.0' changeset='#{changeset.id}' version='1'/>
903 <node id='#{node.id}' lon='0.1' lat='0.0' changeset='#{changeset.id}' version='2'/>
904 <node id='#{node.id}' lon='0.1' lat='0.1' changeset='#{changeset.id}' version='3'/>
905 <node id='#{node.id}' lon='0.1' lat='0.2' changeset='#{changeset.id}' version='4'/>
906 <node id='#{node.id}' lon='0.2' lat='0.2' changeset='#{changeset.id}' version='5'/>
907 <node id='#{node.id}' lon='0.3' lat='0.2' changeset='#{changeset.id}' version='6'/>
908 <node id='#{node.id}' lon='0.3' lat='0.3' changeset='#{changeset.id}' version='7'/>
909 <node id='#{node.id}' lon='0.9' lat='0.9' changeset='#{changeset.id}' version='8'/>
914 auth_header = bearer_authorization_header changeset.user
916 post api_changeset_upload_path(changeset), :params => diff, :headers => auth_header
918 assert_response :success
920 assert_dom "diffResult>node", 8
923 assert_equal 8, changeset.num_changes
924 assert_predicate changeset, :num_type_changes_in_sync?
925 assert_equal 8, changeset.num_modified_nodes
928 assert_equal 9, node.version
929 assert_equal 0.9 * GeoRecord::SCALE, node.latitude
930 assert_equal 0.9 * GeoRecord::SCALE, node.longitude
934 # upload multiple versions of the same element in the same diff, but
935 # keep the version numbers the same.
936 def test_upload_modify_duplicate_node_versions
937 node = create(:node, :latitude => 0, :longitude => 0)
938 changeset = create(:changeset)
943 <node id='#{node.id}' lon='1' lat='1' changeset='#{changeset.id}' version='1'/>
944 <node id='#{node.id}' lon='2' lat='2' changeset='#{changeset.id}' version='1'/>
949 auth_header = bearer_authorization_header changeset.user
951 post api_changeset_upload_path(changeset), :params => diff, :headers => auth_header
953 assert_response :conflict
955 assert_no_changes_in changeset
958 assert_equal 1, node.version
959 assert_equal 0, node.latitude
960 assert_equal 0, node.longitude
964 # try to upload some elements without specifying the version
965 def test_upload_modify_missing_node_version
966 node = create(:node, :latitude => 0, :longitude => 0)
967 changeset = create(:changeset)
972 <node id='#{node.id}' lon='1' lat='1' changeset='#{changeset.id}'/>
977 auth_header = bearer_authorization_header changeset.user
979 post api_changeset_upload_path(changeset), :params => diff, :headers => auth_header
981 assert_response :bad_request
983 assert_no_changes_in changeset
986 assert_equal 1, node.version
987 assert_equal 0, node.latitude
988 assert_equal 0, node.longitude
992 # create a diff which references several changesets, which should cause
993 # a rollback and none of the diff gets committed
994 def test_upload_modify_with_references_to_different_changesets
995 changeset1 = create(:changeset)
996 changeset2 = create(:changeset, :user => changeset1.user)
997 node1 = create(:node)
998 node2 = create(:node)
1000 # simple diff to create a node way and relation using placeholders
1004 <node id='#{node1.id}' lon='0' lat='0' changeset='#{changeset1.id}' version='1'/>
1007 <node id='#{node2.id}' lon='0' lat='0' changeset='#{changeset2.id}' version='1'/>
1012 auth_header = bearer_authorization_header changeset1.user
1014 post api_changeset_upload_path(changeset1), :params => diff, :headers => auth_header
1016 assert_response :conflict
1018 assert_no_changes_in changeset1
1019 assert_no_changes_in changeset2
1021 assert_nodes_are_equal(node1, Node.find(node1.id))
1022 assert_nodes_are_equal(node2, Node.find(node2.id))
1026 # upload a valid changeset which has a mixture of whitespace
1027 # to check a bug https://github.com/openstreetmap/trac-tickets/issues/1565
1028 def test_upload_modify_with_mixed_whitespace
1029 changeset = create(:changeset)
1030 node = create(:node)
1031 way = create(:way_with_nodes, :nodes_count => 2)
1032 relation = create(:relation)
1033 other_relation = create(:relation)
1034 create(:relation_tag, :relation => relation)
1038 <modify><node id='#{node.id}' lon='0' lat='0' changeset='#{changeset.id}'
1040 <node id='#{node.id}' lon='1' lat='1' changeset='#{changeset.id}' version='2'><tag k='k' v='v'/></node></modify>
1042 <relation id='#{relation.id}' changeset='#{changeset.id}' version='1'><member
1043 type='way' role='some' ref='#{way.id}'/><member
1044 type='node' role='some' ref='#{node.id}'/>
1045 <member type='relation' role='some' ref='#{other_relation.id}'/>
1047 </modify></osmChange>
1050 auth_header = bearer_authorization_header changeset.user
1052 post api_changeset_upload_path(changeset), :params => diff, :headers => auth_header
1054 assert_response :success
1056 assert_dom "diffResult>node", 2
1057 assert_dom "diffResult>relation", 1
1059 assert_equal 1, Node.find(node.id).tags.size, "node #{node.id} should now have one tag"
1060 assert_equal 0, Relation.find(relation.id).tags.size, "relation #{relation.id} should now have no tags"
1063 def test_upload_modify_unknown_node_placeholder
1064 check_upload_results_in_not_found do |changeset|
1065 "<modify><node id='-1' lon='0' lat='0' changeset='#{changeset.id}' version='1'/></modify>"
1069 def test_upload_modify_unknown_way_placeholder
1070 check_upload_results_in_not_found do |changeset|
1071 "<modify><way id='-1' changeset='#{changeset.id}' version='1'/></modify>"
1075 def test_upload_modify_unknown_relation_placeholder
1076 check_upload_results_in_not_found do |changeset|
1077 "<modify><relation id='-1' changeset='#{changeset.id}' version='1'/></modify>"
1081 # -------------------------------------
1082 # Test deleting elements.
1083 # -------------------------------------
1085 def test_upload_delete_node
1086 changeset = create(:changeset)
1087 node = create(:node, :lat => 0, :lon => 0)
1088 create(:node_tag, :node => node)
1093 <node id='#{node.id}' changeset='#{changeset.id}' version='1' lat='0' lon='0'/>
1098 auth_header = bearer_authorization_header changeset.user
1100 assert_difference "Node.count" => 0,
1101 "OldNode.count" => 1,
1102 "NodeTag.count" => -1,
1103 "OldNodeTag.count" => 0 do
1104 post api_changeset_upload_path(changeset), :params => diff, :headers => auth_header
1106 assert_response :success
1109 assert_dom "diffResult", 1 do
1110 assert_dom "> node", 1 do
1111 assert_dom "> @old_id", node.id.to_s
1116 assert_not_predicate node, :visible?
1119 def test_upload_delete_way
1120 changeset = create(:changeset)
1121 way = create(:way_with_nodes, :nodes_count => 3)
1122 create(:way_tag, :way => way)
1127 <way id='#{way.id}' changeset='#{changeset.id}' version='1'/>
1132 auth_header = bearer_authorization_header changeset.user
1134 assert_difference "Way.count" => 0,
1135 "OldWay.count" => 1,
1136 "WayTag.count" => -1,
1137 "OldWayTag.count" => 0,
1138 "WayNode.count" => -3,
1139 "OldWayNode.count" => 0 do
1140 post api_changeset_upload_path(changeset), :params => diff, :headers => auth_header
1142 assert_response :success
1145 assert_dom "diffResult", 1 do
1146 assert_dom "> way", 1 do
1147 assert_dom "> @old_id", way.id.to_s
1152 assert_not_predicate way, :visible?
1155 def test_upload_delete_relation
1156 changeset = create(:changeset)
1157 relation = create(:relation)
1158 create(:relation_member, :relation => relation, :member => create(:node))
1159 create(:relation_tag, :relation => relation)
1164 <relation id='#{relation.id}' changeset='#{changeset.id}' version='1'/>
1169 auth_header = bearer_authorization_header changeset.user
1171 assert_difference "Relation.count" => 0,
1172 "OldRelation.count" => 1,
1173 "RelationTag.count" => -1,
1174 "OldRelationTag.count" => 0,
1175 "RelationMember.count" => -1,
1176 "OldRelationMember.count" => 0 do
1177 post api_changeset_upload_path(changeset), :params => diff, :headers => auth_header
1179 assert_response :success
1182 assert_dom "diffResult", 1 do
1183 assert_dom "> relation", 1 do
1184 assert_dom "> @old_id", relation.id.to_s
1189 assert_not_predicate relation, :visible?
1193 # test a complex delete where we delete elements which rely on each other
1194 # in the same transaction.
1195 def test_upload_delete_elements
1196 changeset = create(:changeset)
1197 super_relation = create(:relation)
1198 used_relation = create(:relation)
1199 used_way = create(:way)
1200 used_node = create(:node)
1201 create(:relation_member, :relation => super_relation, :member => used_relation)
1202 create(:relation_member, :relation => super_relation, :member => used_way)
1203 create(:relation_member, :relation => super_relation, :member => used_node)
1205 diff = XML::Document.new
1206 diff.root = XML::Node.new "osmChange"
1207 delete = XML::Node.new "delete"
1209 delete << xml_node_for_relation(super_relation)
1210 delete << xml_node_for_relation(used_relation)
1211 delete << xml_node_for_way(used_way)
1212 delete << xml_node_for_node(used_node)
1213 %w[node way relation].each do |type|
1214 delete.find("//osmChange/delete/#{type}").each do |n|
1215 n["changeset"] = changeset.id.to_s
1219 auth_header = bearer_authorization_header changeset.user
1221 post api_changeset_upload_path(changeset), :params => diff.to_s, :headers => auth_header
1223 assert_response :success
1225 assert_dom "diffResult", 1 do
1226 assert_dom "> node", 1
1227 assert_dom "> way", 1
1228 assert_dom "> relation", 2
1231 assert_not Node.find(used_node.id).visible
1232 assert_not Way.find(used_way.id).visible
1233 assert_not Relation.find(super_relation.id).visible
1234 assert_not Relation.find(used_relation.id).visible
1238 # test uploading a delete with no lat/lon, as they are optional in the osmChange spec.
1239 def test_upload_delete_node_without_latlon
1240 node = create(:node)
1241 changeset = create(:changeset)
1243 diff = "<osmChange><delete><node id='#{node.id}' version='#{node.version}' changeset='#{changeset.id}'/></delete></osmChange>"
1245 auth_header = bearer_authorization_header changeset.user
1247 post api_changeset_upload_path(changeset), :params => diff, :headers => auth_header
1249 assert_response :success
1251 assert_dom "diffResult", 1 do
1252 assert_dom "> node", 1 do
1253 assert_dom "> @old_id", node.id.to_s
1254 assert_dom "> @new_id", 0
1255 assert_dom "> @new_version", 0
1260 assert_not node.visible
1264 # test that deleting stuff in a transaction doesn't bypass the checks
1265 # to ensure that used elements are not deleted.
1266 def test_upload_delete_referenced_elements
1267 changeset = create(:changeset)
1268 relation = create(:relation)
1269 other_relation = create(:relation)
1270 used_way = create(:way)
1271 used_node = create(:node)
1272 create(:relation_member, :relation => relation, :member => used_way)
1273 create(:relation_member, :relation => relation, :member => used_node)
1275 diff = XML::Document.new
1276 diff.root = XML::Node.new "osmChange"
1277 delete = XML::Node.new "delete"
1279 delete << xml_node_for_relation(other_relation)
1280 delete << xml_node_for_way(used_way)
1281 delete << xml_node_for_node(used_node)
1282 %w[node way relation].each do |type|
1283 delete.find("//osmChange/delete/#{type}").each do |n|
1284 n["changeset"] = changeset.id.to_s
1288 auth_header = bearer_authorization_header changeset.user
1290 post api_changeset_upload_path(changeset), :params => diff.to_s, :headers => auth_header
1292 assert_response :precondition_failed
1293 assert_equal "Precondition failed: Way #{used_way.id} is still used by relations #{relation.id}.", @response.body
1295 assert_no_changes_in changeset
1297 assert Node.find(used_node.id).visible
1298 assert Way.find(used_way.id).visible
1299 assert Relation.find(relation.id).visible
1300 assert Relation.find(other_relation.id).visible
1304 # test that a conditional delete of an in use object works.
1305 def test_upload_delete_if_unused
1306 changeset = create(:changeset)
1307 super_relation = create(:relation)
1308 used_relation = create(:relation)
1309 used_way = create(:way)
1310 used_node = create(:node)
1311 create(:relation_member, :relation => super_relation, :member => used_relation)
1312 create(:relation_member, :relation => super_relation, :member => used_way)
1313 create(:relation_member, :relation => super_relation, :member => used_node)
1315 diff = XML::Document.new
1316 diff.root = XML::Node.new "osmChange"
1317 delete = XML::Node.new "delete"
1319 delete["if-unused"] = ""
1320 delete << xml_node_for_relation(used_relation)
1321 delete << xml_node_for_way(used_way)
1322 delete << xml_node_for_node(used_node)
1323 %w[node way relation].each do |type|
1324 delete.find("//osmChange/delete/#{type}").each do |n|
1325 n["changeset"] = changeset.id.to_s
1329 auth_header = bearer_authorization_header changeset.user
1331 post api_changeset_upload_path(changeset), :params => diff.to_s, :headers => auth_header
1333 assert_response :success
1335 assert_dom "diffResult[version='#{Settings.api_version}'][generator='#{Settings.generator}']", 1 do
1336 assert_dom "> node", 1 do
1337 assert_dom "> @old_id", used_node.id.to_s
1338 assert_dom "> @new_id", used_node.id.to_s
1339 assert_dom "> @new_version", used_node.version.to_s
1341 assert_dom "> way", 1 do
1342 assert_dom "> @old_id", used_way.id.to_s
1343 assert_dom "> @new_id", used_way.id.to_s
1344 assert_dom "> @new_version", used_way.version.to_s
1346 assert_dom "> relation", 1 do
1347 assert_dom "> @old_id", used_relation.id.to_s
1348 assert_dom "> @new_id", used_relation.id.to_s
1349 assert_dom "> @new_version", used_relation.version.to_s
1353 assert_no_changes_in changeset
1355 assert Node.find(used_node.id).visible
1356 assert Way.find(used_way.id).visible
1357 assert Relation.find(used_relation.id).visible
1360 def test_upload_delete_with_multiple_blocks_and_if_unused
1361 changeset = create(:changeset)
1362 node = create(:node)
1364 create(:way_node, :way => way, :node => node)
1365 alone_node = create(:node)
1368 <osmChange version='0.6'>
1369 <delete version="0.6">
1370 <node id="#{node.id}" version="#{node.version}" changeset="#{changeset.id}"/>
1372 <delete version="0.6" if-unused="true">
1373 <node id="#{alone_node.id}" version="#{alone_node.version}" changeset="#{changeset.id}"/>
1378 auth_header = bearer_authorization_header changeset.user
1380 post api_changeset_upload_path(changeset), :params => diff.to_s, :headers => auth_header
1382 assert_response :precondition_failed
1383 assert_equal "Precondition failed: Node #{node.id} is still used by ways #{way.id}.", @response.body
1385 assert_no_changes_in changeset
1388 def test_upload_delete_unknown_node_placeholder
1389 check_upload_results_in_not_found do |changeset|
1390 "<delete><node id='-1' changeset='#{changeset.id}' version='1'/></delete>"
1394 def test_upload_delete_unknown_way_placeholder
1395 check_upload_results_in_not_found do |changeset|
1396 "<delete><way id='-1' changeset='#{changeset.id}' version='1'/></delete>"
1400 def test_upload_delete_unknown_relation_placeholder
1401 check_upload_results_in_not_found do |changeset|
1402 "<delete><relation id='-1' changeset='#{changeset.id}' version='1'/></delete>"
1406 # -------------------------------------
1407 # Test combined element changes.
1408 # -------------------------------------
1411 # upload something which creates new objects and inserts them into
1412 # existing containers using placeholders.
1413 def test_upload_create_and_insert_elements
1415 node = create(:node)
1416 relation = create(:relation)
1417 create(:way_node, :way => way, :node => node)
1418 changeset = create(:changeset)
1423 <node id='-1' lon='0' lat='0' changeset='#{changeset.id}'>
1424 <tag k='foo' v='bar'/>
1425 <tag k='baz' v='bat'/>
1429 <way id='#{way.id}' changeset='#{changeset.id}' version='1'>
1431 <nd ref='#{node.id}'/>
1433 <relation id='#{relation.id}' changeset='#{changeset.id}' version='1'>
1434 <member type='way' role='some' ref='#{way.id}'/>
1435 <member type='node' role='some' ref='-1'/>
1436 <member type='relation' role='some' ref='#{relation.id}'/>
1442 auth_header = bearer_authorization_header changeset.user
1444 post api_changeset_upload_path(changeset), :params => diff, :headers => auth_header
1446 assert_response :success
1449 assert_dom "diffResult[version='#{Settings.api_version}'][generator='#{Settings.generator}']", 1 do
1450 assert_dom "> node", 1 do |(node_el)|
1451 new_node_id = node_el["new_id"].to_i
1453 assert_dom "> way", 1
1454 assert_dom "> relation", 1
1457 assert_equal 2, Node.find(new_node_id).tags.size, "new node should have two tags"
1458 assert_equal [new_node_id, node.id], Way.find(way.id).nds, "way nodes should match"
1459 Relation.find(relation.id).members.each do |type, id, _role|
1460 assert_equal new_node_id, id, "relation should contain new node" if type == "node"
1465 # test that a placeholder can be reused within the same upload.
1466 def test_upload_create_modify_delete_node_reusing_placeholder
1467 changeset = create(:changeset)
1472 <node id='-1' lon='0' lat='0' changeset='#{changeset.id}'>
1473 <tag k="foo" v="bar"/>
1477 <node id='-1' lon='1' lat='1' changeset='#{changeset.id}' version='1'/>
1480 <node id='-1' lon='2' lat='2' changeset='#{changeset.id}' version='2'/>
1485 auth_header = bearer_authorization_header changeset.user
1487 assert_difference "Node.count", 1 do
1488 post api_changeset_upload_path(changeset), :params => diff, :headers => auth_header
1490 assert_response :success
1493 assert_dom "diffResult>node", 3
1494 assert_dom "diffResult>node[old_id='-1']", 3
1497 assert_equal 3, node.version
1498 assert_not node.visible
1501 def test_upload_create_and_duplicate_delete
1502 changeset = create(:changeset)
1507 <node id="-1" lat="39" lon="116" changeset="#{changeset.id}" />
1510 <node id="-1" version="1" changeset="#{changeset.id}" />
1511 <node id="-1" version="1" changeset="#{changeset.id}" />
1516 auth_header = bearer_authorization_header changeset.user
1518 assert_no_difference "Node.count" do
1519 post api_changeset_upload_path(changeset), :params => diff, :headers => auth_header
1521 assert_response :gone
1524 assert_no_changes_in changeset
1527 def test_upload_create_and_duplicate_delete_if_unused
1528 changeset = create(:changeset)
1533 <node id="-1" lat="39" lon="116" changeset="#{changeset.id}" />
1535 <delete if-unused="true">
1536 <node id="-1" version="1" changeset="#{changeset.id}" />
1537 <node id="-1" version="1" changeset="#{changeset.id}" />
1542 auth_header = bearer_authorization_header changeset.user
1544 assert_difference "Node.count", 1 do
1545 post api_changeset_upload_path(changeset), :params => diff, :headers => auth_header
1547 assert_response :success
1550 assert_dom "diffResult>node", 3
1551 assert_dom "diffResult>node[old_id='-1']", 3
1552 assert_dom "diffResult>node[new_version='1']", 1
1553 assert_dom "diffResult>node[new_version='2']", 1
1556 assert_equal 2, node.version
1557 assert_not node.visible
1560 # -------------------------------------
1561 # Test bounding boxes.
1562 # -------------------------------------
1564 def test_upload_bbox_of_widely_spaced_nodes
1565 user = create(:user)
1567 # create an old changeset to ensure we have the maximum rate limit
1568 create(:changeset, :user => user, :created_at => Time.now.utc - 28.days)
1570 changeset = create(:changeset, :user => user)
1572 # upload some widely-spaced nodes, spiralling positive and negative
1576 <node id='-1' lon='-20' lat='-10' changeset='#{changeset.id}'/>
1577 <node id='-10' lon='20' lat='10' changeset='#{changeset.id}'/>
1578 <node id='-2' lon='-40' lat='-20' changeset='#{changeset.id}'/>
1579 <node id='-11' lon='40' lat='20' changeset='#{changeset.id}'/>
1580 <node id='-3' lon='-60' lat='-30' changeset='#{changeset.id}'/>
1581 <node id='-12' lon='60' lat='30' changeset='#{changeset.id}'/>
1582 <node id='-4' lon='-80' lat='-40' changeset='#{changeset.id}'/>
1583 <node id='-13' lon='80' lat='40' changeset='#{changeset.id}'/>
1584 <node id='-5' lon='-100' lat='-50' changeset='#{changeset.id}'/>
1585 <node id='-14' lon='100' lat='50' changeset='#{changeset.id}'/>
1586 <node id='-6' lon='-120' lat='-60' changeset='#{changeset.id}'/>
1587 <node id='-15' lon='120' lat='60' changeset='#{changeset.id}'/>
1588 <node id='-7' lon='-140' lat='-70' changeset='#{changeset.id}'/>
1589 <node id='-16' lon='140' lat='70' changeset='#{changeset.id}'/>
1590 <node id='-8' lon='-160' lat='-80' changeset='#{changeset.id}'/>
1591 <node id='-17' lon='160' lat='80' changeset='#{changeset.id}'/>
1592 <node id='-9' lon='-179.9' lat='-89.9' changeset='#{changeset.id}'/>
1593 <node id='-18' lon='179.9' lat='89.9' changeset='#{changeset.id}'/>
1598 auth_header = bearer_authorization_header user
1600 post api_changeset_upload_path(changeset), :params => diff, :headers => auth_header
1602 assert_response :success
1605 assert_equal 18, changeset.num_changes
1606 assert_predicate changeset, :num_type_changes_in_sync?
1607 assert_equal 18, changeset.num_created_nodes
1609 # check that the changeset bbox is within bounds
1610 assert_operator changeset.min_lon, :>=, -180 * GeoRecord::SCALE, "Minimum longitude (#{changeset.min_lon / GeoRecord::SCALE}) should be >= -180 to be valid."
1611 assert_operator changeset.max_lon, :<=, 180 * GeoRecord::SCALE, "Maximum longitude (#{changeset.max_lon / GeoRecord::SCALE}) should be <= 180 to be valid."
1612 assert_operator changeset.min_lat, :>=, -90 * GeoRecord::SCALE, "Minimum latitude (#{changeset.min_lat / GeoRecord::SCALE}) should be >= -90 to be valid."
1613 assert_operator changeset.max_lat, :<=, 90 * GeoRecord::SCALE, "Maximum latitude (#{changeset.max_lat / GeoRecord::SCALE}) should be <= 90 to be valid."
1616 def test_upload_bbox_of_moved_node
1617 changeset = create(:changeset)
1618 node = create(:node, :lat => 1.0, :lon => 2.0)
1623 <node id='#{node.id}' lat='1.1' lon='2.1' changeset='#{changeset.id}' version='1'/>
1628 auth_header = bearer_authorization_header changeset.user
1630 post api_changeset_upload_path(changeset), :params => diff, :headers => auth_header
1632 assert_response :success
1635 assert_equal 1, changeset.num_changes
1636 assert_predicate changeset, :num_type_changes_in_sync?
1637 assert_equal 1, changeset.num_modified_nodes
1640 assert_equal 1.0 * GeoRecord::SCALE, changeset.min_lat, "min_lat should be 1.0 degrees"
1641 assert_equal 2.0 * GeoRecord::SCALE, changeset.min_lon, "min_lon should be 2.0 degrees"
1642 assert_equal 1.1 * GeoRecord::SCALE, changeset.max_lat, "max_lat should be 1.1 degrees"
1643 assert_equal 2.1 * GeoRecord::SCALE, changeset.max_lon, "max_lon should be 2.1 degrees"
1646 def test_upload_bbox_of_extended_way
1648 initial_node = create(:node, :lat => 1.1, :lon => 2.1)
1649 create(:way_node, :way => way, :node => initial_node)
1650 added_node = create(:node, :lat => 1.3, :lon => 2.3)
1651 changeset = create(:changeset)
1656 <way id='#{way.id}' changeset='#{changeset.id}' version='1'>
1657 <nd ref='#{initial_node.id}'/>
1658 <nd ref='#{added_node.id}'/>
1664 auth_header = bearer_authorization_header changeset.user
1666 post api_changeset_upload_path(changeset), :params => diff, :headers => auth_header
1668 assert_response :success
1671 assert_equal 1, changeset.num_changes
1672 assert_predicate changeset, :num_type_changes_in_sync?
1673 assert_equal 1, changeset.num_modified_ways
1676 assert_equal 1.1 * GeoRecord::SCALE, changeset.min_lat, "min_lat should be 1.1 degrees"
1677 assert_equal 2.1 * GeoRecord::SCALE, changeset.min_lon, "min_lon should be 2.1 degrees"
1678 assert_equal 1.3 * GeoRecord::SCALE, changeset.max_lat, "max_lat should be 1.3 degrees"
1679 assert_equal 2.3 * GeoRecord::SCALE, changeset.max_lon, "max_lon should be 2.3 degrees"
1682 # -------------------------------------
1683 # Test upload rate/size limits.
1684 # -------------------------------------
1686 def test_upload_initial_rate_limit
1687 user = create(:user)
1688 node = create(:node)
1689 way = create(:way_with_nodes, :nodes_count => 2)
1690 relation = create(:relation)
1692 # create a changeset that puts us near the initial rate limit
1693 num_changes = Settings.initial_changes_per_hour - 2
1694 changeset = create(:changeset, :user => user,
1695 :created_at => Time.now.utc - 5.minutes,
1696 :num_changes => num_changes,
1697 :num_created_nodes => num_changes)
1702 <node id='-1' lon='0' lat='0' changeset='#{changeset.id}'>
1703 <tag k='foo' v='bar'/>
1704 <tag k='baz' v='bat'/>
1706 <way id='-1' changeset='#{changeset.id}'>
1707 <nd ref='#{node.id}'/>
1711 <relation id='-1' changeset='#{changeset.id}'>
1712 <member type='way' role='some' ref='#{way.id}'/>
1713 <member type='node' role='some' ref='#{node.id}'/>
1714 <member type='relation' role='some' ref='#{relation.id}'/>
1720 auth_header = bearer_authorization_header user
1722 post api_changeset_upload_path(changeset), :params => diff, :headers => auth_header
1724 assert_response :too_many_requests, "upload did not hit rate limit"
1727 assert_equal num_changes, changeset.num_changes
1728 assert_predicate changeset, :num_type_changes_in_sync?
1731 def test_upload_maximum_rate_limit
1732 user = create(:user)
1733 node = create(:node)
1734 way = create(:way_with_nodes, :nodes_count => 2)
1735 relation = create(:relation)
1737 # create a changeset to establish our initial edit time
1738 changeset = create(:changeset, :user => user,
1739 :created_at => Time.now.utc - 28.days)
1741 # create changeset to put us near the maximum rate limit
1742 remaining_num_changes = Settings.max_changes_per_hour - 2
1744 while remaining_num_changes.positive?
1745 num_changes = [remaining_num_changes, Changeset::MAX_ELEMENTS].min
1746 changeset = create(:changeset, :user => user,
1747 :created_at => Time.now.utc - 5.minutes,
1748 :num_changes => num_changes,
1749 :num_created_nodes => num_changes)
1750 remaining_num_changes -= num_changes
1756 <node id='-1' lon='0' lat='0' changeset='#{changeset.id}'>
1757 <tag k='foo' v='bar'/>
1758 <tag k='baz' v='bat'/>
1760 <way id='-1' changeset='#{changeset.id}'>
1761 <nd ref='#{node.id}'/>
1765 <relation id='-1' changeset='#{changeset.id}'>
1766 <member type='way' role='some' ref='#{way.id}'/>
1767 <member type='node' role='some' ref='#{node.id}'/>
1768 <member type='relation' role='some' ref='#{relation.id}'/>
1774 auth_header = bearer_authorization_header user
1776 post api_changeset_upload_path(changeset), :params => diff, :headers => auth_header
1778 assert_response :too_many_requests, "upload did not hit rate limit"
1781 assert_equal num_changes, changeset.num_changes
1782 assert_predicate changeset, :num_type_changes_in_sync?
1785 def test_upload_initial_size_limit
1786 user = create(:user)
1788 # create a changeset that puts us near the initial size limit
1789 changeset = create(:changeset, :user => user,
1790 :min_lat => (-0.5 * GeoRecord::SCALE).round, :min_lon => (0.5 * GeoRecord::SCALE).round,
1791 :max_lat => (0.5 * GeoRecord::SCALE).round, :max_lon => (2.5 * GeoRecord::SCALE).round)
1796 <node id='-1' lon='0.9' lat='2.9' changeset='#{changeset.id}'>
1797 <tag k='foo' v='bar'/>
1798 <tag k='baz' v='bat'/>
1804 auth_header = bearer_authorization_header user
1806 post api_changeset_upload_path(changeset), :params => diff, :headers => auth_header
1808 assert_response :payload_too_large, "upload did not hit size limit"
1810 assert_no_changes_in changeset
1813 def test_upload_size_limit_after_one_week
1814 user = create(:user)
1816 # create a changeset to establish our initial edit time
1817 create(:changeset, :user => user, :created_at => Time.now.utc - 7.days)
1819 # create a changeset that puts us near the initial size limit
1820 changeset = create(:changeset, :user => user, :bbox => [0.5, -0.5, 2.5, 0.5])
1825 <node id='-1' lon='35' lat='35' changeset='#{changeset.id}'>
1826 <tag k='foo' v='bar'/>
1827 <tag k='baz' v='bat'/>
1833 auth_header = bearer_authorization_header user
1835 post api_changeset_upload_path(changeset), :params => diff, :headers => auth_header
1837 assert_response :payload_too_large, "upload did not hit size limit"
1839 assert_no_changes_in changeset
1844 def check_upload_results_in_not_found(&)
1845 changeset = create(:changeset)
1846 diff = "<osmChange>#{yield changeset}</osmChange>"
1847 auth_header = bearer_authorization_header changeset.user
1849 post api_changeset_upload_path(changeset), :params => diff, :headers => auth_header
1851 assert_response :not_found
1853 assert_no_changes_in changeset
1856 def assert_no_changes_in(changeset)
1858 assert_equal 0, changeset.num_changes
1859 assert_predicate changeset, :num_type_changes_in_sync?