From: Tom Hughes Date: Sat, 28 Feb 2015 00:45:56 +0000 (+0000) Subject: More work on test coverage X-Git-Tag: live~4202 X-Git-Url: https://git.openstreetmap.org/rails.git/commitdiff_plain/857f0f460b3cee78454519f9764a4091204bc1a6?hp=9ec625e352fded4b12a36eb59920776e03e35846;ds=sidebyside More work on test coverage --- diff --git a/app/controllers/amf_controller.rb b/app/controllers/amf_controller.rb index d7364d106..210d3c8a4 100644 --- a/app/controllers/amf_controller.rb +++ b/app/controllers/amf_controller.rb @@ -621,7 +621,7 @@ class AmfController < ApplicationController return -1, t("application.setup_user_auth.blocked") if user.blocks.active.exists? return -1, "You must accept the contributor terms before you can edit." if REQUIRE_TERMS_AGREED && user.terms_agreed.nil? - return -2, "Server error - way is only #{points.length} points long." if pointlist.length < 2 + return -2, "Server error - way is only #{pointlist.length} points long." if pointlist.length < 2 return -1, "One of the tags is invalid. Linux users may need to upgrade to Flash Player 10.1." unless tags_ok(attributes) attributes = strip_non_xml_chars attributes @@ -738,7 +738,11 @@ class AmfController < ApplicationController new_node = nil Node.transaction do if id > 0 - node = Node.find(id) + begin + node = Node.find(id) + rescue ActiveRecord::RecordNotFound + return [-4, "node", id] + end unless visible || node.ways.empty? return -1, "Point #{id} has since become part of a way, so you cannot save it as a POI.", id, id, version @@ -782,14 +786,16 @@ class AmfController < ApplicationController def getpoi(id, timestamp) #:doc: amf_handle_error("'getpoi' #{id}", "node", id) do id = id.to_i - n = Node.find(id) - v = n.version - unless timestamp == "" - n = OldNode.where("node_id = ? AND timestamp <= ?", id, timestamp).unredacted.order("timestamp DESC").first + n = Node.where(:id => id).first + if n + v = n.version + unless timestamp == "" + n = OldNode.where("node_id = ? AND timestamp <= ?", id, timestamp).unredacted.order("timestamp DESC").first + end end if n - return [0, "", n.id, n.lon, n.lat, n.tags, v] + return [0, "", id, n.lon, n.lat, n.tags, v] else return [-4, "node", id] end diff --git a/app/models/trace.rb b/app/models/trace.rb index 994bafcf1..601a4506f 100644 --- a/app/models/trace.rb +++ b/app/models/trace.rb @@ -102,6 +102,7 @@ class Trace < ActiveRecord::Base gzipped = filetype =~ /gzip compressed/ bzipped = filetype =~ /bzip2 compressed/ zipped = filetype =~ /Zip archive/ + tarred = filetype =~ /tar archive/ if gzipped mimetype = "application/x-gzip" @@ -109,6 +110,8 @@ class Trace < ActiveRecord::Base mimetype = "application/x-bzip2" elsif zipped mimetype = "application/x-zip" + elsif tarred + mimetype = "application/x-tar" else mimetype = "application/gpx+xml" end @@ -238,7 +241,7 @@ class Trace < ActiveRecord::Base elsif bzipped system("bunzip2 -c #{trace_name} > #{tmpfile.path}") elsif zipped - system("unzip -p #{trace_name} -x '__MACOSX/*' > #{tmpfile.path}") + system("unzip -p #{trace_name} -x '__MACOSX/*' > #{tmpfile.path} 2> /dev/null") end tmpfile.unlink @@ -260,12 +263,8 @@ class Trace < ActiveRecord::Base f_lon = 0 first = true - # If there are any existing points for this trace then delete - # them - we check for existing points first to avoid locking - # the table in the common case where there aren't any. - if Tracepoint.where(:gpx_id => id).exists? - Tracepoint.delete_all(:gpx_id => id) - end + # If there are any existing points for this trace then delete them + Tracepoint.delete_all(:gpx_id => id) gpx.points do |point| if first diff --git a/test/controllers/amf_controller_test.rb b/test/controllers/amf_controller_test.rb index fb506ee14..371319c23 100644 --- a/test/controllers/amf_controller_test.rb +++ b/test/controllers/amf_controller_test.rb @@ -18,6 +18,28 @@ class AmfControllerTest < ActionController::TestCase ) end + def test_getpresets + amf_content "getpresets", "/1", ["test@example.com:test", ""] + post :amf_read + assert_response :success + amf_parse_response + presets = amf_result("/1") + + assert_equal 15, presets.length + assert_equal POTLATCH_PRESETS[0], presets[0] + assert_equal POTLATCH_PRESETS[1], presets[1] + assert_equal POTLATCH_PRESETS[2], presets[2] + assert_equal POTLATCH_PRESETS[3], presets[3] + assert_equal POTLATCH_PRESETS[4], presets[4] + assert_equal POTLATCH_PRESETS[5], presets[5] + assert_equal POTLATCH_PRESETS[6], presets[6] + assert_equal POTLATCH_PRESETS[7], presets[7] + assert_equal POTLATCH_PRESETS[8], presets[8] + assert_equal POTLATCH_PRESETS[9], presets[9] + assert_equal POTLATCH_PRESETS[10], presets[10] + assert_equal POTLATCH_PRESETS[12], presets[12] + end + def test_getway # check a visible way id = current_ways(:visible_way).id @@ -409,8 +431,192 @@ class AmfControllerTest < ActionController::TestCase assert history[2].empty? end + def test_findgpx_bad_user + amf_content "findgpx", "/1", [1, "test@example.com:wrong"] + post :amf_read + assert_response :success + amf_parse_response + result = amf_result("/1") + + assert_equal 2, result.length + assert_equal -1, result[0] + assert_match /must be logged in/, result[1] + + amf_content "findgpx", "/1", [1, "blocked@openstreetmap.org:test"] + post :amf_read + assert_response :success + amf_parse_response + result = amf_result("/1") + + assert_equal 2, result.length + assert_equal -1, result[0] + assert_match /access to the API has been blocked/, result[1] + end + + def test_findgpx_by_id + trace = gpx_files(:anon_trace_file) + + amf_content "findgpx", "/1", [trace.id, "test@example.com:test"] + post :amf_read + assert_response :success + amf_parse_response + result = amf_result("/1") + + assert_equal 3, result.length + assert_equal 0, result[0] + assert_equal "", result[1] + traces = result[2] + assert_equal 1, traces.length + assert_equal 3, traces[0].length + assert_equal trace.id, traces[0][0] + assert_equal trace.name, traces[0][1] + assert_equal trace.description, traces[0][2] + end + + def test_findgpx_by_name + amf_content "findgpx", "/1", ["Trace", "test@example.com:test"] + post :amf_read + assert_response :success + amf_parse_response + result = amf_result("/1") + + # find by name fails as it uses mysql text search syntax... + assert_equal 2, result.length + assert_equal -2, result[0] + end + + def test_findrelations_by_id + relation = current_relations(:relation_with_versions) + + amf_content "findrelations", "/1", [relation.id] + post :amf_read + assert_response :success + amf_parse_response + result = amf_result("/1") + + assert_equal 1, result.length + assert_equal 4, result[0].length + assert_equal relation.id, result[0][0] + assert_equal relation.tags, result[0][1] + assert_equal relation.members, result[0][2] + assert_equal relation.version, result[0][3] + + amf_content "findrelations", "/1", [999999] + post :amf_read + assert_response :success + amf_parse_response + result = amf_result("/1") + + assert_equal 0, result.length + end + + def test_findrelations_by_tags + visible_relation = current_relations(:visible_relation) + used_relation = current_relations(:used_relation) + + amf_content "findrelations", "/1", ["yes"] + post :amf_read + assert_response :success + amf_parse_response + result = amf_result("/1").sort + + assert_equal 2, result.length + assert_equal 4, result[0].length + assert_equal visible_relation.id, result[0][0] + assert_equal visible_relation.tags, result[0][1] + assert_equal visible_relation.members, result[0][2] + assert_equal visible_relation.version, result[0][3] + assert_equal 4, result[1].length + assert_equal used_relation.id, result[1][0] + assert_equal used_relation.tags, result[1][1] + assert_equal used_relation.members, result[1][2] + assert_equal used_relation.version, result[1][3] + + amf_content "findrelations", "/1", ["no"] + post :amf_read + assert_response :success + amf_parse_response + result = amf_result("/1").sort + + assert_equal 0, result.length + end + + def test_getpoi_without_timestamp + node = current_nodes(:node_with_versions) + + amf_content "getpoi", "/1", [node.id, ""] + post :amf_read + assert_response :success + amf_parse_response + result = amf_result("/1") + + assert_equal 7, result.length + assert_equal 0, result[0] + assert_equal "", result[1] + assert_equal node.id, result[2] + assert_equal node.lon, result[3] + assert_equal node.lat, result[4] + assert_equal node.tags, result[5] + assert_equal node.version, result[6] + + amf_content "getpoi", "/1", [999999, ""] + post :amf_read + assert_response :success + amf_parse_response + result = amf_result("/1") + + assert_equal 3, result.length + assert_equal -4, result[0] + assert_equal "node", result[1] + assert_equal 999999, result[2] + end + + def test_getpoi_with_timestamp + node = nodes(:node_with_versions_v2) + current_node = current_nodes(:node_with_versions) + + amf_content "getpoi", "/1", [node.node_id, node.timestamp.xmlschema] + post :amf_read + assert_response :success + amf_parse_response + result = amf_result("/1") + + assert_equal 7, result.length + assert_equal 0, result[0] + assert_equal "", result[1] + assert_equal node.node_id, result[2] + assert_equal node.lon, result[3] + assert_equal node.lat, result[4] + assert_equal node.tags, result[5] + assert_equal current_node.version, result[6] + + amf_content "getpoi", "/1", [node.node_id, "2000-01-01T00:00:00Z"] + post :amf_read + assert_response :success + amf_parse_response + result = amf_result("/1") + + assert_equal 3, result.length + assert_equal -4, result[0] + assert_equal "node", result[1] + assert_equal node.node_id, result[2] + + amf_content "getpoi", "/1", [999999, Time.now.xmlschema] + post :amf_read + assert_response :success + amf_parse_response + result = amf_result("/1") + + assert_equal 3, result.length + assert_equal -4, result[0] + assert_equal "node", result[1] + assert_equal 999999, result[2] + end + # ************************************************************ # AMF Write tests + + # check that we can update a poi def test_putpoi_update_valid nd = current_nodes(:visible_node) cs_id = changesets(:public_user_first_change).id @@ -420,6 +626,7 @@ class AmfControllerTest < ActionController::TestCase amf_parse_response result = amf_result("/1") + assert_equal 5, result.size assert_equal 0, result[0] assert_equal "", result[1] assert_equal nd.id, result[2] @@ -435,6 +642,7 @@ class AmfControllerTest < ActionController::TestCase amf_parse_response result = amf_result("/2") + assert_equal 5, result.size assert_equal 0, result[0] assert_equal "", result[1] assert_equal nd.id, result[2] @@ -584,16 +792,118 @@ class AmfControllerTest < ActionController::TestCase assert_equal "One of the tags is invalid. Linux users may need to upgrade to Flash Player 10.1.", result[1] end + # try deleting a node def test_putpoi_delete_valid + nd = current_nodes(:visible_node) + cs_id = changesets(:public_user_first_change).id + amf_content "putpoi", "/1", ["test@example.com:test", cs_id, nd.version, nd.id, nd.lon, nd.lat, nd.tags, false] + post :amf_write + assert_response :success + amf_parse_response + result = amf_result("/1") + + assert_equal 5, result.size + assert_equal 0, result[0] + assert_equal "", result[1] + assert_equal nd.id, result[2] + assert_equal nd.id, result[3] + assert_equal nd.version + 1, result[4] + + current_node = Node.find(result[3].to_i) + assert_equal false, current_node.visible end + # try deleting a node that is already deleted def test_putpoi_delete_already_deleted + nd = current_nodes(:invisible_node) + cs_id = changesets(:public_user_first_change).id + amf_content "putpoi", "/1", ["test@example.com:test", cs_id, nd.version, nd.id, nd.lon, nd.lat, nd.tags, false] + post :amf_write + assert_response :success + amf_parse_response + result = amf_result("/1") + + assert_equal 3, result.size + assert_equal -4, result[0] + assert_equal "node", result[1] + assert_equal nd.id, result[2] end + # try deleting a node that has never existed def test_putpoi_delete_not_found + cs_id = changesets(:public_user_first_change).id + amf_content "putpoi", "/1", ["test@example.com:test", cs_id, 1, 999999, 0, 0, {}, false] + post :amf_write + assert_response :success + amf_parse_response + result = amf_result("/1") + + assert_equal 3, result.size + assert_equal -4, result[0] + assert_equal "node", result[1] + assert_equal 999999, result[2] end + # try setting an invalid location on a node def test_putpoi_invalid_latlon + nd = current_nodes(:visible_node) + cs_id = changesets(:public_user_first_change).id + amf_content "putpoi", "/1", ["test@example.com:test", cs_id, nd.version, nd.id, 200, 100, nd.tags, true] + post :amf_write + assert_response :success + amf_parse_response + result = amf_result("/1") + + assert_equal 2, result.size + assert_equal -2, result[0] + assert_match /Node is not in the world/, result[1] + end + + # check that we can update way + def test_putway_update_valid + way = current_ways(:way_with_multiple_nodes) + cs_id = changesets(:public_user_first_change).id + amf_content "putway", "/1", ["test@example.com:test", cs_id, way.version, way.id, way.nds, { "test" => "ok" }, [], {}] + post :amf_write + assert_response :success + amf_parse_response + result = amf_result("/1") + + assert_equal 8, result.size + assert_equal 0, result[0] + assert_equal "", result[1] + assert_equal way.id, result[2] + assert_equal way.id, result[3] + assert_equal({}, result[4]) + assert_equal way.version + 1, result[5] + assert_equal({}, result[6]) + assert_equal({}, result[7]) + + new_way = Way.find(way.id) + assert_equal way.version + 1, new_way.version + assert_equal way.nds, new_way.nds + assert_equal({ "test" => "ok" }, new_way.tags) + + amf_content "putway", "/1", ["test@example.com:test", cs_id, way.version + 1, way.id, [4, 6, 15, 1], way.tags, [], {}] + post :amf_write + assert_response :success + amf_parse_response + result = amf_result("/1") + + assert_equal 8, result.size + assert_equal 0, result[0] + assert_equal "", result[1] + assert_equal way.id, result[2] + assert_equal way.id, result[3] + assert_equal({}, result[4]) + assert_equal way.version + 2, result[5] + assert_equal({}, result[6]) + assert_equal({}, result[7]) + + new_way = Way.find(way.id) + assert_equal way.version + 2, new_way.version + assert_equal [4, 6, 15, 1], new_way.nds + assert_equal way.tags, new_way.tags end def test_startchangeset_invalid_xmlchar_comment @@ -614,6 +924,8 @@ class AmfControllerTest < ActionController::TestCase assert_equal "foobar", cs.tags["comment"] end + private + # ************************************************************ # AMF Helper functions diff --git a/test/fixtures/gpx_files.yml b/test/fixtures/gpx_files.yml index 6e082d24d..14c5c5497 100644 --- a/test/fixtures/gpx_files.yml +++ b/test/fixtures/gpx_files.yml @@ -10,7 +10,7 @@ public_trace_file: visibility: "public" description: This is a trace inserted: true - + anon_trace_file: id: 2 user_id: 2 @@ -62,3 +62,55 @@ deleted_trace_file: visibility: "public" description: This is a trace that has been deleted. inserted: true + +zipped_trace_file: + id: 6 + user_id: 4 + visible: true + name: Zipped Trace.gpx + size: + latitude: 1 + longitude: 1 + timestamp: "2008-10-29 10:10:10" + visibility: "private" + description: This is a zipped trace + inserted: true + +tar_trace_file: + id: 7 + user_id: 4 + visible: true + name: Tarred Trace.gpx + size: + latitude: 1 + longitude: 1 + timestamp: "2008-10-29 10:10:10" + visibility: "private" + description: This is a tarred trace + inserted: true + +tar_gzip_trace_file: + id: 8 + user_id: 4 + visible: true + name: Gzipped Tarred Trace.gpx + size: + latitude: 1 + longitude: 1 + timestamp: "2008-10-29 10:10:10" + visibility: "private" + description: This is a gzipped tarred trace + inserted: true + +tar_bzip_trace_file: + id: 9 + user_id: 4 + visible: true + name: Bzipped Tarred Trace.gpx + size: + latitude: 1 + longitude: 1 + timestamp: "2008-10-29 10:10:10" + visibility: "private" + description: This is a bzipped tarred trace + inserted: true diff --git a/test/models/trace_test.rb b/test/models/trace_test.rb index ed1dbc862..4be160959 100644 --- a/test/models/trace_test.rb +++ b/test/models/trace_test.rb @@ -1,4 +1,5 @@ require "test_helper" +require "digest" class TraceTest < ActiveSupport::TestCase api_fixtures @@ -14,21 +15,34 @@ class TraceTest < ActiveSupport::TestCase end def test_trace_count - assert_equal 5, Trace.count + assert_equal 9, Trace.count end def test_visible - check_query(Trace.visible, [:public_trace_file, :anon_trace_file, :trackable_trace_file, :identifiable_trace_file]) + check_query(Trace.visible, [ + :public_trace_file, :anon_trace_file, :trackable_trace_file, + :identifiable_trace_file, :zipped_trace_file, :tar_trace_file, + :tar_gzip_trace_file, :tar_bzip_trace_file + ]) end def test_visible_to - check_query(Trace.visible_to(1), [:public_trace_file, :identifiable_trace_file]) - check_query(Trace.visible_to(2), [:public_trace_file, :anon_trace_file, :trackable_trace_file, :identifiable_trace_file]) - check_query(Trace.visible_to(3), [:public_trace_file, :identifiable_trace_file]) + check_query(Trace.visible_to(1), [ + :public_trace_file, :identifiable_trace_file + ]) + check_query(Trace.visible_to(2), [ + :public_trace_file, :anon_trace_file, :trackable_trace_file, + :identifiable_trace_file + ]) + check_query(Trace.visible_to(3), [ + :public_trace_file, :identifiable_trace_file + ]) end def test_visible_to_all - check_query(Trace.visible_to_all, [:public_trace_file, :identifiable_trace_file, :deleted_trace_file]) + check_query(Trace.visible_to_all, [ + :public_trace_file, :identifiable_trace_file, :deleted_trace_file + ]) end def test_tagged @@ -99,6 +113,10 @@ class TraceTest < ActiveSupport::TestCase assert_equal "application/gpx+xml", gpx_files(:anon_trace_file).mime_type assert_equal "application/x-bzip2", gpx_files(:trackable_trace_file).mime_type assert_equal "application/x-gzip", gpx_files(:identifiable_trace_file).mime_type + assert_equal "application/x-zip", gpx_files(:zipped_trace_file).mime_type + assert_equal "application/x-tar", gpx_files(:tar_trace_file).mime_type + assert_equal "application/x-gzip", gpx_files(:tar_gzip_trace_file).mime_type + assert_equal "application/x-bzip2", gpx_files(:tar_bzip_trace_file).mime_type end def test_extension_name @@ -106,13 +124,28 @@ class TraceTest < ActiveSupport::TestCase assert_equal ".gpx", gpx_files(:anon_trace_file).extension_name assert_equal ".gpx.bz2", gpx_files(:trackable_trace_file).extension_name assert_equal ".gpx.gz", gpx_files(:identifiable_trace_file).extension_name + assert_equal ".zip", gpx_files(:zipped_trace_file).extension_name + assert_equal ".tar", gpx_files(:tar_trace_file).extension_name + assert_equal ".tar.gz", gpx_files(:tar_gzip_trace_file).extension_name + assert_equal ".tar.bz2", gpx_files(:tar_bzip_trace_file).extension_name + end + + def test_xml_file + assert_equal "848caa72f2f456d1bd6a0fdf228aa1b9", md5sum(gpx_files(:public_trace_file).xml_file) + assert_equal "66179ca44f1e93d8df62e2b88cbea732", md5sum(gpx_files(:anon_trace_file).xml_file) + assert_equal "848caa72f2f456d1bd6a0fdf228aa1b9", md5sum(gpx_files(:trackable_trace_file).xml_file) + assert_equal "abd6675fdf3024a84fc0a1deac147c0d", md5sum(gpx_files(:identifiable_trace_file).xml_file) + assert_equal "848caa72f2f456d1bd6a0fdf228aa1b9", md5sum(gpx_files(:zipped_trace_file).xml_file) + assert_equal "848caa72f2f456d1bd6a0fdf228aa1b9", md5sum(gpx_files(:tar_trace_file).xml_file) + assert_equal "848caa72f2f456d1bd6a0fdf228aa1b9", md5sum(gpx_files(:tar_gzip_trace_file).xml_file) + assert_equal "848caa72f2f456d1bd6a0fdf228aa1b9", md5sum(gpx_files(:tar_bzip_trace_file).xml_file) end private def check_query(query, traces) - traces = traces.map { |t| gpx_files(t) }.sort - assert_equal traces, query.order(:id) + traces = traces.map { |t| gpx_files(t).id }.sort + assert_equal traces, query.order(:id).ids end def trace_valid(attrs, result = true) @@ -120,4 +153,8 @@ class TraceTest < ActiveSupport::TestCase entry.assign_attributes(attrs) assert_equal result, entry.valid?, "Expected #{attrs.inspect} to be #{result}" end + + def md5sum(io) + io.each_with_object(Digest::MD5.new) { |l, d| d.update(l) }.hexdigest + end end