Merge remote-tracking branch 'upstream/pull/1614'

This commit is contained in:
Tom Hughes 2017-08-30 21:09:32 +01:00
commit f1faffd4d1
3 changed files with 29 additions and 24 deletions

View file

@ -263,15 +263,7 @@ class TraceController < ApplicationController
trace = Trace.visible.find(params[:id]) trace = Trace.visible.find(params[:id])
if trace.user == current_user if trace.user == current_user
new_trace = Trace.from_xml(request.raw_post) trace.update_from_xml(request.raw_post)
unless new_trace && new_trace.id == trace.id
raise OSM::APIBadUserInput.new("The id in the url (#{trace.id}) is not the same as provided in the xml (#{new_trace.id})")
end
trace.description = new_trace.description
trace.tags = new_trace.tags
trace.visibility = new_trace.visibility
trace.save! trace.save!
head :ok head :ok

View file

@ -172,13 +172,12 @@ class Trace < ActiveRecord::Base
el1 el1
end end
# Read in xml as text and return it's Node object representation def update_from_xml(xml, create = false)
def self.from_xml(xml, create = false)
p = XML::Parser.string(xml, :options => XML::Parser::Options::NOERROR) p = XML::Parser.string(xml, :options => XML::Parser::Options::NOERROR)
doc = p.parse doc = p.parse
doc.find("//osm/gpx_file").each do |pt| doc.find("//osm/gpx_file").each do |pt|
return Trace.from_xml_node(pt, create) return update_from_xml_node(pt, create)
end end
raise OSM::APIBadXMLError.new("trace", xml, "XML doesn't contain an osm/gpx_file element.") raise OSM::APIBadXMLError.new("trace", xml, "XML doesn't contain an osm/gpx_file element.")
@ -186,34 +185,31 @@ class Trace < ActiveRecord::Base
raise OSM::APIBadXMLError.new("trace", xml, ex.message) raise OSM::APIBadXMLError.new("trace", xml, ex.message)
end end
def self.from_xml_node(pt, create = false) def update_from_xml_node(pt, create = false)
trace = Trace.new
raise OSM::APIBadXMLError.new("trace", pt, "visibility missing") if pt["visibility"].nil? raise OSM::APIBadXMLError.new("trace", pt, "visibility missing") if pt["visibility"].nil?
trace.visibility = pt["visibility"] self.visibility = pt["visibility"]
unless create unless create
raise OSM::APIBadXMLError.new("trace", pt, "ID is required when updating.") if pt["id"].nil? raise OSM::APIBadXMLError.new("trace", pt, "ID is required when updating.") if pt["id"].nil?
trace.id = pt["id"].to_i id = pt["id"].to_i
# .to_i will return 0 if there is no number that can be parsed. # .to_i will return 0 if there is no number that can be parsed.
# We want to make sure that there is no id with zero anyway # We want to make sure that there is no id with zero anyway
raise OSM::APIBadUserInput.new("ID of trace cannot be zero when updating.") if trace.id.zero? raise OSM::APIBadUserInput.new("ID of trace cannot be zero when updating.") if id.zero?
raise OSM::APIBadUserInput.new("The id in the url (#{self.id}) is not the same as provided in the xml (#{id})") unless self.id == id
end end
# We don't care about the time, as it is explicitly set on create/update/delete # We don't care about the time, as it is explicitly set on create/update/delete
# We don't care about the visibility as it is implicit based on the action # We don't care about the visibility as it is implicit based on the action
# and set manually before the actual delete # and set manually before the actual delete
trace.visible = true self.visible = true
description = pt.find("description").first description = pt.find("description").first
raise OSM::APIBadXMLError.new("trace", pt, "description missing") if description.nil? raise OSM::APIBadXMLError.new("trace", pt, "description missing") if description.nil?
trace.description = description.content self.description = description.content
pt.find("tag").each do |tag| self.tags = pt.find("tag").collect do |tag|
trace.tags.build(:tag => tag.content) Tracetag.new(:tag => tag.content)
end end
trace
end end
def xml_file def xml_file

View file

@ -931,6 +931,23 @@ class TraceControllerTest < ActionController::TestCase
assert_equal nt.visibility, t.visibility assert_equal nt.visibility, t.visibility
end end
# Test that updating a trace doesn't duplicate the tags
def test_api_update_tags
tracetag = create(:tracetag)
trace = tracetag.trace
basic_authorization trace.user.display_name, "test"
content trace.to_xml
put :api_update, :params => { :id => trace.id }
assert_response :success
updated = Trace.find(trace.id)
# Ensure there's only one tag in the database after updating
assert_equal Tracetag.count, 1
# The new tag object might have a different id, so check the string representation
assert_equal trace.tagstring, updated.tagstring
end
# Check deleting a trace through the api # Check deleting a trace through the api
def test_api_delete def test_api_delete
public_trace_file = create(:trace, :visibility => "public") public_trace_file = create(:trace, :visibility => "public")