Style/Tab:
Enabled: false
-# Offense count: 6
-# Cop supports --auto-correct.
-# Configuration parameters: EnforcedStyle, SupportedStyles.
-Style/TrailingBlankLines:
- Enabled: false
-
# Offense count: 4
# Cop supports --auto-correct.
# Configuration parameters: EnforcedStyleForMultiline, SupportedStyles.
Style/TrailingComma:
Enabled: false
-# Offense count: 1052
-# Cop supports --auto-correct.
-Style/TrailingWhitespace:
- Enabled: false
-
# Offense count: 13
# Cop supports --auto-correct.
# Configuration parameters: ExactNameMatch, AllowPredicates, AllowDSLWriters, Whitelist.
Vagrant.configure("2") do |config|
config.vm.box = "precise64"
config.vm.box_url = "http://files.vagrantup.com/precise64.box"
-
+
# port forward for webrick on 3000
config.vm.network :forwarded_port, guest: 3000, host: 3000
-# amf_controller is a semi-standalone API for Flash clients, particularly
-# Potlatch. All interaction between Potlatch (as a .SWF application) and the
-# OSM database takes place using this controller. Messages are
+# amf_controller is a semi-standalone API for Flash clients, particularly
+# Potlatch. All interaction between Potlatch (as a .SWF application) and the
+# OSM database takes place using this controller. Messages are
# encoded in the Actionscript Message Format (AMF).
#
# Helper functions are in /lib/potlatch.rb
# == General structure
#
# Apart from the amf_read and amf_write methods (which distribute the requests
-# from the AMF message), each method generally takes arguments in the order
-# they were sent by the Potlatch SWF. Do not assume typing has been preserved.
+# from the AMF message), each method generally takes arguments in the order
+# they were sent by the Potlatch SWF. Do not assume typing has been preserved.
# Methods all return an array to the SWF.
#
# == API 0.6
#
# Note that this requires a patched version of composite_primary_keys 1.1.0
-# (see http://groups.google.com/group/compositekeys/t/a00e7562b677e193)
+# (see http://groups.google.com/group/compositekeys/t/a00e7562b677e193)
# if you are to run with POTLATCH_USE_SQL=false .
-#
+#
# == Debugging
-#
+#
# Any method that returns a status code (0 for ok) can also send:
# return(-1,"message") <-- just puts up a dialogue
# return(-2,"message") <-- also asks the user to e-mail me
# return(-3,["type",v],id) <-- version conflict
# return(-4,"type",id) <-- object not found
# -5 indicates the method wasn't called (due to a previous error)
-#
+#
# To write to the Rails log, use logger.info("message").
# Remaining issues:
# Main AMF handlers: process the raw AMF string (using AMF library) and
# calls each action (private method) accordingly.
-
+
def amf_read
self.status = :ok
self.content_type = Mime::AMF
when 'findrelations'; result = findrelations(*args)
when 'getpoi'; result = getpoi(*args)
end
-
+
result
end
end
# Start new changeset
# Returns success_code,success_message,changeset id
-
+
def startchangeset(usertoken, cstags, closeid, closecomment, opennew)
amf_handle_error("'startchangeset'",nil,nil) do
user = getuser(usertoken)
cs.save_with_tags!
end
end
-
+
# open a new changeset
if opennew!=0
cs = Changeset.new
cs.tags = cstags
cs.user_id = user.id
- if !closecomment.empty?
- cs.tags['comment']=closecomment
+ if !closecomment.empty?
+ cs.tags['comment']=closecomment
# in case closecomment has chars not allowed in xml
cs.tags = strip_non_xml_chars cs.tags
end
##
# Find all the ways, POI nodes (i.e. not part of ways), and relations
- # in a given bounding box. Nodes are returned in full; ways and relations
- # are IDs only.
+ # in a given bounding box. Nodes are returned in full; ways and relations
+ # are IDs only.
#
- # return is of the form:
+ # return is of the form:
# [success_code, success_message,
# [[way_id, way_version], ...],
# [[node_id, lat, lon, [tags, ...], node_version], ...],
else
# find the way ids in an area
nodes_in_area = Node.bbox(bbox).visible.includes(:ways)
- ways = nodes_in_area.inject([]) { |sum, node|
+ ways = nodes_in_area.inject([]) { |sum, node|
visible_ways = node.ways.select { |w| w.visible? }
sum + visible_ways.collect { |w| [w.id,w.version] }
}.uniq
[0, '', wayid, points, tags, version, uid]
end
end
-
+
# Get an old version of a way, and all constituent nodes.
#
- # For undelete (version<0), always uses the most recent version of each node,
- # even if it's moved. For revert (version >= 0), uses the node in existence
+ # For undelete (version<0), always uses the most recent version of each node,
+ # even if it's moved. For revert (version >= 0), uses the node in existence
# at the time, generating a new id if it's still visible and has been moved/
# retagged.
#
# Returns:
- # 0. success code,
- # 1. id,
- # 2. array of points,
- # 3. hash of tags,
- # 4. version,
+ # 0. success code,
+ # 1. id,
+ # 2. array of points,
+ # 3. hash of tags,
+ # 4. version,
# 5. is this the current, visible version? (boolean)
-
+
def getway_old(id, timestamp) #:doc:
amf_handle_error_with_timeout("'getway_old' #{id}, #{timestamp}", 'way',id) do
if timestamp == ''
end
end
end
-
+
# Find history of a way.
# Returns 'way', id, and an array of previous versions:
# - formerly [old_way.version, old_way.timestamp.strftime("%d %b %Y, %H:%M"), old_way.visible ? 1 : 0, user, uid]
# - now [timestamp,user,uid]
#
- # Heuristic: Find all nodes that have ever been part of the way;
+ # Heuristic: Find all nodes that have ever been part of the way;
# get a list of their revision dates; add revision dates of the way;
- # sort and collapse list (to within 2 seconds); trim all dates before the
+ # sort and collapse list (to within 2 seconds); trim all dates before the
# start date of the way.
def getway_history(wayid) #:doc:
return ['way', wayid, []]
end
end
-
+
# Find history of a node. Returns 'node', id, and an array of previous versions as above.
def getnode_history(nodeid) #:doc:
- begin
+ begin
history = Node.find(nodeid).old_nodes.unredacted.reverse.collect do |old_node|
[(old_node.timestamp + 1).strftime("%d %b %Y, %H:%M:%S")] + change_user(old_node)
end
# Find GPS traces with specified name/id.
# Returns array listing GPXs, each one comprising id, name and description.
-
+
def findgpx(searchterm, usertoken)
amf_handle_error_with_timeout("'findgpx'" ,nil,nil) do
user = getuser(usertoken)
# 3. hash of tags,
# 4. list of members,
# 5. version.
-
+
def getrelation(relid) #:doc:
amf_handle_error("'getrelation' #{relid}" ,'relation',relid) do
rel = Relation.where(:id => relid).first
# Find relations with specified name/id.
# Returns array of relations, each in same form as getrelation.
-
+
def findrelations(searchterm)
rels = []
if searchterm.to_i>0 then
relation.delete_with_history!(new_relation, user)
end
end # transaction
-
+
if relid <= 0
return [0, '', relid, new_relation.id, new_relation.version]
else
# Save a way to the database, including all nodes. Any nodes in the previous
# version and no longer used are deleted.
- #
+ #
# Parameters:
# 0. hash of renumbered nodes (added by amf_controller)
# 1. current user token (for authentication)
# 6. hash of way tags
# 7. array of nodes to change (each one is [lon,lat,id,version,tags]),
# 8. hash of nodes to delete (id->version).
- #
+ #
# Returns:
# 0. '0' (code for success),
# 1. message,
def putway(renumberednodes, usertoken, changeset_id, wayversion, originalway, pointlist, attributes, nodes, deletednodes) #:doc:
amf_handle_error("'putway' #{originalway}" ,'way',originalway) do
# -- Initialise
-
+
user = getuser(usertoken)
if !user then return -1,"You are not logged in, so the way could not be saved." end
if user.blocks.active.exists? then return -1,t('application.setup_user_auth.blocked') end
new_node.lat = lat
new_node.lon = lon
new_node.tags = tags
- if id <= 0
+ if id <= 0
# We're creating the node
new_node.create_with_history(user)
elsif visible
return [0, '', id, new_node.id, new_node.version]
else
return [0, '', id, node.id, node.version]
- end
+ end
end
end
# * the changeset id
# * the id of the way to change
# * the version of the way that was downloaded
- # * a hash of the id and versions of all the nodes that are in the way, if any
+ # * a hash of the id and versions of all the nodes that are in the way, if any
# of the nodes have been changed by someone else then, there is a problem!
# Returns 0 (success), unchanged way id, new way version, new node versions.
unless user then return -1,"You are not logged in, so the way could not be deleted." end
if user.blocks.active.exists? then return -1,t('application.setup_user_auth.blocked') end
if REQUIRE_TERMS_AGREED and user.terms_agreed.nil? then return -1,"You must accept the contributor terms before you can edit." end
-
+
way_id = way_id.to_i
nodeversions = {}
old_way=nil # returned, so scope it outside the transaction
# Authenticate token
# (can also be of form user:pass)
- # When we are writing to the api, we need the actual user model,
+ # When we are writing to the api, we need the actual user model,
# not just the id, hence this abstraction
def getuser(token) #:doc:
def getlocales
Dir.glob("#{Rails.root}/config/potlatch/locales/*").collect { |f| File.basename(f, ".yml") }
end
-
+
##
# check that all key-value pairs are valid UTF-8.
def tags_ok(tags)
FROM current_way_nodes
INNER JOIN current_nodes ON current_nodes.id=current_way_nodes.node_id
INNER JOIN current_ways ON current_ways.id =current_way_nodes.id
- WHERE current_nodes.visible=TRUE
- AND current_ways.visible=TRUE
+ WHERE current_nodes.visible=TRUE
+ AND current_ways.visible=TRUE
AND #{OSM.sql_for_area(bbox, "current_nodes.")}
EOF
return ActiveRecord::Base.connection.select_all(sql).collect { |a| [a['wayid'].to_i,a['version'].to_i] }
end
-
+
def sql_find_pois_in_area(bbox)
pois=[]
sql=<<-EOF
- SELECT current_nodes.id,current_nodes.latitude*0.0000001 AS lat,current_nodes.longitude*0.0000001 AS lon,current_nodes.version
- FROM current_nodes
- LEFT OUTER JOIN current_way_nodes cwn ON cwn.node_id=current_nodes.id
+ SELECT current_nodes.id,current_nodes.latitude*0.0000001 AS lat,current_nodes.longitude*0.0000001 AS lon,current_nodes.version
+ FROM current_nodes
+ LEFT OUTER JOIN current_way_nodes cwn ON cwn.node_id=current_nodes.id
WHERE current_nodes.visible=TRUE
AND cwn.id IS NULL
AND #{OSM.sql_for_area(bbox, "current_nodes.")}
end
pois
end
-
+
def sql_find_relations_in_area_and_ways(bbox,way_ids)
# ** It would be more Potlatchy to get relations for nodes within ways
# during 'getway', not here
sql=<<-EOF
- SELECT DISTINCT cr.id AS relid,cr.version AS version
+ SELECT DISTINCT cr.id AS relid,cr.version AS version
FROM current_relations cr
- INNER JOIN current_relation_members crm ON crm.id=cr.id
- INNER JOIN current_nodes cn ON crm.member_id=cn.id AND crm.member_type='Node'
+ INNER JOIN current_relation_members crm ON crm.id=cr.id
+ INNER JOIN current_nodes cn ON crm.member_id=cn.id AND crm.member_type='Node'
WHERE #{OSM.sql_for_area(bbox, "cn.")}
EOF
unless way_ids.empty?
SELECT DISTINCT cr.id AS relid,cr.version AS version
FROM current_relations cr
INNER JOIN current_relation_members crm ON crm.id=cr.id
- WHERE crm.member_type='Way'
+ WHERE crm.member_type='Way'
AND crm.member_id IN (#{way_ids.join(',')})
EOF
end
ActiveRecord::Base.connection.select_all(sql).collect { |a| [a['relid'].to_i,a['version'].to_i] }
end
-
+
def sql_get_nodes_in_way(wayid)
points=[]
sql=<<-EOF
- SELECT latitude*0.0000001 AS lat,longitude*0.0000001 AS lon,current_nodes.id,current_nodes.version
- FROM current_way_nodes,current_nodes
- WHERE current_way_nodes.id=#{wayid.to_i}
- AND current_way_nodes.node_id=current_nodes.id
+ SELECT latitude*0.0000001 AS lat,longitude*0.0000001 AS lon,current_nodes.id,current_nodes.version
+ FROM current_way_nodes,current_nodes
+ WHERE current_way_nodes.id=#{wayid.to_i}
+ AND current_way_nodes.node_id=current_nodes.id
AND current_nodes.visible=TRUE
ORDER BY sequence_id
EOF
end
points
end
-
+
def sql_get_tags_in_way(wayid)
tags={}
ActiveRecord::Base.connection.select_all("SELECT k,v FROM current_way_tags WHERE id=#{wayid.to_i}").each do |row|
ActiveRecord::Base.connection.select_one("SELECT user FROM current_ways,changesets WHERE current_ways.id=#{wayid.to_i} AND current_ways.changeset=changesets.id")['user']
end
end
-
root['version'] = '1.0'
root['creator'] = 'OpenStreetMap.org'
root['xmlns'] = "http://www.topografix.com/GPX/1/0"
-
+
doc.root = root
# initialise these variables outside of the loop so that they
# use the anonymous track segment if the user hasn't allowed
# their GPX points to be tracked.
timestamps = false
- if anon_track.nil?
+ if anon_track.nil?
anon_track = XML::Node.new 'trk'
doc.root << anon_track
end
track = anon_track
end
end
-
+
if trackid != point.trackid
if gpx_file.trackable?
trkseg = XML::Node.new 'trkseg'
track << trkseg
trackid = point.trackid
else
- if anon_trkseg.nil?
+ if anon_trkseg.nil?
anon_trkseg = XML::Node.new 'trkseg'
anon_track << anon_trkseg
end
render :text => doc.to_s, :content_type => "text/xml"
end
- # This is probably the most common call of all. It is used for getting the
+ # This is probably the most common call of all. It is used for getting the
# OSM data for a specified bounding box, usually for editing. First the
- # bounding box (bbox) is checked to make sure that it is sane. All nodes
+ # bounding box (bbox) is checked to make sure that it is sane. All nodes
# are searched, then all the ways that reference those nodes are found.
# All Nodes that are referenced by those ways are fetched and added to the list
# of nodes.
# Then all the relations that reference the already found nodes and ways are
- # fetched. All the nodes and ways that are referenced by those ways are then
+ # fetched. All the nodes and ways that are referenced by those ways are then
# fetched. Finally all the xml is returned.
def map
# Figure out the bbox
doc.root << way.to_xml_node(visible_nodes, changeset_cache, user_display_name_cache)
way_ids << way.id
end
- end
+ end
relations = Relation.nodes(visible_nodes.keys).visible +
Relation.ways(way_ids).visible
- # we do not normally return the "other" partners referenced by an relation,
- # e.g. if we return a way A that is referenced by relation X, and there's
- # another way B also referenced, that is not returned. But we do make
- # an exception for cases where an relation references another *relation*;
+ # we do not normally return the "other" partners referenced by an relation,
+ # e.g. if we return a way A that is referenced by relation X, and there's
+ # another way B also referenced, that is not returned. But we do make
+ # an exception for cases where an relation references another *relation*;
# in that case we return that as well (but we don't go recursive here)
relations += Relation.relations(relations.collect { |r| r.id }).visible
end
end
- # External apps that use the api are able to query the api to find out some
- # parameters of the API. It currently returns:
+ # External apps that use the api are able to query the api to find out some
+ # parameters of the API. It currently returns:
# * minimum and maximum API versions that can be used.
# * maximum area that can be requested in a bbox request in square degrees
# * number of tracepoints that are returned in each tracepoints page
doc.root << api
policy = XML::Node.new 'policy'
blacklist = XML::Node.new 'imagery'
- IMAGERY_BLACKLIST.each do |url_regex|
+ IMAGERY_BLACKLIST.each do |url_regex|
xnd = XML::Node.new 'blacklist'
xnd['regex'] = url_regex.to_s
blacklist << xnd
end
##
- # requires the user to be logged in by the token or HTTP methods, or have an
- # OAuth token with the right capability. this method is a bit of a pain to call
+ # requires the user to be logged in by the token or HTTP methods, or have an
+ # OAuth token with the right capability. this method is a bit of a pain to call
# directly, since it's cumbersome to call filters with arguments in rails. to
# make it easier to read and write the code, there are some utility methods
# below.
end
end
- def authorize(realm='Web Password', errormessage="Couldn't authenticate you")
+ def authorize(realm='Web Password', errormessage="Couldn't authenticate you")
# make the @user object from any auth sources we have
setup_user_auth
# handle authenticate pass/fail
unless @user
# no auth, the user does not exist or the password was wrong
- response.headers["WWW-Authenticate"] = "Basic realm=\"#{realm}\""
+ response.headers["WWW-Authenticate"] = "Basic realm=\"#{realm}\""
render :text => errormessage, :status => :unauthorized
return false
- end
- end
+ end
+ end
##
# to be used as a before_filter *after* authorize. this checks that
#
# NOTE: this isn't a very good way of doing it - it duplicates logic
# from require_moderator - but what we really need to do is a fairly
- # drastic refactoring based on :format and respond_to? but not a
+ # drastic refactoring based on :format and respond_to? but not a
# good idea to do that in this branch.
- def authorize_moderator(errormessage="Access restricted to moderators")
+ def authorize_moderator(errormessage="Access restricted to moderators")
# check user is a moderator
unless @user.moderator?
render :text => errormessage, :status => :forbidden
return false
- end
- end
+ end
+ end
def check_database_readable(need_api = false)
if STATUS == :database_offline or (need_api and STATUS == :api_offline)
:offline
elsif STATUS == :database_readonly
:readonly
- else
+ else
:online
end
end
# Report and error to the user
# (If anyone ever fixes Rails so it can set a http status "reason phrase",
- # rather than only a status code and having the web engine make up a
+ # rather than only a status code and having the web engine make up a
# phrase from that, we can also put the error message into the status
# message. For now, rails won't let us)
def report_error(message, status = :bad_request)
render :text => message, :status => status, :content_type => "text/plain"
end
end
-
+
def set_locale
response.header['Vary'] = 'Accept-Language'
helper_method :preferred_editor
-private
+private
# extract authorisation credentials from headers, returns user = nil if none
- def get_auth_data
- if request.env.has_key? 'X-HTTP_AUTHORIZATION' # where mod_rewrite might have put it
- authdata = request.env['X-HTTP_AUTHORIZATION'].to_s.split
- elsif request.env.has_key? 'REDIRECT_X_HTTP_AUTHORIZATION' # mod_fcgi
- authdata = request.env['REDIRECT_X_HTTP_AUTHORIZATION'].to_s.split
+ def get_auth_data
+ if request.env.has_key? 'X-HTTP_AUTHORIZATION' # where mod_rewrite might have put it
+ authdata = request.env['X-HTTP_AUTHORIZATION'].to_s.split
+ elsif request.env.has_key? 'REDIRECT_X_HTTP_AUTHORIZATION' # mod_fcgi
+ authdata = request.env['REDIRECT_X_HTTP_AUTHORIZATION'].to_s.split
elsif request.env.has_key? 'HTTP_AUTHORIZATION' # regular location
authdata = request.env['HTTP_AUTHORIZATION'].to_s.split
- end
+ end
# only basic authentication supported
- if authdata and authdata[0] == 'Basic'
+ if authdata and authdata[0] == 'Basic'
user, pass = Base64.decode64(authdata[1]).split(':',2)
- end
- return [user, pass]
- end
+ end
+ return [user, pass]
+ end
# used by oauth plugin to get the current user
def current_user
class BrowseController < ApplicationController
layout :map_layout
- before_filter :authorize_web
- before_filter :set_locale
+ before_filter :authorize_web
+ before_filter :set_locale
before_filter :except => [ :query ] { |c| c.check_database_readable(true) }
before_filter :require_oauth
around_filter :web_timeout
end
else
@entries = DiaryEntry.joins(:user).where(:users => { :status => ["active", "confirmed"] })
-
+
if params[:language]
@title = t 'diary_entry.list.in_language_title', :language => Language.find(params[:language]).english_name
@entries = @entries.where(:language_code => params[:language])
render :text => "", :status => :gone
end
end
-
+
# Update a node from given XML
def update
node = Node.find(params[:id])
new_node = Node.from_xml(request.raw_post)
-
+
unless new_node and new_node.id == node.id
raise OSM::APIBadUserInput.new("The id in the url (#{node.id}) is not the same as provided in the xml (#{new_node.id})")
end
render :text => node.version.to_s, :content_type => "text/plain"
end
- # Delete a node. Doesn't actually delete it, but retains its history
+ # Delete a node. Doesn't actually delete it, but retains its history
# in a wiki-like way. We therefore treat it like an update, so the delete
# method returns the new version number.
def delete
node = Node.find(params[:id])
new_node = Node.from_xml(request.raw_post)
-
+
unless new_node and new_node.id == node.id
raise OSM::APIBadUserInput.new("The id in the url (#{node.id}) is not the same as provided in the xml (#{new_node.id})")
end
format.xml { render :action => :show }
format.json { render :action => :show }
end
- end
+ end
##
# Reopen a note
format.xml { render :action => :show }
format.json { render :action => :show }
end
- end
+ end
##
# Get a feed of recent notes and comments
##
# Display a list of notes by a specified user
def mine
- if params[:display_name]
+ if params[:display_name]
if @this_user = User.active.find_by_display_name(params[:display_name])
- @title = t 'note.mine.title', :user => @this_user.display_name
- @heading = t 'note.mine.heading', :user => @this_user.display_name
+ @title = t 'note.mine.title', :user => @this_user.display_name
+ @heading = t 'note.mine.heading', :user => @this_user.display_name
@description = t 'note.mine.subheading', :user => render_to_string(:partial => "user", :object => @this_user)
- @page = (params[:page] || 1).to_i
+ @page = (params[:page] || 1).to_i
@page_size = 10
@notes = @this_user.notes.order("updated_at DESC, id").uniq.offset((@page - 1) * @page_size).limit(@page_size).preload(:comments => :author).to_a
else
- @title = t 'user.no_such_user.title'
- @not_found_user = params[:display_name]
+ @title = t 'user.no_such_user.title'
+ @not_found_user = params[:display_name]
- render :template => 'user/no_such_user', :status => :not_found
- end
+ render :template => 'user/no_such_user', :status => :not_found
+ end
end
end
-private
- #------------------------------------------------------------
- # utility functions below.
- #------------------------------------------------------------
-
+private
+ #------------------------------------------------------------
+ # utility functions below.
+ #------------------------------------------------------------
+
##
# Render an OK response
def render_ok
if params[:format] == "js"
- render :text => "osbResponse();", :content_type => "text/javascript"
+ render :text => "osbResponse();", :content_type => "text/javascript"
else
render :text => "ok " + @note.id.to_s + "\n", :content_type => "text/plain" if @note
render :text => "ok\n", :content_type => "text/plain" unless @note
else
closed_since = 7
end
-
+
if closed_since < 0
notes = notes.where("status != 'hidden'")
elsif closed_since > 0
def add_comment(note, text, event, notify = true)
attributes = { :visible => true, :event => event, :body => text }
- if @user
+ if @user
attributes[:author_id] = @user.id
- else
+ else
attributes[:author_ip] = request.remote_ip
end
def history
# the .where() method used in the lookup_old_element_versions
- # call won't throw an error if no records are found, so we have
+ # call won't throw an error if no records are found, so we have
# to do that ourselves.
raise OSM::APINotFoundError.new if @elements.empty?
doc = OSM::API.new.get_xml_doc
-
+
visible_elements = if show_redactions?
@elements
else
visible_elements.each do |element|
doc.root << element.to_xml_node
end
-
+
render :text => doc.to_s, :content_type => "text/xml"
end
-
+
def version
if @old_element.redacted? and not show_redactions?
render :text => "", :status => :forbidden
else
response.last_modified = @old_element.timestamp
-
+
doc = OSM::API.new.get_xml_doc
doc.root << @old_element.to_xml_node
-
+
render :text => doc.to_s, :content_type => "text/xml"
end
end
# be redacted in that redaction.
redaction = Redaction.find(redaction_id.to_i)
@old_element.redact!(redaction)
-
+
else
# if no redaction ID was provided, then this is an unredact
# operation.
@old_element.redact!(nil)
end
-
+
# just return an empty 200 OK for success
render :text => ""
end
private
-
+
def show_redactions?
@user and @user.moderator? and params[:show_redactions] == "true"
end
class OldNodeController < OldController
private
-
+
def lookup_old_element
@old_element = OldNode.find([params[:id], params[:version]])
end
class OldRelationController < OldController
private
-
+
def lookup_old_element
@old_element = OldRelation.find([params[:id], params[:version]])
end
class OldWayController < OldController
private
-
+
def lookup_old_element
@old_element = OldWay.find([params[:id], params[:version]])
end
class RedactionsController < ApplicationController
layout 'site'
-
+
before_filter :authorize_web
before_filter :set_locale
before_filter :require_user, :only => [:new, :create, :edit, :update, :destroy]
def new
@redaction = Redaction.new
end
-
+
def create
@redaction = Redaction.new
@redaction.user = @user
render :action => 'new'
end
end
-
+
def show
end
-
+
def edit
end
-
+
def update
# note - don't update the user ID
@redaction.title = params[:redaction][:title]
render :action => 'edit'
end
end
-
+
def destroy
unless @redaction.old_nodes.empty? and
@redaction.old_ways.empty? and
assert_method :put
relation = Relation.from_xml(request.raw_post, true)
-
- # We assume that an exception has been thrown if there was an error
+
+ # We assume that an exception has been thrown if there was an error
# generating the relation
#if relation
relation.create_with_history @user
relation = Relation.find(params[:id])
new_relation = Relation.from_xml(request.raw_post)
-
+
if new_relation and new_relation.id == relation.id
relation.update_from new_relation, @user
render :text => relation.version.to_s, :content_type => "text/plain"
# -----------------------------------------------------------------
# full
- #
+ #
# input parameters: id
#
# returns XML representation of one relation object plus all its
# -----------------------------------------------------------------
def full
relation = Relation.find(params[:id])
-
+
if relation.visible
-
+
# first find the ids of nodes, ways and relations referenced by this
# relation - note that we exclude this relation just in case.
-
+
node_ids = relation.members.select { |m| m[0] == 'Node' }.map { |m| m[1] }
way_ids = relation.members.select { |m| m[0] == 'Way' }.map { |m| m[1] }
relation_ids = relation.members.select { |m| m[0] == 'Relation' and m[1] != relation.id }.map { |m| m[1] }
-
+
# next load the relations and the ways.
-
+
relations = Relation.where(:id => relation_ids).includes(:relation_tags)
ways = Way.where(:id => way_ids).includes(:way_nodes, :way_tags)
-
- # now additionally collect nodes referenced by ways. Note how we
+
+ # now additionally collect nodes referenced by ways. Note how we
# recursively evaluate ways but NOT relations.
-
+
way_node_ids = ways.collect { |way|
way.way_nodes.collect { |way_node| way_node.node_id }
}
node_ids += way_node_ids.flatten
nodes = Node.where(:id => node_ids.uniq).includes(:node_tags)
-
+
# create XML.
doc = OSM::API.new.get_xml_doc
visible_nodes = {}
visible_members = { "Node" => {}, "Way" => {}, "Relation" => {} }
changeset_cache = {}
user_display_name_cache = {}
-
+
nodes.each do |node|
if node.visible? # should be unnecessary if data is consistent.
doc.root << node.to_xml_node(changeset_cache, user_display_name_cache)
# finally add self and output
doc.root << relation.to_xml_node(visible_members, changeset_cache, user_display_name_cache)
render :text => doc.to_s, :content_type => "text/xml"
-
+
else
render :text => "", :status => :gone
end
# ====================================================================
# Public methods
-
+
# ---- trackpoints compile SWF of trackpoints
- def trackpoints
-
+ def trackpoints
+
# - Initialise
-
+
baselong =params['baselong'].to_f
basey =params['basey'].to_f
masterscale =params['masterscale'].to_f
-
+
bbox = BoundingBox.new(params['xmin'], params['ymin'],
params['xmax'], params['ymax'])
start=params['start'].to_i;
-
+
# - Begin movie
-
+
bounds_left =0
bounds_right =320*20
bounds_bottom=0
absy=0
xl=yb= 9999999
xr=yt=-9999999
-
+
# - Send SQL for GPS tracks
-
+
b=''
lasttime=0
lasttrack=lastfile='-1'
-
+
if params['token']
user=User.authenticate(:token => params[:token])
sql="SELECT gps_points.latitude*0.0000001 AS lat,gps_points.longitude*0.0000001 AS lon,gpx_files.id AS fileid,"+
"LIMIT 10000 OFFSET #{start}"
end
gpslist=ActiveRecord::Base.connection.select_all sql
-
+
# - Draw GPS trace lines
-
+
r=startShape()
gpslist.each do |row|
xs=(long2coord(row['lon'].to_f,baselong,masterscale)*20).floor
r+=[b.slice!(0...80)].pack("B*")
end
end
-
+
# (Unwayed segments removed)
-
+
# - Write shape
-
+
b+=endShape()
r+=[b].pack("B*")
m+=swfRecord(2,packUI16(1) + packRect(xl,xr,yb,yt) + r)
m+=swfRecord(4,packUI16(1) + packUI16(1))
-
+
# - Create Flash header and write to browser
-
+
m+=swfRecord(1,'') # Show frame
m+=swfRecord(0,'') # End
-
+
m=packRect(bounds_left,bounds_right,bounds_bottom,bounds_top) + 0.chr + 12.chr + packUI16(1) + m
m='FWS' + 6.chr + packUI32(m.length+8) + m
-
+
render :text => m, :content_type => "application/x-shockwave-flash"
end
# =======================================================================
# SWF functions
-
+
# -----------------------------------------------------------------------
# Line-drawing
s+=34.chr # 2 fill, 2 line index bits
s
end
-
+
def endShape
'000000'
end
-
+
def startAndMove(x,y,col)
d='001001' # Line style change, moveTo
l =[lengthSB(x),lengthSB(y)].max
d+=sprintf("%05b%0#{l}b%0#{l}b",l,x,y)
d+=col # Select line style
end
-
+
def drawTo(absx,absy,x,y)
dx=x-absx
dy=y-absy
end
d
end
-
+
def drawSection(x1,y1,x2,y2)
d='11' # TypeFlag, EdgeFlag
dx=x2-x1
# -----------------------------------------------------------------------
# Generic pack functions
-
+
def packUI16(n)
[n.floor].pack("v")
end
-
+
def packUI32(n)
[n.floor].pack("V")
end
-
+
# Find number of bits required to store arbitrary-length binary
-
+
def lengthSB(n)
Math.frexp(n+ (n==0?1:0) )[1]+1
end
-
+
# ====================================================================
# Co-ordinate conversion
# (this is duplicated from amf_controller, should probably share)
-
+
def lat2coord(a,basey,masterscale)
-(lat2y(a)-basey)*masterscale
end
-
+
def long2coord(a,baselong,masterscale)
(a-baselong)*masterscale
end
-
+
def lat2y(a)
180/Math::PI * Math.log(Math.tan(Math::PI/4+a*(Math::PI/180)/2))
end
end
def create
- if @valid_params
+ if @valid_params
@user_block = UserBlock.new(
:user_id => @this_user.id,
:creator_id => @user.id,
:ends_at => Time.now.getutc() + @block_period.hours,
:needs_view => params[:user_block][:needs_view]
)
-
+
if @user_block.save
flash[:notice] = t('user_block.create.flash', :name => @this_user.display_name)
redirect_to @user_block
end
end
- def update
- if @valid_params
+ def update
+ if @valid_params
if @user_block.creator_id != @user.id
flash[:error] = t('user_block.update.only_creator_can_edit')
redirect_to :action => "edit"
if !UserBlock::PERIODS.include?(@block_period)
flash[:error] = t('user_block.filter.block_period')
-
+
elsif @user_block and !@user_block.active?
flash[:error] = t('user_block.filter.block_expired')
-
+
else
@valid_params = true
end
def update_one
begin
pref = UserPreference.find([@user.id, params[:preference_key]])
- rescue ActiveRecord::RecordNotFound
+ rescue ActiveRecord::RecordNotFound
pref = UserPreference.new
pref.user = @user
pref.k = params[:preference_key]
end
##
- # require that the given role is valid. the role is a URL
+ # require that the given role is valid. the role is a URL
# parameter, so should always be present.
def require_valid_role
@role = params[:role]
assert_method :put
way = Way.from_xml(request.raw_post, true)
-
+
if way
way.create_with_history @user
render :text => way.id.to_s, :content_type => "text/plain"
def read
way = Way.find(params[:id])
-
+
response.last_modified = way.timestamp
-
+
if way.visible
render :text => way.to_xml.to_s, :content_type => "text/xml"
else
def update
way = Way.find(params[:id])
new_way = Way.from_xml(request.raw_post)
-
+
if new_way and new_way.id == way.id
way.update_from(new_way, @user)
render :text => way.version.to_s, :content_type => "text/plain"
def delete
way = Way.find(params[:id])
new_way = Way.from_xml(request.raw_post)
-
+
if new_way and new_way.id == way.id
way.delete_with_history!(new_way, @user)
render :text => way.version.to_s, :content_type => "text/plain"
def full
way = Way.includes(:nodes => :node_tags).find(params[:id])
-
+
if way.visible
visible_nodes = {}
changeset_cache = {}
end
end
doc.root << way.to_xml_node(visible_nodes, changeset_cache, user_display_name_cache)
-
+
render :text => doc.to_s, :content_type => "text/xml"
else
render :text => "", :status => :gone
end
##
- # returns all the ways which are currently using the node given in the
+ # returns all the ways which are currently using the node given in the
# :id parameter. note that this used to return deleted ways as well, but
# this seemed not to be the expected behaviour, so it was removed.
def ways_for_node
module UserBlocksHelper
##
- # returns a translated string representing the status of the
+ # returns a translated string representing the status of the
# user block (i.e: whether it's active, what the expiry time is)
def block_status(block)
if block.active?
end
else
# the max of the last update time or the ends_at time is when this block finished
- # either because the user viewed the block (updated_at) or it expired or was
+ # either because the user viewed the block (updated_at) or it expired or was
# revoked (ends_at)
last_time = [block.ends_at, block.updated_at].max
I18n.t('user_block.helper.time_past', :time => distance_of_time_in_words_to_now(last_time))
url = grant_role_path(:display_name => user.display_name, :role => role)
confirm = t("user_role.grant.are_you_sure", :name => user.display_name, :role => role)
end
- elsif user.has_role?(role)
+ elsif user.has_role?(role)
image = "roles/#{role}.png"
alt = t("user.view.role.#{role}")
title = t("user.view.role.#{role}")
validates_presence_of :user, :secret
before_create :set_authorized_at
-
-protected
-
+
+protected
+
def set_authorized_at
self.authorized_at = Time.now
end
has_many :old_nodes
has_many :old_ways
has_many :old_relations
-
+
has_many :comments, -> { where(:visible => true).order(:created_at) }, :class_name => "ChangesetComment"
has_and_belongs_to_many :subscribers, :class_name => 'User', :join_table => 'changesets_subscribers', :association_foreign_key => 'subscriber_id'
# suggested on the wiki page by kleptog.
def update_bbox!(bbox_update)
bbox.expand!(bbox_update, EXPAND)
-
+
# update active record. rails 2.1's dirty handling should take care of
# whether this object needs saving or not.
self.min_lon, self.min_lat, self.max_lon, self.max_lat = @bbox.to_a if bbox.complete?
validates_presence_of :author
validates_associated :author
validates :visible, :inclusion => { :in => [true,false] }
-
+
# Return the comment text
def body
RichText.new("text", read_attribute(:body))
before_validation :generate_keys, :on => :create
attr_accessor :token_callback_url
-
+
def self.find_token(token_key)
token = OauthToken.find_by_token(token_key, :include => :client_application)
if token && token.authorized?
false
end
end
-
+
def self.all_permissions
PERMISSIONS
end
def oauth_server
@oauth_server ||= OAuth::Server.new("http://" + SERVER_URL)
end
-
+
def credentials
@oauth_client ||= OAuth::Consumer.new(key, secret)
end
-
+
def create_request_token(params={})
params = { :client_application => self, :callback_url => self.token_callback_url }
permissions.each do |p|
token = access_tokens.create(params)
end
-
+
token
end
end
protected
-
+
# this is the set of permissions that the client can ask for. clients
# have to say up-front what permissions they want and when users sign up they
# can agree or not agree to each of them.
name = english_name
name += " (#{native_name})" unless native_name.nil?
name
- end
+ end
end
has_many :ways, :through => :way_nodes
has_many :node_tags
-
+
has_many :old_way_nodes
has_many :ways_via_history, :class_name=> "Way", :through => :old_way_nodes, :source => :way
def self.from_xml_node(pt, create=false)
node = Node.new
-
+
raise OSM::APIBadXMLError.new("node", pt, "lat missing") if pt['lat'].nil?
raise OSM::APIBadXMLError.new("node", pt, "lon missing") if pt['lon'].nil?
node.lat = OSM.parse_float(pt['lat'], OSM::APIBadXMLError, "node", pt, "lat not a number")
unless create
raise OSM::APIBadXMLError.new("node", pt, "ID is required when updating.") if pt['id'].nil?
node.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
raise OSM::APIBadUserInput.new("ID of node cannot be zero when updating.") if node.id == 0
end
raise OSM::APIAlreadyDeletedError.new("node", new_node.id)
end
- # need to start the transaction here, so that the database can
+ # need to start the transaction here, so that the database can
# provide repeatable reads for the used-by checks. this means it
# shouldn't be possible to get race conditions.
Node.transaction do
check_consistency(self, new_node, user)
ways = Way.joins(:way_nodes).where(:visible => true, :current_way_nodes => { :node_id => id }).order(:id)
raise OSM::APIPreconditionFailedError.new("Node #{self.id} is still used by ways #{ways.collect { |w| w.id }.join(",")}.") unless ways.empty?
-
+
rels = Relation.joins(:relation_members).where(:visible => true, :current_relation_members => { :member_type => "Node", :member_id => id }).order(:id)
raise OSM::APIPreconditionFailedError.new("Node #{self.id} is still used by relations #{rels.collect { |r| r.id }.join(",")}.") unless rels.empty?
self.changeset_id = new_node.changeset_id
self.tags = {}
self.visible = false
-
+
# update the changeset with the deleted position
changeset.update_bbox!(bbox)
-
+
save_with_history!
end
end
Node.transaction do
self.lock!
check_consistency(self, new_node, user)
-
+
# update changeset first
self.changeset_id = new_node.changeset_id
self.changeset = new_node.changeset
-
+
# update changeset bbox with *old* position first
changeset.update_bbox!(bbox);
-
+
# FIXME logic needs to be double checked
- self.latitude = new_node.latitude
+ self.latitude = new_node.latitude
self.longitude = new_node.longitude
self.tags = new_node.tags
self.visible = true
-
+
# update changeset bbox with *new* position
changeset.update_bbox!(bbox);
-
+
save_with_history!
end
end
-
+
def create_with_history(user)
check_create_consistency(self, user)
self.version = 0
end
def tags=(t)
- @tags = t
- end
+ @tags = t
+ end
def add_tag_key_val(k,v)
@tags = Hash.new unless @tags
def fix_placeholders!(id_map, placeholder_id = nil)
# nodes don't refer to anything, so there is nothing to do here
end
-
+
private
def save_with_history!
tags.each do |k,v|
tag = NodeTag.new
tag.node_id = self.id
- tag.k = k
- tag.v = v
+ tag.k = k
+ tag.v = v
tag.save!
- end
+ end
# Create an OldNode
old_node = OldNode.from_node(self)
changeset.save!
end
end
-
+
end
self.primary_keys = "node_id", "k"
belongs_to :node
-
+
validates_presence_of :node
validates_length_of :k, :maximum => 255, :allow_blank => true
validates_uniqueness_of :k, :scope => :node_id
validates_presence_of :client_application, :token
before_validation :generate_keys, :on => :create
-
+
def invalidated?
invalidated_at != nil
end
-
+
def invalidate!
update_attributes(:invalidated_at => Time.now)
end
-
+
def authorized?
authorized_at != nil && !invalidated?
end
-
+
def to_query
"oauth_token=#{token}&oauth_token_secret=#{secret}"
end
-
+
protected
-
+
def generate_keys
self.token = OAuth::Helper.generate_key(40)[0,40]
self.secret = OAuth::Helper.generate_key(40)[0,40]
old_node.version = node.version
return old_node
end
-
+
def to_xml
doc = OSM::API.new.get_xml_doc
doc.root << to_xml_node()
def save_with_dependencies!
save!
-
+
self.tags.each do |k,v|
tag = OldNodeTag.new
tag.k = k
end
def tags=(t)
- @tags = t
+ @tags = t
end
- def tags_as_hash
+ def tags_as_hash
return self.tags
- end
-
- # Pretend we're not in any ways
- def ways
- return []
- end
-
- # Pretend we're not in any relations
- def containing_relation_members
- return []
- end
+ end
+
+ # Pretend we're not in any ways
+ def ways
+ return []
+ end
+
+ # Pretend we're not in any relations
+ def containing_relation_members
+ return []
+ end
# check whether this element is the latest version - that is,
# has the same version as its "current" counterpart.
class OldRelation < ActiveRecord::Base
include ConsistencyValidations
include ObjectMetadata
-
+
self.table_name = "relations"
self.primary_keys = "relation_id", "version"
has_many :old_members, -> { order(:sequence_id) }, :class_name => 'OldRelationMember', :foreign_key => [:relation_id, :version]
has_many :old_tags, :class_name => 'OldRelationTag', :foreign_key => [:relation_id, :version]
-
+
validates_associated :changeset
def self.from_relation(relation)
member_el['role'] = member.member_role.to_s
el << member_el
end
-
+
add_tags_to_xml_node(el, self.old_tags)
return el
self.primary_keys = "relation_id", "version", "k"
belongs_to :old_relation, :foreign_key => [:relation_id, :version]
-
+
validates_presence_of :old_relation
validates_length_of :k, :maximum => 255, :allow_blank => true
validates_uniqueness_of :k, :scope => [:relation_id, :version]
has_many :old_tags, :class_name => 'OldWayTag', :foreign_key => [:way_id, :version]
validates_associated :changeset
-
+
def self.from_way(way)
old_way = OldWay.new
old_way.visible = way.visible
node_el['ref'] = nd.node_id.to_s
el << node_el
end
-
+
add_tags_to_xml_node(el, self.old_tags)
return el
# Read full version of old way
# For get_nodes_undelete, uses same nodes, even if they've moved since
- # For get_nodes_revert, allocates new ids
+ # For get_nodes_revert, allocates new ids
# Currently returns Potlatch-style array
# where [5] indicates whether latest version is usable as is (boolean)
# (i.e. is it visible? are we actually reverting to an earlier version?)
[node.lon, node.lat, n, node.version, node.tags_as_hash, node.visible]
end
end
-
+
def get_nodes_revert(timestamp)
points=[]
self.nds.each do |n|
##
# Redaction represents a record associated with a particular
# action on the database to hide revisions from the history
-# which are not appropriate to redistribute any more.
+# which are not appropriate to redistribute any more.
#
# The circumstances of the redaction can be recorded in the
-# record's title and description fields, which can be
+# record's title and description fields, which can be
# displayed linked from the redacted records.
#
class Redaction < ActiveRecord::Base
has_many :old_ways
has_many :old_relations
- # this method overrides the AR default to provide the rich
+ # this method overrides the AR default to provide the rich
# text object for the description field.
def description
RichText.new(read_attribute(:description_format), read_attribute(:description))
class Relation < ActiveRecord::Base
require 'xml/libxml'
-
+
include ConsistencyValidations
include NotRedactable
include ObjectMetadata
has_many :containing_relations, :class_name => "Relation", :through => :containing_relation_members, :source => :relation
validates_presence_of :id, :on => :update
- validates_presence_of :timestamp,:version, :changeset_id
+ validates_presence_of :timestamp,:version, :changeset_id
validates_uniqueness_of :id
validates_inclusion_of :visible, :in => [ true, false ]
validates_numericality_of :id, :on => :update, :integer_only => true
validates_numericality_of :changeset_id, :version, :integer_only => true
validates_associated :changeset
-
+
scope :visible, -> { where(:visible => true) }
scope :invisible, -> { where(:visible => false) }
scope :nodes, ->(*ids) { joins(:relation_members).where(:current_relation_members => { :member_type => "Node", :member_id => ids.flatten }) }
relation.version = pt['version']
raise OSM::APIBadXMLError.new("relation", pt, "Changeset id is missing") if pt['changeset'].nil?
relation.changeset_id = pt['changeset']
-
+
unless create
raise OSM::APIBadXMLError.new("relation", pt, "ID is required when updating") if pt['id'].nil?
relation.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
raise OSM::APIBadUserInput.new("ID of relation cannot be zero when updating.") if relation.id == 0
end
-
+
# We don't care about the timestamp nor the visibility as these are either
- # set explicitly or implicit in the action. The visibility is set to true,
+ # set explicitly or implicit in the action. The visibility is set to true,
# and manually set to false before the actual delete.
relation.visible = true
end
# need to initialise the relation members array explicitly, as if this
- # isn't done for a new relation then @members attribute will be nil,
- # and the members will be loaded from the database instead of being
+ # isn't done for a new relation then @members attribute will be nil,
+ # and the members will be loaded from the database instead of being
# empty, as intended.
relation.members = Array.new
pt.find('member').each do |member|
- #member_type =
+ #member_type =
logger.debug "each member"
raise OSM::APIBadXMLError.new("relation", pt, "The #{member['type']} is not allowed only, #{TYPES.inspect} allowed") unless TYPES.include? member['type']
logger.debug "after raise"
if p
member_el = XML::Node.new 'member'
member_el['type'] = member.member_type.downcase
- member_el['ref'] = member.member_id.to_s
+ member_el['ref'] = member.member_id.to_s
member_el['role'] = member.member_role
el << member_el
end
add_tags_to_xml_node(el, self.relation_tags)
return el
- end
+ end
# FIXME is this really needed?
def members
end
##
- # updates the changeset bounding box to contain the bounding box of
+ # updates the changeset bounding box to contain the bounding box of
# the element with given +type+ and +id+. this only works with nodes
# and ways at the moment, as they're the only elements to respond to
# the :bbox call.
def update_changeset_element(type, id)
element = Kernel.const_get(type.capitalize).find(id)
changeset.update_bbox! element.bbox
- end
+ end
def delete_with_history!(new_relation, user)
unless self.visible
raise OSM::APIAlreadyDeletedError.new("relation", new_relation.id)
end
- # need to start the transaction here, so that the database can
+ # need to start the transaction here, so that the database can
# provide repeatable reads for the used-by checks. this means it
# shouldn't be possible to get race conditions.
Relation.transaction do
save_with_history!
end
end
-
+
def create_with_history(user)
check_create_consistency(self, user)
unless self.preconditions_ok?
end
def preconditions_ok?(good_members = [])
- # These are hastables that store an id in the index of all
+ # These are hastables that store an id in the index of all
# the nodes/way/relations that have already been added.
- # If the member is valid and visible then we add it to the
+ # If the member is valid and visible then we add it to the
# relevant hash table, with the value true as a cache.
# Thus if you have nodes with the ids of 50 and 1 already in the
# relation, then the hash table nodes would contain:
##
# if any members are referenced by placeholder IDs (i.e: negative) then
- # this calling this method will fix them using the map from placeholders
- # to IDs +id_map+.
+ # this calling this method will fix them using the map from placeholders
+ # to IDs +id_map+.
def fix_placeholders!(id_map, placeholder_id = nil)
self.members.map! do |type, id, role|
old_id = id.to_i
end
private
-
+
def save_with_history!
Relation.transaction do
# have to be a little bit clever here - to detect if any tags
key = old_tag.k
# if we can match the tags we currently have to the list
# of old tags, then we never set the tags_changed flag. but
- # if any are different then set the flag and do the DB
+ # if any are different then set the flag and do the DB
# update.
- if tags.has_key? key
+ if tags.has_key? key
tags_changed |= (old_tag.v != tags[key])
# remove from the map, so that we can expect an empty map
tag.v = v
tag.save!
end
-
+
# same pattern as before, but this time we're collecting the
# changed members in an array, as the bounding box updates for
# elements are per-element, not blanked on/off like for tags.
# bounding box. this is similar to how the map call does things and is
# reasonable on the assumption that adding or removing members doesn't
# materially change the rest of the relation.
- any_relations =
+ any_relations =
changed_members.collect { |id,type| type == "relation" }.
inject(false) { |b,s| b or s }
# FIXME: check for tag changes along with element deletions and
# make sure that the deleted element's bounding box is hit.
self.members
- else
+ else
changed_members
end
update_members.each do |type, id, role|
f.syswrite(data)
f.close
end
-
+
def icon_picture= (data)
f = File.new(icon_picture_name, "wb")
f.syswrite(data)
f.close
data
end
-
+
def icon_picture
f = File.new(icon_picture_name, "rb")
logger.info "icon picture file: '#{f.path}'"
f.close
data
end
-
+
def large_picture_name
"#{GPX_IMAGE_DIR}/#{id}.gif"
end
def self.from_xml_node(pt, create=false)
trace = Trace.new
-
+
raise OSM::APIBadXMLError.new("trace", pt, "visibility missing") if pt['visibility'].nil?
trace.visibility = pt['visibility']
unless create
raise OSM::APIBadXMLError.new("trace", pt, "ID is required when updating.") if pt['id'].nil?
trace.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
raise OSM::APIBadUserInput.new("ID of trace cannot be zero when updating.") if trace.id == 0
end
self.primary_keys = "user_id", "k"
belongs_to :user
-
+
validates_length_of :k, :within => 1..255
validates_length_of :v, :within => 1..255
el1 = XML::Node.new 'preference'
el1['k'] = self.k
el1['v'] = self.v
-
+
return el1
end
class Way < ActiveRecord::Base
require 'xml/libxml'
-
+
include ConsistencyValidations
include NotRedactable
include ObjectMetadata
self.table_name = "current_ways"
-
+
belongs_to :changeset
has_many :old_ways, -> { order(:version) }
unless create
raise OSM::APIBadXMLError.new("way", pt, "ID is required when updating") if pt['id'].nil?
way.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
raise OSM::APIBadUserInput.new("ID of way cannot be zero when updating.") if way.id == 0
end
# We don't care about the timestamp nor the visibility as these are either
- # set explicitly or implicit in the action. The visibility is set to true,
+ # set explicitly or implicit in the action. The visibility is set to true,
# and manually set to false before the actual delete.
way.visible = true
# Find a way given it's ID, and in a single SQL call also grab its nodes
#
-
+
# You can't pull in all the tags too unless we put a sequence_id on the way_tags table and have a multipart key
def self.find_eager(id)
way = Way.find(id, :include => {:way_nodes => :node})
add_tags_to_xml_node(el, self.way_tags)
return el
- end
+ end
def nds
@nds ||= self.way_nodes.collect { |n| n.node_id }
unless new_way.preconditions_ok?(self.nds)
raise OSM::APIPreconditionFailedError.new("Cannot update way #{self.id}: data is invalid.")
end
-
+
self.changeset_id = new_way.changeset_id
self.changeset = new_way.changeset
self.tags = new_way.tags
unless self.visible
raise OSM::APIAlreadyDeletedError.new("way", new_way.id)
end
-
- # need to start the transaction here, so that the database can
+
+ # need to start the transaction here, so that the database can
# provide repeatable reads for the used-by checks. this means it
# shouldn't be possible to get race conditions.
Way.transaction do
##
# if any referenced nodes are placeholder IDs (i.e: are negative) then
- # this calling this method will fix them using the map from placeholders
- # to IDs +id_map+.
+ # this calling this method will fix them using the map from placeholders
+ # to IDs +id_map+.
def fix_placeholders!(id_map, placeholder_id = nil)
self.nds.map! do |node_id|
if node_id < 0
end
private
-
+
def save_with_history!
t = Time.now.getutc
- # update the bounding box, note that this has to be done both before
- # and after the save, so that nodes from both versions are included in the
+ # update the bounding box, note that this has to be done both before
+ # and after the save, so that nodes from both versions are included in the
# bbox. we use a copy of the changeset so that it isn't reloaded
# later in the save.
cs = self.changeset
# new set of nodes.
self.reload
- # update and commit the bounding box, now that way nodes
+ # update and commit the bounding box, now that way nodes
# have been updated and we're in a transaction.
cs.update_bbox!(bbox) unless nodes.empty?
self.primary_keys = "way_id", "k"
belongs_to :way
-
+
validates_presence_of :way
validates_length_of :k, :maximum => 255, :allow_blank => true
validates_uniqueness_of :k, :scope => :way_id
class AbstractAdapter
protected
alias_method :old_log, :log
-
+
def log(sql, name)
if block_given?
old_log(sql, name) do
# Configure ActionMailer SMTP settings
ActionMailer::Base.smtp_settings = {
:address => 'localhost',
- :port => 25,
+ :port => 25,
:domain => 'localhost',
:enable_starttls_auto => false
}
def initialize(app)
@app = app
end
-
+
def call(env)
# Process this requst
status, headers, body = @app.call(env)
-
+
# Restart if we've hit our memory limit
if resident_size > SOFT_MEMORY_LIMIT
Process.kill("USR1", Process.pid)
end
-
+
# Return the result of this request
[status, headers, body]
end
fields = File.open("/proc/self/statm") do |file|
fields = file.gets.split(" ")
end
-
+
# Return resident size in megabytes
return fields[1].to_i / 256
end
def prepare
@output = R2.r2(data)
end
-
+
def evaluate(scope, locals, &block)
@output
end
match 'api/0.6/gpx/:id' => 'trace#api_delete', :via => :delete, :id => /\d+/
match 'api/0.6/gpx/:id/details' => 'trace#api_read', :via => :get, :id => /\d+/
match 'api/0.6/gpx/:id/data' => 'trace#api_data', :via => :get
-
+
# AMF (ActionScript) API
match 'api/0.6/amf/read' => 'amf#amf_read', :via => :post
match 'api/0.6/amf/write' => 'amf#amf_write', :via => :post
end
def self.down
-
+
end
end
add_index "users", ["display_name"], :name => "users_display_name_idx", :unique => true
change_column "way_segments", "segment_id", :bigint, :null => false
-
+
change_column "way_tags", "k", :string, :null => false
change_column "way_tags", "v", :string, :null => false
change_column "way_tags", "version", :bigint, :null => false
change_column "way_tags", "k", :string, :default => nil
change_column "way_segments", "segment_id", :integer
-
+
remove_index "users", :name => "users_display_name_idx"
add_index "users", ["display_name"], :name => "users_display_name_idx"
remove_index "users", :name => "users_email_idx"
change_column "current_segments", "user_id", :bigint
change_column "current_segments", "node_b", :bigint
change_column "current_segments", "node_a", :bigint
-
+
add_index "current_nodes", ["id"], :name => "current_nodes_id_idx"
remove_primary_key "current_nodes"
change_column "current_nodes", "timestamp", :datetime
change_column "current_nodes", "tile", :bigint
upgrade_table "current_nodes_v5", "current_nodes", Node
-
+
drop_table "current_nodes_v5"
remove_index "nodes", :name=> "nodes_uid_idx"
cmd = "db/migrate/008_remove_segments_helper"
src = "#{cmd}.cc"
- if not File.exists? cmd or File.mtime(cmd) < File.mtime(src) then
+ if not File.exists? cmd or File.mtime(cmd) < File.mtime(src) then
system 'c++ -O3 -Wall `mysql_config --cflags --libs` ' +
"#{src} -o #{cmd}" or fail
end
cmd = "db/migrate/020_populate_node_tags_and_remove_helper"
src = "#{cmd}.c"
- if not File.exists? cmd or File.mtime(cmd) < File.mtime(src) then
+ if not File.exists? cmd or File.mtime(cmd) < File.mtime(src) then
system 'cc -O3 -Wall `mysql_config --cflags --libs` ' +
"#{src} -o #{cmd}" or fail
end
@@ver_tbl.each { |tbl|
add_column "current_#{tbl}", "version", :bigint, :null => false
- # As the initial version of all nodes, ways and relations is 0, we set the
- # current version to something less so that we can update the version in
+ # As the initial version of all nodes, ways and relations is 0, we set the
+ # current version to something less so that we can update the version in
# batches of 10000
tbl.classify.constantize.update_all("version=-1")
while tbl.classify.constantize.count(:conditions => {:version => -1}) > 0
class AddChangesets < ActiveRecord::Migration
@@conv_user_tables = ['current_nodes',
'current_relations', 'current_ways', 'nodes', 'relations', 'ways' ]
-
+
def self.up
create_table "changesets", :id => false do |t|
t.column "id", :bigserial, :primary_key => true, :null => false
end
add_index "changeset_tags", ["id"], :name => "changeset_tags_id_idx"
-
+
#
- # Initially we will have one changeset for every user containing
- # all edits up to the API change,
+ # Initially we will have one changeset for every user containing
+ # all edits up to the API change,
# all the changesets will have the id of the user that made them.
# We need to generate a changeset for each user in the database
- execute "INSERT INTO changesets (id, user_id, created_at, open)" +
+ execute "INSERT INTO changesets (id, user_id, created_at, open)" +
"SELECT id, id, creation_time, false from users;"
@@conv_user_tables.each { |tbl|
add_column(:relation_members, :sequence_id, :integer,
:default => 0, :null => false)
- # update the sequence column with default (partial) ordering by
+ # update the sequence column with default (partial) ordering by
# element ID. the sequence ID is a smaller int type, so we can't
# just copy the member_id.
execute("update relation_members set sequence_id = mod(member_id, 16384)")
- # need to update the primary key to include the sequence number,
+ # need to update the primary key to include the sequence number,
# otherwise the primary key will barf when we have repeated members.
# mysql barfs on this anyway, so we need a single command. this may
# not work in postgres... needs testing.
# swap the boolean closed-or-not for a time when the changeset will
# close or has closed.
add_column(:changesets, :closed_at, :datetime, :null => false)
-
+
# it appears that execute will only accept string arguments, so
# this is an ugly, ugly hack to get some sort of mysql/postgres
# independence. now i have to go wash my brain with bleach.
execute("update changesets set closed_at=(now()-'1 hour'::interval) where open=(1=0)")
execute("update changesets set closed_at=(now()+'1 hour'::interval) where open=(1=1)")
- # remove the open column as it is unnecessary now and denormalises
+ # remove the open column as it is unnecessary now and denormalises
# the table.
remove_column :changesets, :open
# add a column to keep track of the number of changes in a changeset.
# could probably work out how many changes there are here, but i'm not
# sure its actually important.
- add_column(:changesets, :num_changes, :integer,
+ add_column(:changesets, :num_changes, :integer,
:null => false, :default => 0)
end
t.timestamps
end
add_index :client_applications, :key, :unique => true
-
+
create_table :oauth_tokens do |t|
t.integer :user_id
t.string :type, :limit => 20
t.timestamp :authorized_at, :invalidated_at
t.timestamps
end
-
+
add_index :oauth_tokens, :token, :unique => true
-
+
create_table :oauth_nonces do |t|
t.string :nonce
t.integer :timestamp
t.timestamps
end
add_index :oauth_nonces, [:nonce, :timestamp], :unique => true
-
+
end
def self.down
create_enumeration :map_bug_status_enum, ["open", "closed", "hidden"]
create_table :map_bugs do |t|
- t.integer :latitude, :null => false
- t.integer :longitude, :null => false
+ t.integer :latitude, :null => false
+ t.integer :longitude, :null => false
t.column :tile, :bigint, :null => false
t.datetime :last_changed, :null => false
- t.datetime :date_created, :null => false
- t.string :nearby_place
+ t.datetime :date_created, :null => false
+ t.string :nearby_place
t.string :text
t.column :status, :map_bug_status_enum, :null => false
end
def self.up
create_table :map_bug_comment do |t|
t.column :bug_id, :bigint, :null => false
- t.boolean :visible, :null => false
+ t.boolean :visible, :null => false
t.datetime :date_created, :null => false
t.string :commenter_name
t.string :commenter_ip
t.string :comment
end
- remove_column :map_bugs, :text
+ remove_column :map_bugs, :text
change_column :map_bug_comment, :id, :bigint
end
def self.down
- remove_column :map_bugs, :date_closed
+ remove_column :map_bugs, :date_closed
end
end
class AddOpenId < ActiveRecord::Migration
def self.up
- add_column :users, :openid_url, :string
+ add_column :users, :openid_url, :string
add_index :users, [:openid_url], :name => "user_openid_url_idx", :unique => true
end
class AddTermsSeenToUser < ActiveRecord::Migration
def self.up
add_column :users, :terms_seen, :boolean, :null => false, :default => false
-
+
# best guess available is just that everyone who has agreed has
# seen the terms, and that noone else has.
User.update_all "terms_seen = (terms_agreed is not null)"
#
# Pagination is included automatically for all controllers.
#
- # For help rendering pagination links, see
+ # For help rendering pagination links, see
# ActionView::Helpers::PaginationHelper.
#
# ==== Automatic pagination for every action in a controller
#
- # class PersonController < ApplicationController
+ # class PersonController < ApplicationController
# model :person
#
# paginate :people, :order => 'last_name, first_name',
# :per_page => 20
- #
+ #
# # ...
# end
#
# Each action in this controller now has access to a <tt>@people</tt>
# instance variable, which is an ordered collection of model objects for the
- # current page (at most 20, sorted by last name and first name), and a
+ # current page (at most 20, sorted by last name and first name), and a
# <tt>@person_pages</tt> Paginator instance. The current page is determined
# by the <tt>params[:page]</tt> variable.
#
# and <tt>@people</tt> for a single action, and uses the default of 10 items
# per page.
#
- # ==== Custom/"classic" pagination
+ # ==== Custom/"classic" pagination
#
# def list
# @person_pages = Paginator.new self, Person.count, 10, params[:page]
- # @people = Person.find :all, :order => 'last_name, first_name',
+ # @people = Person.find :all, :order => 'last_name, first_name',
# :limit => @person_pages.items_per_page,
# :offset => @person_pages.current.offset
# end
- #
- # Explicitly creates the paginator from the previous example and uses
+ #
+ # Explicitly creates the paginator from the previous example and uses
# Paginator#to_sql to retrieve <tt>@people</tt> from the model.
#
module Pagination
unless const_defined?(:OPTIONS)
# A hash holding options for controllers using macro-style pagination
OPTIONS = Hash.new
-
+
# The default options for pagination
DEFAULT_OPTIONS = {
:class_name => nil,
else
DEFAULT_OPTIONS[:group] = nil
end
-
+
def self.included(base) #:nodoc:
super
base.extend(ClassMethods)
end
-
+
def self.validate_options!(collection_id, options, in_action) #:nodoc:
options.merge!(DEFAULT_OPTIONS) {|key, old, new| old}
valid_options = DEFAULT_OPTIONS.keys
valid_options << :actions unless in_action
-
+
unknown_option_keys = options.keys - valid_options
raise ActionController::ActionControllerError,
"Unknown options: #{unknown_option_keys.join(', ')}" unless
# <tt>:singular_name</tt>:: the singular name to use, if it can't be inferred by singularizing the collection name
# <tt>:class_name</tt>:: the class name to use, if it can't be inferred by
# camelizing the singular name
- # <tt>:per_page</tt>:: the maximum number of items to include in a
+ # <tt>:per_page</tt>:: the maximum number of items to include in a
# single page. Defaults to 10
# <tt>:conditions</tt>:: optional conditions passed to Model.find(:all, *params) and
# Model.count
paginator_and_collection_for(collection_id, options)
end
- # These methods become class methods on any controller
+ # These methods become class methods on any controller
module ClassMethods
# Creates a +before_filter+ which automatically paginates an Active
# Record model for all actions in a controller (or certain actions if
# specified with the <tt>:actions</tt> option).
#
- # +options+ are the same as PaginationHelper#paginate, with the addition
+ # +options+ are the same as PaginationHelper#paginate, with the addition
# of:
# <tt>:actions</tt>:: an array of actions for which the pagination is
# active. Defaults to +nil+ (i.e., every action)
next unless options[:actions].include? action_name if
options[:actions]
- paginator, collection =
+ paginator, collection =
paginator_and_collection_for(collection_id, options)
paginator_name = "@#{options[:singular_name]}_pages"
self.instance_variable_set(paginator_name, paginator)
collection_name = "@#{collection_id.to_s}"
- self.instance_variable_set(collection_name, collection)
+ self.instance_variable_set(collection_name, collection)
end
end
-
+
# Returns the total number of items in the collection to be paginated for
# the +model+ and given +conditions+. Override this method to implement a
# custom counter.
collection.count
end
-
+
# Returns a collection of items for the given +model+ and +options[conditions]+,
# ordered by +options[order]+, for the current page in the given +paginator+.
# Override this method to implement a custom finder.
if options[:select]
collection = collection.select(options[:select])
end
-
+
collection.offset(paginator.current.offset).limit(options[:per_page])
end
-
+
protected :create_paginators_and_retrieve_collections,
:count_collection_for_pagination,
:find_collection_for_pagination
count = count_collection_for_pagination(klass, options)
paginator = Paginator.new(self, count, options[:per_page], page)
collection = find_collection_for_pagination(klass, options, paginator)
-
- return paginator, collection
+
+ return paginator, collection
end
-
+
private :paginator_and_collection_for
# A class representing a paginator for an Active Record collection.
@item_count = item_count || 0
@items_per_page = items_per_page
@pages = {}
-
+
self.current_page = current_page
end
attr_reader :controller, :item_count, :items_per_page
-
+
# Sets the current page number of this paginator. If +page+ is a Page
- # object, its +number+ attribute is used as the value; if the page does
+ # object, its +number+ attribute is used as the value; if the page does
# not belong to this Paginator, an ArgumentError is raised.
def current_page=(page)
if page.is_a? Page
# Returns a new Page representing the last page in this paginator.
def last_page
- @last_page ||= self[page_count]
+ @last_page ||= self[page_count]
end
alias last :last_page
attr_reader :paginator, :number
alias to_i :number
- # Compares two Page objects and returns true when they represent the
+ # Compares two Page objects and returns true when they represent the
# same page (i.e., their paginators are the same and they have the
# same page number).
def ==(page)
return false if page.nil?
- @paginator == page.paginator and
+ @paginator == page.paginator and
@number == page.number
end
def offset
@paginator.items_per_page * (@number - 1)
end
-
+
# Returns the number of the first item displayed.
def first_item
offset + 1
end
-
+
# Returns the number of the last item displayed.
def last_item
[@paginator.items_per_page * @number, @paginator.item_count].min
if last? then nil else @paginator[@number + 1] end
end
- # Returns a new Window object for this page with the specified
+ # Returns a new Window object for this page with the specified
# +padding+.
def window(padding=2)
Window.new(self, padding)
def to_sql
[@paginator.items_per_page, offset]
end
-
+
def to_param #:nodoc:
@number.to_s
end
# (i.e. Older Pages: 1 2 3 4)
# <tt>:suffix</tt>:: suffix for pagination links
# (i.e. 1 2 3 4 <- Older Pages)
- # <tt>:window_size</tt>:: the number of pages to show around
+ # <tt>:window_size</tt>:: the number of pages to show around
# the current page (defaults to <tt>2</tt>)
# <tt>:always_show_anchors</tt>:: whether or not the first and last
# pages should always be shown
# # => <a href="/?page=1/">1</a> <a href="/?page=2/">2</a> <a href="/?page=3/">3</a> ... <a href="/?page=10/">10</a>
#
# pagination_links(@person_pages, :always_show_anchors => false)
- # # => 1 <a href="/?page=2/">2</a> <a href="/?page=3/">3</a>
+ # # => 1 <a href="/?page=2/">2</a> <a href="/?page=3/">3</a>
#
# pagination_links(@person_pages, :window_size => 1)
# # => 1 <a href="/?page=2/">2</a> ... <a href="/?page=10/">10</a>
#
# pagination_links(@person_pages, :params => { :viewer => "flash" })
- # # => 1 <a href="/?page=2&viewer=flash/">2</a> <a href="/?page=3&viewer=flash/">3</a> ...
+ # # => 1 <a href="/?page=2&viewer=flash/">2</a> <a href="/?page=3&viewer=flash/">3</a> ...
# # <a href="/?page=10&viewer=flash/">10</a>
def pagination_links(paginator, options={}, html_options={})
name = options[:name] || DEFAULT_OPTIONS[:name]
params = (options[:params] || DEFAULT_OPTIONS[:params]).clone
-
+
prefix = options[:prefix] || ''
suffix = options[:suffix] || ''
# Iterate through the pages of a given +paginator+, invoking a
# block for each page number that needs to be rendered as a link.
- #
+ #
# ==== Options
- # <tt>:window_size</tt>:: the number of pages to show around
+ # <tt>:window_size</tt>:: the number of pages to show around
# the current page (defaults to +2+)
# <tt>:always_show_anchors</tt>:: whether or not the first and last
# pages should always be shown
current_page = paginator.current_page
window_pages = current_page.window(options[:window_size]).pages
return if window_pages.length <= 1 unless link_to_current_page
-
+
first, last = paginator.first, paginator.last
-
+
html = ''
html << prefix if prefix
html << ' ... ' if wp_first.number - first.number > 1
html << ' '
end
-
+
window_pages.each do |page|
if current_page == page && !link_to_current_page
html << page.number.to_s
end
html << ' '
end
-
- if always_show_anchors and not (wp_last = window_pages[-1]).last?
+
+ if always_show_anchors and not (wp_last = window_pages[-1]).last?
html << ' ... ' if last.number - wp_last.number > 1
html << yield(last.number)
end
html
end
-
+
end # PaginationHelper
end # Helpers
end # ActionView
module ConsistencyValidations
# Generic checks that are run for the updates and deletes of
- # node, ways and relations. This code is here to avoid duplication,
+ # node, ways and relations. This code is here to avoid duplication,
# and allow the extention of the checks without having to modify the
- # code in 6 places for all the updates and deletes. Some of these tests are
- # needed for creates, but are currently not run :-(
+ # code in 6 places for all the updates and deletes. Some of these tests are
+ # needed for creates, but are currently not run :-(
# This will throw an exception if there is an inconsistency
def check_consistency(old, new, user)
if new.id != old.id or new.id.nil? or old.id.nil?
raise OSM::APIChangesetAlreadyClosedError.new(new.changeset)
end
end
-
+
# This is similar to above, just some validations don't apply
def check_create_consistency(new, user)
if new.changeset.nil?
# may alter it.
if changeset.nil?
raise OSM::APIChangesetMissingError.new
- elsif user.id != changeset.user_id
+ elsif user.id != changeset.user_id
raise OSM::APIUserChangesetMismatchError.new
elsif not changeset.is_open?
raise OSM::APIChangesetAlreadyClosedError.new(changeset)
ActiveRecord::Base.logger.info("GPX Import daemon wake @ #{Time.now}.")
Trace.find(:all, :conditions => { :inserted => false, :visible => true }, :order => "id").each do |trace|
- Signal.trap("TERM") do
+ Signal.trap("TERM") do
terminated = true
end
end
Trace.find(:all, :conditions => { :visible => false }, :order => "id").each do |trace|
- Signal.trap("TERM") do
+ Signal.trap("TERM") do
terminated = true
end
include ConsistencyValidations
# maps each element type to the model class which handles it
- MODELS = {
- "node" => Node,
- "way" => Way,
+ MODELS = {
+ "node" => Node,
+ "way" => Way,
"relation" => Relation
}
end
##
- # An element-block mapping for using the LibXML reader interface.
+ # An element-block mapping for using the LibXML reader interface.
#
# Since a lot of LibXML reader usage is boilerplate iteration through
# elements, it would be better to DRY and do this in a block. This
else
read_or_die
end
- end
+ end
end
read_or_die
end
##
- # An element-block mapping for using the LibXML reader interface.
+ # An element-block mapping for using the LibXML reader interface.
#
# Since a lot of LibXML reader usage is boilerplate iteration through
# elements, it would be better to DRY and do this in a block. This
model = MODELS[model_name]
raise OSM::APIBadUserInput.new("Unexpected element type #{model_name}, " +
"expected node, way or relation.") if model.nil?
- # new in libxml-ruby >= 2, expand returns an element not associated
+ # new in libxml-ruby >= 2, expand returns an element not associated
# with a document. this means that there's no encoding parameter,
# which means basically nothing works.
expanded = @reader.expand
# such as save_ and delete_with_history.
def check(model, xml, new)
raise OSM::APIBadXMLError.new(model, xml) if new.nil?
- unless new.changeset_id == @changeset.id
+ unless new.changeset_id == @changeset.id
raise OSM::APIChangesetMismatchError.new(new.changeset_id, @changeset.id)
end
end
# is *not* transactional, so code which calls it should ensure that the
# appropriate transaction block is in place.
#
- # On a failure to meet preconditions (e.g: optimistic locking fails)
+ # On a failure to meet preconditions (e.g: optimistic locking fails)
# an exception subclassing OSM::APIError will be thrown.
def commit
# create element given user
new.create_with_history(@changeset.user)
-
+
# save placeholder => allocated ID map
ids[model_sym][placeholder_id] = new.id
xml_result["new_version"] = new.version.to_s
result.root << xml_result
end
-
+
elsif action_name == 'modify'
# modify an existing element. again, this code doesn't directly deal
# with types, but uses duck typing to handle them transparently.
xml_result = XML::Node.new model.to_s.downcase
xml_result["old_id"] = client_id.to_s
- xml_result["new_id"] = id.to_s
+ xml_result["new_id"] = id.to_s
# version is updated in "old" through the update, so we must not
# return new.version here but old.version!
xml_result["new_version"] = old.version.to_s
-module Editors
+module Editors
ALL_EDITORS = [ "potlatch", "potlatch2", "id", "remote" ]
RECOMMENDED_EDITORS = [ "id", "potlatch2", "remote" ]
end
module GeoRecord
- # This scaling factor is used to convert between the float lat/lon that is
+ # This scaling factor is used to convert between the float lat/lon that is
# returned by the API, and the integer lat/lon equivalent that is stored in
# the database.
SCALE = 10000000
-
+
def self.included(base)
base.scope :bbox, ->(bbox) { base.where(OSM.sql_for_area(bbox)) }
base.before_save :update_tile
end
private
-
+
def lat2y(a)
180/Math::PI * Math.log(Math.tan(Math::PI/4+a*(Math::PI/180)/2))
end
# OutputCompression
-# Rails output compression filters
-#
-# Adds two classmethods to ActionController that can be used as after-filters:
-# strip_whitespace and compress_output.
-# If you use page-caching, you MUST specify the compress_output filter AFTER
-# caches_page, otherwise the compressed data will be cached instead of the HTML
-#
-# class MyController < ApplicationController
-# after_filter :strip_whitespace
-# caches_page :index
-# after_filter :compress_output
-# end
+# Rails output compression filters
+#
+# Adds two classmethods to ActionController that can be used as after-filters:
+# strip_whitespace and compress_output.
+# If you use page-caching, you MUST specify the compress_output filter AFTER
+# caches_page, otherwise the compressed data will be cached instead of the HTML
+#
+# class MyController < ApplicationController
+# after_filter :strip_whitespace
+# caches_page :index
+# after_filter :compress_output
+# end
-begin
- require 'zlib'
- require 'stringio'
- GZIP_SUPPORTED = true
-rescue
- GZIP_SUPPORTED = false
-end
+begin
+ require 'zlib'
+ require 'stringio'
+ GZIP_SUPPORTED = true
+rescue
+ GZIP_SUPPORTED = false
+end
-module CompressionSystem
- def compress_output
+module CompressionSystem
+ def compress_output
return unless accepts_gzip?
- output = StringIO.new
- def output.close
- # Zlib does a close. Bad Zlib...
- rewind
- end
- gz = Zlib::GzipWriter.new(output)
- gz.write(response.body)
- gz.close
- if output.length < response.body.length
- @old_response_body = response.body
- response.body = output.string
- response.headers['Content-encoding'] = @compression_encoding
- end
- end
-
- def accepts_gzip?
- return false unless GZIP_SUPPORTED
- accepts = request.env['HTTP_ACCEPT_ENCODING']
- return false unless accepts && accepts =~ /(x-gzip|gzip)/
- @compression_encoding = $1
- true
+ output = StringIO.new
+ def output.close
+ # Zlib does a close. Bad Zlib...
+ rewind
+ end
+ gz = Zlib::GzipWriter.new(output)
+ gz.write(response.body)
+ gz.close
+ if output.length < response.body.length
+ @old_response_body = response.body
+ response.body = output.string
+ response.headers['Content-encoding'] = @compression_encoding
+ end
+ end
+
+ def accepts_gzip?
+ return false unless GZIP_SUPPORTED
+ accepts = request.env['HTTP_ACCEPT_ENCODING']
+ return false unless accepts && accepts =~ /(x-gzip|gzip)/
+ @compression_encoding = $1
+ true
end
-
+
def strip_whitespace
- response.body.gsub!(/()|(.*?<\/script>)|()|()|\s+/m) do |m|
- if m =~ /^()(.*?)<\/script>$/m
- $1 + $2.strip.gsub(/\s+/, ' ').gsub('',"\n-->") + ''
- elsif m =~ /^$/m
- ''
- elsif m =~ /^<(textarea|pre)/
- m
- else ' '
- end
+ response.body.gsub!(/()|(.*?<\/script>)|()|()|\s+/m) do |m|
+ if m =~ /^()(.*?)<\/script>$/m
+ $1 + $2.strip.gsub(/\s+/, ' ').gsub('',"\n-->") + ''
+ elsif m =~ /^$/m
+ ''
+ elsif m =~ /^<(textarea|pre)/
+ m
+ else ' '
+ end
end
- response.body.gsub! /\s+\s+/, '>'
- end
-end
+ response.body.gsub! /\s+\s+/, '>'
+ end
+end
-class ActionController::Base
- include CompressionSystem
-end
\ No newline at end of file
+class ActionController::Base
+ include CompressionSystem
+end
# The AMF class is a set of helper functions for encoding and decoding AMF.
class AMF
-
+
# Return two-byte integer
- def self.getint(s)
+ def self.getint(s)
s.getbyte*256+s.getbyte
end
# Return four-byte long
- def self.getlong(s)
+ def self.getlong(s)
((s.getbyte*256+s.getbyte)*256+s.getbyte)*256+s.getbyte
end
- # Return string with two-byte length
- def self.getstring(s)
+ # Return string with two-byte length
+ def self.getstring(s)
len=s.getbyte*256+s.getbyte
str=s.read(len)
str.force_encoding("UTF-8") if str.respond_to?("force_encoding")
str
end
- # Return eight-byte double-precision float
- def self.getdouble(s)
+ # Return eight-byte double-precision float
+ def self.getdouble(s)
a=s.read(8).unpack('G') # G big-endian, E little-endian
a[0]
end
# Return numeric array
- def self.getarray(s)
+ def self.getarray(s)
len=getlong(s)
arr=[]
for i in (0..len-1)
arr
end
- # Return object/hash
- def self.getobject(s)
+ # Return object/hash
+ def self.getobject(s)
arr={}
while (key=getstring(s))
if (key=='') then break end
end
# Parse and get value
- def self.getvalue(s)
+ def self.getvalue(s)
case s.getbyte
when 0; return getdouble(s) # number
when 1; return s.getbyte # boolean
end
# Envelope data into AMF writeable form
- def self.putdata(index,n)
+ def self.putdata(index,n)
d =encodestring(index+"/onResult")
d+=encodestring("null")
d+=[-1].pack("N")
end
# Pack variables as AMF
- def self.encodevalue(n)
+ def self.encodevalue(n)
case n.class.to_s
when 'Array'
a=10.chr+encodelong(n.length)
a.chr+b.chr+n
end
- # Encode number as eight-byte double precision float
- def self.encodedouble(n)
+ # Encode number as eight-byte double precision float
+ def self.encodedouble(n)
[n].pack('G')
end
# Encode number as four-byte long
- def self.encodelong(n)
+ def self.encodelong(n)
[n].pack('N')
end
}
end
icon_list.reverse!
-
+
# Read auto-complete
autotags={}; autotags['point']={}; autotags['way']={}; autotags['POI']={};
File.open("#{Rails.root}/config/potlatch/autocomplete.txt") do |file|
end
end
-
def status
@ipinfo["GetIpInfoResult"]["Response"]["Status"].to_i
end
-
+
def country_code
@ipinfo["GetIpInfoResult"]["Location"]["Country"]["Name"]
end
end
end
end
-
# in scope for the module itself.
base.scope :unredacted, -> { base.where(:redaction_id => nil) }
end
-
+
def redacted?
not self.redaction.nil?
end
else
"<a rel=\"nofollow\" href=\"#{link}\">#{link}</a>"
end
- end
+ end
end
end
# session_expires_after 1.hour
# session_expires_after 2.weeks
def session_expires_after(seconds)
- session[session_persistence_key] = seconds
+ session[session_persistence_key] = seconds
end
# Expire the session.
module ShortLink
# array of 64 chars to encode 6 bits. this is almost like base64 encoding, but
- # the symbolic chars are different, as base64's + and / aren't very
+ # the symbolic chars are different, as base64's + and / aren't very
# URL-friendly.
ARRAY = ('A'..'Z').to_a + ('a'..'z').to_a + ('0'..'9').to_a + ['_','~']
##
- # Given a string encoding a location, returns the [lon, lat, z] tuple of that
+ # Given a string encoding a location, returns the [lon, lat, z] tuple of that
# location.
def self.decode(str)
x = 0
y <<= (32 - z)
# project the parameters back to their coordinate ranges.
- [(x * 360.0 / 2**32) - 180.0,
- (y * 180.0 / 2**32) - 90.0,
+ [(x * 360.0 / 2**32) - 180.0,
+ (y * 180.0 / 2**32) - 90.0,
z - 8 - (z_offset % 3)]
end
##
# given a location and zoom, return a short string representing it.
def self.encode(lon, lat, z)
- code = interleave_bits(((lon + 180.0) * 2**32 / 360.0).to_i,
+ code = interleave_bits(((lon + 180.0) * 2**32 / 360.0).to_i,
((lat + 90.0) * 2**32 / 180.0).to_i)
str = ""
# add eight to the zoom level, which approximates an accuracy of
# partial zoom levels (characters themselves have a granularity
# of 3 zoom levels).
((z + 8) % 3).times { str << "-" }
-
+
return str
end
private
-
+
##
# interleaves the bits of two 32-bit numbers. the result is known
# as a Morton code.
increment = 1000
offset = 0
id_max = OldNode.find(:first, :order => 'id desc').id
-
+
while offset < (id_max + increment)
hash = {}
#should be offsetting not selecting
OldNode.find(:all, :limit => increment, :offset => offset, :order => 'timestamp').each do |node|
if hash[node.id].nil?
- hash[node.id] = []
+ hash[node.id] = []
end
hash[node.id] << node
end
temp_old_node.tile = node.tile
temp_old_node.version = n
temp_old_node.save! || raise
- n +=1
+ n +=1
end
end
offset += increment
end
end
end
-
-
-
-
-
-
namespace :test do
- Rails::TestTask.new(lib: "test:prepare") do |t|
+ Rails::TestTask.new(lib: "test:prepare") do |t|
t.pattern = 'test/lib/**/*_test.rb'
end
end
module ActiveRecord
module Validations
module ClassMethods
-
+
# error message when invalid UTF-8 is detected
@@invalid_utf8_message = " is invalid UTF-8"
validates_each(attrs) do |record, attr, value|
record.errors.add(attr, @@invalid_utf8_message) unless UTF8.valid? value
end
- end
+ end
end
end
#!/usr/bin/env ruby
-Dir[File.dirname(__FILE__) + "/../lib/daemons/*_ctl"].each {|f| `#{f} #{ARGV.first}`}
\ No newline at end of file
+Dir[File.dirname(__FILE__) + "/../lib/daemons/*_ctl"].each {|f| `#{f} #{ARGV.first}`}
elsif line[0..7] == 'msgstr "'
msgstr = line[8..-2]
end
-
+
if !path.empty? and !msgstr.empty?
add_translation(trs, path, msgstr)
path = []
puts "<tr><th>Nodes</th><td>#{day_count}</td><td>#{week_count}</td><td>#{month_count}</td></tr>"
puts "</table>"
-
+
puts "<h2>Top users editing over the past...</h2>"
puts "<table>"
puts "<tr><th>Day</th><th>Week</th><th>Month</th></tr>"
amf_content "getway", "/1", [id]
post :amf_read
assert_response :success
- amf_parse_response
+ amf_parse_response
way = amf_result("/1")
assert_equal 0, way[0]
assert_equal "", way[1]
amf_content "getway", "/1", [id]
post :amf_read
assert_response :success
- amf_parse_response
+ amf_parse_response
way = amf_result("/1")
assert_equal 0, way[0]
assert_equal "", way[1]
amf_content "getway", "/1", [id]
post :amf_read
assert_response :success
- amf_parse_response
+ amf_parse_response
way = amf_result("/1")
assert_equal 0, way[0]
assert_equal "", way[1]
amf_content "getway", "/1", [id]
post :amf_read
assert_response :success
- amf_parse_response
+ amf_parse_response
way = amf_result("/1")
assert_equal 0, way[0]
assert_equal "", way[1]
amf_content "whichways", "/1", [minlon, minlat, maxlon, maxlat]
post :amf_read
assert_response :success
- amf_parse_response
+ amf_parse_response
# check contents of message
map = amf_result "/1"
amf_content "whichways_deleted", "/1", bbox
post :amf_read
assert_response :success
- amf_parse_response
+ amf_parse_response
map = amf_result "/1"
assert_deleted_boundary_error map, " The server said: The maximum bbox size is 0.25, and your request was too large. Either request a smaller area, or use planet.osm"
# instead of a version number...
# try to get version 1
v1 = ways(:way_with_versions_v1)
- { latest.id => '',
+ { latest.id => '',
v1.way_id => v1.timestamp.strftime("%d %b %Y, %H:%M:%S")
}.each do |id, t|
amf_content "getway_old", "/1", [id, t]
- post :amf_read
+ post :amf_read
assert_response :success
amf_parse_response
returned_way = amf_result("/1")
assert_equal latest.version, returned_way[5]
end
end
-
+
##
# test that the server doesn't fall over when rubbish is passed
# into the method args.
v1 = ways(:way_with_versions_v1)
# try to get last visible version of non-existent way
# try to get specific version of non-existent way
- [[0, ''],
- [0, '1 Jan 1970, 00:00:00'],
+ [[0, ''],
+ [0, '1 Jan 1970, 00:00:00'],
[v1.way_id, (v1.timestamp - 10).strftime("%d %b %Y, %H:%M:%S")]
].each do |id, t|
amf_content "getway_old", "/1", [id, t]
# ['way',wayid,history]
assert_equal 'way', history[0]
- assert_equal latest.id, history[1]
+ assert_equal latest.id, history[1]
# We use dates rather than version numbers here, because you might
# have moved a node within a way (i.e. way version not incremented).
# The timestamp is +1 because we say "give me the revision of 15:33:02",
# ['node',nodeid,history]
# note that (as per getway_history) we actually round up
# to the next second
- assert_equal history[0], 'node',
+ assert_equal history[0], 'node',
'first element should be "node"'
assert_equal history[1], latest.id,
'second element should be the input node ID'
- assert_equal history[2].first[0],
+ assert_equal history[2].first[0],
(latest.timestamp + 1).strftime("%d %b %Y, %H:%M:%S"),
'first element in third element (array) should be the latest version'
- assert_equal history[2].last[0],
+ assert_equal history[2].last[0],
(nodes(:node_with_versions_v1).timestamp + 1).strftime("%d %b %Y, %H:%M:%S"),
'last element in third element (array) should be the initial version'
end
assert_response :success
amf_parse_response
result = amf_result("/1")
-
+
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]
-
+
# Now try to update again, with a different lat/lon, using the updated version number
lat = nd.lat+0.1
lon = nd.lon-0.1
assert_response :success
amf_parse_response
result = amf_result("/2")
-
+
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+2, result[4]
end
-
+
# Check that we can create a no valid poi
# Using similar method for the node controller test
def test_putpoi_create_valid
lon = rand(100)-50 + rand
# normal user has a changeset open
changeset = changesets(:public_user_first_change)
-
+
amf_content "putpoi", "/1", ["test@example.com:test", changeset.id, nil, nil, lon, lat, {}, nil]
post :amf_write
assert_response :success
amf_parse_response
result = amf_result("/1")
-
+
# check the array returned by the amf
assert_equal 5, result.size
assert_equal 0, result[0], "expected to get the status ok from the amf"
assert_equal 0, result[2], "The old id should be 0"
assert result[3] > 0, "The new id should be greater than 0"
assert_equal 1, result[4], "The new version should be 1"
-
- # Finally check that the node that was saved has saved the data correctly
+
+ # Finally check that the node that was saved has saved the data correctly
# in both the current and history tables
# First check the current table
current_node = Node.find(result[3].to_i)
assert_in_delta lon, first_historic_node.lon, 0.00001, "The longitude was not retreuved correctly"
assert_equal 0, first_historic_node.tags.size, "There seems to be a tag that have been attached to this node"
assert_equal result[4], first_historic_node.version, "The version returned, is different to the one returned by the amf"
-
+
####
# This node has some tags
tnd = Node.new
lon = rand(100)-50 + rand
# normal user has a changeset open
changeset = changesets(:public_user_first_change)
-
+
amf_content "putpoi", "/2", ["test@example.com:test", changeset.id, nil, nil, lon, lat, { "key" => "value", "ping" => "pong" }, nil]
post :amf_write
assert_response :success
assert_equal 0, result[2], "The old id should be 0"
assert result[3] > 0, "The new id should be greater than 0"
assert_equal 1, result[4], "The new version should be 1"
-
- # Finally check that the node that was saved has saved the data correctly
+
+ # Finally check that the node that was saved has saved the data correctly
# in both the current and history tables
# First check the current table
current_node = Node.find(result[3].to_i)
assert_equal({ "key" => "value", "ping" => "pong" }, first_historic_node.tags, "tags are different")
assert_equal result[4], first_historic_node.version, "The version returned, is different to the one returned by the amf"
end
-
+
# try creating a POI with rubbish in the tags
def test_putpoi_create_with_control_chars
# This node has no tags
lon = rand(100)-50 + rand
# normal user has a changeset open
changeset = changesets(:public_user_first_change)
-
+
mostly_invalid = (0..31).to_a.map {|i| i.chr}.join
tags = { "something" => "foo#{mostly_invalid}bar" }
-
+
amf_content "putpoi", "/1", ["test@example.com:test", changeset.id, nil, nil, lon, lat, tags, nil]
post :amf_write
assert_response :success
amf_parse_response
result = amf_result("/1")
-
+
# check the array returned by the amf
assert_equal 5, result.size
assert_equal 0, result[0], "Expected to get the status ok in the amf"
assert_equal 0, result[2], "The old id should be 0"
assert result[3] > 0, "The new id should be greater than 0"
assert_equal 1, result[4], "The new version should be 1"
-
- # Finally check that the node that was saved has saved the data correctly
+
+ # Finally check that the node that was saved has saved the data correctly
# in both the current and history tables
# First check the current table
current_node = Node.find(result[3].to_i)
lon = rand(100)-50 + rand
# normal user has a changeset open
changeset = changesets(:public_user_first_change)
-
+
invalid = "\xc0\xc0"
tags = { "something" => "foo#{invalid}bar" }
-
+
amf_content "putpoi", "/1", ["test@example.com:test", changeset.id, nil, nil, lon, lat, tags, nil]
post :amf_write
assert_response :success
assert_equal 2, result.size
assert_equal -1, result[0], "Expected to get the status FAIL in the amf"
- assert_equal "One of the tags is invalid. Linux users may need to upgrade to Flash Player 10.1.", result[1]
+ assert_equal "One of the tags is invalid. Linux users may need to upgrade to Flash Player 10.1.", result[1]
end
-
+
def test_putpoi_delete_valid
-
+
end
-
+
def test_putpoi_delete_already_deleted
-
+
end
-
+
def test_putpoi_delete_not_found
-
+
end
-
+
def test_putpoi_invalid_latlon
-
+
end
def test_startchangeset_invalid_xmlchar_comment
invalid = "\035\022"
comment = "foo#{invalid}bar"
-
+
amf_content "startchangeset", "/1", ["test@example.com:test", Hash.new, nil, comment, 1]
post :amf_write
assert_response :success
yield map, bbox
end
end
-
+
# this should be what AMF controller returns when the bbox of a
# whichways request is invalid or too large.
def assert_boundary_error(map, msg=nil, error_hint=nil)
class ApiControllerTest < ActionController::TestCase
api_fixtures
-
+
def setup
super
@badbigbbox = %w{ -0.1,-0.1,1.1,1.1 10,10,11,11 }
- @badmalformedbbox = %w{ -0.1 hello
+ @badmalformedbbox = %w{ -0.1 hello
10N2W10.1N2.1W }
@badlatmixedbbox = %w{ 0,0.1,0.1,0 -0.1,80,0.1,70 0.24,54.34,0.25,54.33 }
- @badlonmixedbbox = %w{ 80,-0.1,70,0.1 54.34,0.24,54.33,0.25 }
+ @badlonmixedbbox = %w{ 80,-0.1,70,0.1 54.34,0.24,54.33,0.25 }
#@badlatlonoutboundsbbox = %w{ 191,-0.1,193,0.1 -190.1,89.9,-190,90 }
- @goodbbox = %w{ -0.1,-0.1,0.1,0.1 51.1,-0.1,51.2,0
+ @goodbbox = %w{ -0.1,-0.1,0.1,0.1 51.1,-0.1,51.2,0
-0.1,%20-0.1,%200.1,%200.1 -0.1edcd,-0.1d,0.1,0.1 -0.1E,-0.1E,0.1S,0.1N S0.1,W0.1,N0.1,E0.1}
# That last item in the goodbbox really shouldn't be there, as the API should
# reall reject it, however this is to test to see if the api changes.
{ :controller => "api", :action => "capabilities" }
)
assert_recognizes(
- { :controller => "api", :action => "capabilities" },
+ { :controller => "api", :action => "capabilities" },
{ :path => "/api/0.6/capabilities", :method => :get }
)
assert_routing(
# Should also test for the ways and relation
end
end
-
+
# This differs from the above test in that we are making the bbox exactly
# the same as the node we are looking at
def test_map_inclusive
# Should also test for the ways and relation
end
end
-
+
def test_tracepoints
point = gpx_files(:public_trace_file)
minlon = point.longitude-0.001
end
end
end
-
+
def test_tracepoints_trackable
point = gpx_files(:trackable_trace_file)
minlon = point.longitude-0.002
end
end
end
-
+
def test_tracepoints_identifiable
point = gpx_files(:identifiable_trace_file)
minlon = point.longitude-0.002
end
end
end
-
+
def test_map_without_bbox
["trackpoints", "map"].each do |tq|
get tq
assert_equal "The parameter bbox is required, and must be of the form min_lon,min_lat,max_lon,max_lat", @response.body, "A bbox param was expected"
end
end
-
+
def test_traces_page_less_than_0
-10.upto(-1) do |i|
get :trackpoints, :page => i, :bbox => "-0.1,-0.1,0.1,0.1"
assert_response :success, "The page number was #{i} and should have been accepted"
end
end
-
+
def test_bbox_too_big
@badbigbbox.each do |bbox|
[ "trackpoints", "map" ].each do |tq|
end
end
end
-
+
def test_bbox_malformed
@badmalformedbbox.each do |bbox|
[ "trackpoints", "map" ].each do |tq|
end
end
end
-
+
def test_bbox_lon_mixedup
@badlonmixedbbox.each do |bbox|
[ "trackpoints", "map" ].each do |tq|
end
end
end
-
+
def test_bbox_lat_mixedup
@badlatmixedbbox.each do |bbox|
["trackpoints", "map"].each do |tq|
end
end
end
-
+
# We can't actually get an out of bounds error, as the bbox is sanitised.
#def test_latlon_outofbounds
# @badlatlonoutboundsbbox.each do |bbox|
# end
# end
#end
-
- # MySQL and Postgres require that the C based functions are installed for
+
+ # MySQL and Postgres require that the C based functions are installed for
# this test to work. More information is available from:
# http://wiki.openstreetmap.org/wiki/Rails#Installing_the_quadtile_functions
# or by looking at the readme in db/README
get :changes
assert_response :success
#print @response.body
- # As we have loaded the fixtures, we can assume that there are no
+ # As we have loaded the fixtures, we can assume that there are no
# changes at the time we have frozen at
now = Time.now.getutc
hourago = now - 1.hour
end
Timecop.return
end
-
+
def test_changes_zoom_invalid
zoom_to_test = %w{ p -1 0 17 one two }
zoom_to_test.each do |zoom|
assert_equal @response.body, "Requested zoom is invalid, or the supplied start is after the end time, or the start duration is more than 24 hours"
end
end
-
+
def test_changes_zoom_valid
1.upto(16) do |zoom|
get :changes, :zoom => zoom
end
end
end
-
+
def test_hours_invalid
invalid = %w{ -21 335 -1 0 25 26 100 one two three ping pong : }
invalid.each do |hour|
assert_equal @response.body, "Requested zoom is invalid, or the supplied start is after the end time, or the start duration is more than 24 hours", "Problem with the hour: #{hour}."
end
end
-
+
def test_hours_valid
1.upto(24) do |hour|
get :changes, :hours => hour
assert_response :success
end
end
-
+
def test_capabilities
get :capabilities
assert_response :success
assert_no_difference('ChangesetComment.count') do
post :comment, { :id => changesets(:normal_user_closed_change).id, :text => '' }
end
- assert_response :bad_request
+ assert_response :bad_request
end
##
post :unhide_comment, { :id => comment.id }
assert_response :unauthorized
end
-
+
basic_authorization(users(:public_user).email, 'test')
# not a moderator
get :new
assert_response :redirect
assert_redirected_to :controller => :user, :action => "login", :referer => "/diary/new"
- # Now pretend to login by using the session hash, with the
+ # Now pretend to login by using the session hash, with the
# id of the person we want to login as through session(:user)=user.id
get(:new, nil, {'user' => users(:normal_user).id})
assert_response :success
#print @response.body
-
+
#print @response.to_yaml
assert_select "title", :text => /New Diary Entry/, :count => 1
assert_select "div.content-heading", :count => 1 do
end
end
end
-
+
def test_editing_diary_entry
entry = diary_entries(:normal_user_entry_1)
- # Make sure that you are redirected to the login page when you are
+ # Make sure that you are redirected to the login page when you are
# not logged in, without and with the id of the entry you want to edit
get :edit, :display_name => entry.user.display_name, :id => entry.id
assert_response :redirect
assert_redirected_to :controller => :user, :action => "login", :referer => "/user/#{entry.user.display_name}/diary/#{entry.id}/edit"
-
+
# Verify that you get a not found error, when you pass a bogus id
get(:edit, {:display_name => entry.user.display_name, :id => 9999}, {'user' => entry.user.id})
assert_response :not_found
assert_select "h2", :text => "No entry with the id: 9999", :count => 1
end
- # Now pass the id, and check that you can edit it, when using the same
+ # Now pass the id, and check that you can edit it, when using the same
# user as the person who created the entry
get(:edit, {:display_name => entry.user.display_name, :id => entry.id}, {'user' => entry.user.id})
assert_response :success
new_latitude = "1.1"
new_longitude = "2.2"
new_language_code = "en"
- post(:edit, {:display_name => entry.user.display_name, :id => entry.id, 'commit' => 'save',
+ post(:edit, {:display_name => entry.user.display_name, :id => entry.id, 'commit' => 'save',
'diary_entry'=>{'title' => new_title, 'body' => new_body, 'latitude' => new_latitude,
'longitude' => new_longitude, 'language_code' => new_language_code} },
{'user' => entry.user.id})
assert_response :redirect
assert_redirected_to :action => :view, :display_name => entry.user.display_name, :id => entry.id
-
+
# Now check that the new data is rendered, when logged in
get :view, {:display_name => entry.user.display_name, :id => entry.id}, {'user' => entry.user.id}
assert_response :success
end
end
end
-
+
def test_edit_diary_entry_i18n
get :edit, {:display_name => users(:normal_user).display_name, :id => diary_entries(:normal_user_entry_1).id}, {'user' => users(:normal_user).id}
assert_response :success
assert_select "span[class=translation_missing]", false, "Missing translation in edit diary entry"
end
-
+
def test_create_diary_entry
# Make sure that you are redirected to the login page when you
# are not logged in
new_longitude = "2.2"
new_language_code = "en"
assert_difference "DiaryEntry.count", 1 do
- post(:new, {'commit' => 'save',
+ post(:new, {'commit' => 'save',
'diary_entry'=>{'title' => new_title, 'body' => new_body, 'latitude' => new_latitude,
'longitude' => new_longitude, 'language_code' => new_language_code} },
{:user => users(:normal_user).id})
assert_equal new_longitude.to_f, entry.longitude
assert_equal new_language_code, entry.language_code
end
-
+
def test_creating_diary_comment
entry = diary_entries(:normal_user_entry_1)
# Make sure that you are denied when you are not logged in
post :comment, :display_name => entry.user.display_name, :id => entry.id
assert_response :forbidden
-
+
# Verify that you get a not found error, when you pass a bogus id
post :comment, {:display_name => entry.user.display_name, :id => 9999}, {:user => users(:public_user).id}
assert_response :not_found
assert_select ".richtext", :text => /New comment/, :count => 1
end
end
-
+
# Check that you can get the expected response and template for all available languages
# Should test that there are no <span class="translation_missing">
def test_listing_diary_entries
assert_response :success, "Should be able to list the diary entries in locale"
assert_template 'list', "Should use the list template in locale"
assert_select "span[class=translation_missing]", false, "Missing translation in list of diary entries"
-
+
# Now try to find a specific user's diary entry
get :list, {:display_name => users(:normal_user).display_name}
assert_response :success, "Should be able to list the diary entries for a user in locale"
assert_template 'list', "Should use the list template for a user in locale"
assert_no_missing_translations
end
-
+
def test_rss
get :rss, {:format => :rss}
assert_response :success, "Should be able to get a diary RSS"
end
end
end
-
+
def test_rss_language
get :rss, {:language => diary_entries(:normal_user_entry_1).language_code, :format => :rss}
assert_response :success, "Should be able to get a specific language diary RSS"
assert_select "rss>channel>item", :count => 1 #, "Diary entries should be filtered by language"
end
-
+
# def test_rss_nonexisting_language
# get :rss, {:language => 'xx', :format => :rss}
# assert_response :not_found, "Should not be able to get a nonexisting language diary RSS"
assert_response :success, "Should be able to get a specific users diary RSS"
assert_select "rss>channel>item", :count => 2 #, "Diary entries should be filtered by user"
end
-
+
def test_rss_nonexisting_user
# Try a user that has never existed
get :rss, {:display_name => 'fakeUsername76543', :format => :rss}
assert_response :redirect
assert_redirected_to "http://api.openstreetmap.org/api/#{API_VERSION}/map?bbox=0.0,50.0,1.0,51.0"
end
-
+
###
# test the finish action for mapnik images
def test_finish_mapnik
def test_create
# cannot read password from fixture as it is stored as MD5 digest
## First try with no auth
-
+
# create a node with random lat/lon
lat = rand(100)-50 + rand
lon = rand(100)-50 + rand
# hope for unauthorized
assert_response :unauthorized, "node upload did not return unauthorized status"
-
-
+
+
## Now try with the user which doesn't have their data public
basic_authorization(users(:normal_user).email, "test")
-
+
# create a node with random lat/lon
lat = rand(100)-50 + rand
lon = rand(100)-50 + rand
assert_require_public_data "node create did not return forbidden status"
-
+
## Now try with the user that has the public data
basic_authorization(users(:public_user).email, "test")
-
+
# create a node with random lat/lon
lat = rand(100)-50 + rand
lon = rand(100)-50 + rand
changeset = changesets(:public_user_first_change)
lat = 3.434
lon = 3.23
-
+
# test that the upload is rejected when xml is valid, but osm doc isn't
content("<create/>")
put :create
## first try to delete node without auth
delete :delete, :id => current_nodes(:visible_node).id
assert_response :unauthorized
-
-
+
+
## now set auth for the non-data public user
- basic_authorization(users(:normal_user).email, "test");
+ basic_authorization(users(:normal_user).email, "test");
# try to delete with an invalid (closed) changeset
content update_changeset(current_nodes(:visible_node).to_xml,
assert_require_public_data
"shouldn't be able to delete a node used in a relation (#{@response.body})"
-
+
## now set auth for the public data user
- basic_authorization(users(:public_user).email, "test");
+ basic_authorization(users(:public_user).email, "test");
# try to delete with an invalid (closed) changeset
content update_changeset(current_nodes(:visible_node).to_xml,
# try to delete a node with a different ID
content(nodes(:public_visible_node).to_xml)
delete :delete, :id => current_nodes(:visible_node).id
- assert_response :bad_request,
+ assert_response :bad_request,
"should not be able to delete a node with a different ID from the XML"
# try to delete a node rubbish in the payloads
content("<delete/>")
delete :delete, :id => current_nodes(:visible_node).id
- assert_response :bad_request,
+ assert_response :bad_request,
"should not be able to delete a node without a valid XML payload"
# valid delete now takes a payload
content current_nodes(:visible_node).to_xml
put :update, :id => current_nodes(:visible_node).id
assert_response :unauthorized
-
-
-
+
+
+
## Second test with the private user
-
+
# setup auth
basic_authorization(users(:normal_user).email, "test")
content xml_attr_rewrite(current_nodes(:visible_node).to_xml, 'lat', -91.0);
put :update, :id => current_nodes(:visible_node).id
assert_require_public_data "node at lat=-91 should be forbidden, when data isn't public"
-
+
content xml_attr_rewrite(current_nodes(:visible_node).to_xml, 'lon', 181.0);
put :update, :id => current_nodes(:visible_node).id
assert_require_public_data "node at lon=181 should be forbidden, when data isn't public"
content xml_attr_rewrite(current_nodes(:visible_node).to_xml, 'lon', -181.0);
put :update, :id => current_nodes(:visible_node).id
assert_require_public_data "node at lon=-181 should be forbidden, when data isn't public"
-
+
## finally, produce a good request which should work
content current_nodes(:visible_node).to_xml
put :update, :id => current_nodes(:visible_node).id
assert_require_public_data "should have failed with a forbidden when data isn't public"
-
+
## Finally test with the public user
-
+
# try and update a node without authorisation
# first try to delete node without auth
content current_nodes(:visible_node).to_xml
put :update, :id => current_nodes(:visible_node).id
assert_response :forbidden
-
+
# setup auth
basic_authorization(users(:public_user).email, "test")
content xml_attr_rewrite(current_nodes(:visible_node).to_xml, 'lat', -91.0);
put :update, :id => current_nodes(:visible_node).id
assert_response :bad_request, "node at lat=-91 should be rejected"
-
+
content xml_attr_rewrite(current_nodes(:visible_node).to_xml, 'lon', 181.0);
put :update, :id => current_nodes(:visible_node).id
assert_response :bad_request, "node at lon=181 should be rejected"
current_node_version = current_nodes(:visible_node).version
# try and submit a version behind
- content xml_attr_rewrite(current_nodes(:visible_node).to_xml,
+ content xml_attr_rewrite(current_nodes(:visible_node).to_xml,
'version', current_node_version - 1);
put :update, :id => current_nodes(:visible_node).id
assert_response :conflict, "should have failed on old version number"
-
+
# try and submit a version ahead
- content xml_attr_rewrite(current_nodes(:visible_node).to_xml,
+ content xml_attr_rewrite(current_nodes(:visible_node).to_xml,
'version', current_node_version + 1);
put :update, :id => current_nodes(:visible_node).id
assert_response :conflict, "should have failed on skipped version number"
# try and submit total crap in the version field
- content xml_attr_rewrite(current_nodes(:visible_node).to_xml,
+ content xml_attr_rewrite(current_nodes(:visible_node).to_xml,
'version', 'p1r4t3s!');
put :update, :id => current_nodes(:visible_node).id
- assert_response :conflict,
+ assert_response :conflict,
"should not be able to put 'p1r4at3s!' in the version field"
-
+
## try an update with the wrong ID
content current_nodes(:public_visible_node).to_xml
put :update, :id => current_nodes(:visible_node).id
- assert_response :bad_request,
+ assert_response :bad_request,
"should not be able to update a node with a different ID from the XML"
## try an update with a minimal valid XML doc which isn't a well-formed OSM doc.
content "<update/>"
put :update, :id => current_nodes(:visible_node).id
- assert_response :bad_request,
+ assert_response :bad_request,
"should not be able to update a node with non-OSM XML doc."
## finally, produce a good request which should work
# try and upload it
content node_xml
put :update, :id => current_nodes(:public_visible_node).id
- assert_response :bad_request,
+ assert_response :bad_request,
"adding duplicate tags to a node should fail with 'bad request'"
assert_equal "Element node/#{current_nodes(:public_visible_node).id} has duplicate tags with key #{current_node_tags(:t1).k}", @response.body
end
basic_authorization(users(:normal_user).email, "test")
changeset_id = changesets(:normal_user_first_change).id
- # try and put something into a string that the API might
+ # try and put something into a string that the API might
# use unquoted and therefore allow code injection...
content "<osm><node lat='0' lon='0' changeset='#{changeset_id}'>" +
'<tag k="#{@user.inspect}" v="0"/>' +
'</node></osm>'
put :create
assert_require_public_data "Shouldn't be able to create with non-public user"
-
-
+
+
## Then try with the public data user
basic_authorization(users(:public_user).email, "test")
changeset_id = changesets(:public_user_first_change).id
- # try and put something into a string that the API might
+ # try and put something into a string that the API might
# use unquoted and therefore allow code injection...
content "<osm><node lat='0' lon='0' changeset='#{changeset_id}'>" +
'<tag k="#{@user.inspect}" v="0"/>' +
# find the node in the database
checknode = Node.find(nodeid)
assert_not_nil checknode, "node not found in data base after upload"
-
+
# and grab it using the api
get :read, :id => nodeid
assert_response :success
apinode = Node.from_xml(@response.body)
assert_not_nil apinode, "downloaded node is nil, but shouldn't be"
-
+
# check the tags are not corrupted
assert_equal checknode.tags, apinode.tags
assert apinode.tags.include?('#{@user.inspect}')
end
get :feed, {:bbox => "1,1,1.2,1.2", :format => "rss"}
- assert_response :success
+ assert_response :success
assert_equal "application/rss+xml", @response.content_type
assert_select "rss", :count => 1 do
assert_select "channel", :count => 1 do
assert_response :success
get :mine, {:display_name => "non-existent"}
- assert_response :not_found
+ assert_response :not_found
end
end
}
end
assert_response :success
- assert_template "new"
-
+ assert_template "new"
+
assert_difference "ClientApplication.count", 1 do
post :create, {
:display_name => user.display_name,
assert_template "not_found"
put :update, {
- :display_name => user.display_name,
+ :display_name => user.display_name,
:id => client.id,
:client_application => {
:name => "New Name",
assert_template "edit"
put :update, {
- :display_name => user.display_name,
+ :display_name => user.display_name,
:id => client.id,
:client_application => {
:name => "New Name",
##
# test the version call by submitting several revisions of a new node
- # to the API and ensuring that later calls to version return the
+ # to the API and ensuring that later calls to version return the
# matching versions of the object.
#
##
- # FIXME Move this test to being an integration test since it spans multiple controllers
+ # FIXME Move this test to being an integration test since it spans multiple controllers
def test_version
## First try this with a non-public user
basic_authorization(users(:normal_user).email, "test")
changeset_id = changesets(:normal_user_first_change).id
-
+
# setup a simple XML node
xml_doc = current_nodes(:visible_node).to_xml
xml_node = xml_doc.find("//osm/node").first
versions[xml_node['version']] = xml_doc.to_s
# randomly move the node about
- 20.times do
+ 20.times do
# move the node somewhere else
xml_node['lat'] = precision(rand * 180 - 90).to_s
xml_node['lon'] = precision(rand * 360 - 180).to_s
end
# add a bunch of random tags
- 30.times do
+ 30.times do
xml_tag = XML::Node.new("tag")
xml_tag['k'] = random_string
xml_tag['v'] = random_string
# probably should check that they didn't get written to the database
-
+
## Now do it with the public user
basic_authorization(users(:public_user).email, "test")
changeset_id = changesets(:public_user_first_change).id
versions[xml_node['version']] = xml_doc.to_s
# randomly move the node about
- 20.times do
+ 20.times do
# move the node somewhere else
xml_node['lat'] = precision(rand * 180 - 90).to_s
xml_node['lon'] = precision(rand * 360 - 180).to_s
end
# add a bunch of random tags
- 30.times do
+ 30.times do
xml_tag = XML::Node.new("tag")
xml_tag['k'] = random_string
xml_tag['v'] = random_string
assert_nodes_are_equal check_node, api_node
end
end
-
+
def test_not_found_version
check_not_found_id_version(70000,312344)
check_not_found_id_version(-1, -13)
check_not_found_id_version(nodes(:visible_node).id, 24354)
check_not_found_id_version(24356, nodes(:visible_node).version)
end
-
+
def check_not_found_id_version(id, version)
get :version, :id => id, :version => version
assert_response :not_found
rescue ActionController::UrlGenerationError => ex
assert_match /No route matches/, ex.to_s
end
-
+
##
# Test that getting the current version is identical to picking
# that version with the version URI call.
end
##
- # test the redaction of an old version of a node, while being
+ # test the redaction of an old version of a node, while being
# authorised as a normal user.
def test_redact_node_normal_user
basic_authorization(users(:public_user).email, "test")
do_redact_node(nodes(:node_with_versions_v4),
redactions(:example))
assert_response :bad_request, "shouldn't be OK to redact current version as moderator."
- end
+ end
##
- # test that redacted nodes aren't visible, regardless of
+ # test that redacted nodes aren't visible, regardless of
# authorisation except as moderator...
def test_version_redacted
node = nodes(:redacted_node_redacted_version)
end
##
- # test the redaction of an old version of a node, while being
+ # test the redaction of an old version of a node, while being
# authorised as a moderator.
def test_redact_node_moderator
node = nodes(:node_with_versions_v3)
assert_response :forbidden, "After redaction, node should be gone for moderator, when flag not passed."
get :version, :id => node.node_id, :version => node.version, :show_redactions => 'true'
assert_response :success, "After redaction, node should not be gone for moderator, when flag passed."
-
+
# and when accessed via history
get :history, :id => node.node_id
assert_response :success, "Redaction shouldn't have stopped history working."
# check can't see the redacted data
get :version, :id => node.node_id, :version => node.version
assert_response :forbidden, "Redacted node shouldn't be visible via the version API."
-
+
# and when accessed via history
get :history, :id => node.node_id
assert_response :success, "Redaction shouldn't have stopped history working."
def do_redact_node(node, redaction)
get :version, :id => node.node_id, :version => node.version
assert_response :success, "should be able to get version #{node.version} of node #{node.node_id}."
-
+
# now redact it
post :redact, :id => node.node_id, :version => node.version, :redaction => redaction.id
end
# get the current version of the node
current_node = with_controller(NodeController.new) do
get :read, :id => node_id
- assert_response :success, "cant get current node #{node_id}"
+ assert_response :success, "cant get current node #{node_id}"
Node.from_xml(@response.body)
end
assert_not_nil current_node, "getting node #{node_id} returned nil"
# get the "old" version of the node from the old_node interface
get :version, :id => node_id, :version => current_node.version
- assert_response :success, "cant get old node #{node_id}, v#{current_node.version}"
+ assert_response :success, "cant get old node #{node_id}, v#{current_node.version}"
old_node = Node.from_xml(@response.body)
# check the nodes are the same
end
##
- # test the redaction of an old version of a relation, while being
+ # test the redaction of an old version of a relation, while being
# authorised as a normal user.
def test_redact_relation_normal_user
basic_authorization(users(:public_user).email, "test")
do_redact_relation(relations(:relation_with_versions_v4),
redactions(:example))
assert_response :bad_request, "shouldn't be OK to redact current version as moderator."
- end
+ end
##
- # test that redacted relations aren't visible, regardless of
+ # test that redacted relations aren't visible, regardless of
# authorisation except as moderator...
def test_version_redacted
relation = relations(:relation_with_redacted_versions_v2)
end
##
- # test the redaction of an old version of a relation, while being
+ # test the redaction of an old version of a relation, while being
# authorised as a moderator.
def test_redact_relation_moderator
relation = relations(:relation_with_versions_v3)
assert_response :forbidden, "After redaction, node should be gone for moderator, when flag not passed."
get :version, :id => relation.relation_id, :version => relation.version, :show_redactions => 'true'
assert_response :success, "After redaction, node should not be gone for moderator, when flag passed."
-
+
# and when accessed via history
get :history, :id => relation.relation_id
assert_response :success, "Redaction shouldn't have stopped history working."
# check can't see the redacted data
get :version, :id => relation.relation_id, :version => relation.version
assert_response :forbidden, "Redacted node shouldn't be visible via the version API."
-
+
# and when accessed via history
get :history, :id => relation.relation_id
assert_response :success, "Redaction shouldn't have stopped history working."
assert_response :success, "couldn't get relation #{relation_id}, v#{history_relation.version}"
version_relation = Relation.from_xml(@response.body)
assert_not_nil version_relation, "failed to parse #{relation_id}, v#{history_relation.version}"
-
+
assert_relations_are_equal history_relation, version_relation
end
end
def do_redact_relation(relation, redaction)
get :version, :id => relation.relation_id, :version => relation.version
assert_response :success, "should be able to get version #{relation.version} of node #{relation.relation_id}."
-
+
# now redact it
post :redact, :id => relation.relation_id, :version => relation.version, :redaction => redaction.id
end
get :history, :id => ways(:visible_way).way_id
assert_response :success
end
-
+
def test_history_invisible
# check that an invisible way's history is returned properly
get :history, :id => ways(:invisible_way).way_id
assert_response :success
end
-
+
def test_history_invalid
# check chat a non-existent way is not returned
get :history, :id => 0
assert_response :not_found
end
-
+
##
# check that we can retrieve versions of a way
def test_version
end
##
- # check that returned history is the same as getting all
+ # check that returned history is the same as getting all
# versions of a way from the api.
def test_history_equals_versions
check_history_equals_versions(current_ways(:visible_way).id)
end
##
- # test the redaction of an old version of a way, while being
+ # test the redaction of an old version of a way, while being
# authorised as a normal user.
def test_redact_way_normal_user
basic_authorization(users(:public_user).email, "test")
do_redact_way(ways(:way_with_versions_v4),
redactions(:example))
assert_response :bad_request, "shouldn't be OK to redact current version as moderator."
- end
+ end
##
- # test that redacted ways aren't visible, regardless of
+ # test that redacted ways aren't visible, regardless of
# authorisation except as moderator...
def test_version_redacted
way = ways(:way_with_redacted_versions_v2)
end
##
- # test the redaction of an old version of a way, while being
+ # test the redaction of an old version of a way, while being
# authorised as a moderator.
def test_redact_way_moderator
way = ways(:way_with_versions_v3)
assert_response :forbidden, "After redaction, node should be gone for moderator, when flag not passed."
get :version, :id => way.way_id, :version => way.version, :show_redactions => 'true'
assert_response :success, "After redaction, node should not be gone for moderator, when flag passed."
-
+
# and when accessed via history
get :history, :id => way.way_id
assert_response :success, "Redaction shouldn't have stopped history working."
# check can't see the redacted data
get :version, :id => way.way_id, :version => way.version
assert_response :forbidden, "Redacted node shouldn't be visible via the version API."
-
+
# and when accessed via history
get :history, :id => way.way_id
assert_response :success, "Redaction shouldn't have stopped history working."
assert_response :success, "couldn't get way #{way_id}, v#{history_way.version}"
version_way = Way.from_xml(@response.body)
assert_not_nil version_way, "failed to parse #{way_id}, v#{history_way.version}"
-
+
assert_ways_are_equal history_way, version_way
end
end
def do_redact_way(way, redaction)
get :version, :id => way.way_id, :version => way.version
assert_response :success, "should be able to get version #{way.version} of node #{way.way_id}."
-
+
# now redact it
post :redact, :id => way.way_id, :version => way.version, :redaction => redaction.id
end
# check that all relations containing a particular node, and no extra
# relations, are returned from the relations_for_node call.
def test_relations_for_node
- check_relations_for_element(:relations_for_node, "node",
+ check_relations_for_element(:relations_for_node, "node",
current_nodes(:node_used_by_relationship).id,
[ :visible_relation, :used_relation ])
end
def test_create
basic_authorization users(:normal_user).email, "test"
-
+
# put the relation in a dummy fixture changset
changeset_id = changesets(:normal_user_first_change).id
content "<osm><relation changeset='#{changeset_id}'><tag k='test' v='yes' /></relation></osm>"
put :create
# hope for forbidden, due to user
- assert_response :forbidden,
+ assert_response :forbidden,
"relation upload should have failed with forbidden"
###
"<tag k='test' v='yes' /></relation></osm>"
put :create
# hope for forbidden due to user
- assert_response :forbidden,
+ assert_response :forbidden,
"relation upload did not return forbidden status"
-
+
###
- # create an relation with a node as member, this time test that we don't
+ # create an relation with a node as member, this time test that we don't
# need a role attribute to be included
nid = current_nodes(:used_node_1).id
content "<osm><relation changeset='#{changeset_id}'>" +
"<tag k='test' v='yes' /></relation></osm>"
put :create
# hope for forbidden due to user
- assert_response :forbidden,
+ assert_response :forbidden,
"relation upload did not return forbidden status"
###
"<tag k='test' v='yes' /></relation></osm>"
put :create
# hope for forbidden, due to user
- assert_response :forbidden,
+ assert_response :forbidden,
"relation upload did not return success status"
## Now try with the public user
basic_authorization users(:public_user).email, "test"
-
+
# put the relation in a dummy fixture changset
changeset_id = changesets(:public_user_first_change).id
content "<osm><relation changeset='#{changeset_id}'><tag k='test' v='yes' /></relation></osm>"
put :create
# hope for success
- assert_response :success,
+ assert_response :success,
"relation upload did not return success status"
# read id of created relation and search for it
relationid = @response.body
checkrelation = Relation.find(relationid)
- assert_not_nil checkrelation,
+ assert_not_nil checkrelation,
"uploaded relation not found in data base after upload"
# compare values
- assert_equal checkrelation.members.length, 0,
+ assert_equal checkrelation.members.length, 0,
"saved relation contains members but should not"
- assert_equal checkrelation.tags.length, 1,
+ assert_equal checkrelation.tags.length, 1,
"saved relation does not contain exactly one tag"
assert_equal changeset_id, checkrelation.changeset.id,
"saved relation does not belong in the changeset it was assigned to"
- assert_equal users(:public_user).id, checkrelation.changeset.user_id,
+ assert_equal users(:public_user).id, checkrelation.changeset.user_id,
"saved relation does not belong to user that created it"
- assert_equal true, checkrelation.visible,
+ assert_equal true, checkrelation.visible,
"saved relation is not visible"
# ok the relation is there but can we also retrieve it?
get :read, :id => relationid
"<tag k='test' v='yes' /></relation></osm>"
put :create
# hope for success
- assert_response :success,
+ assert_response :success,
"relation upload did not return success status"
# read id of created relation and search for it
relationid = @response.body
checkrelation = Relation.find(relationid)
- assert_not_nil checkrelation,
+ assert_not_nil checkrelation,
"uploaded relation not found in data base after upload"
# compare values
- assert_equal checkrelation.members.length, 1,
+ assert_equal checkrelation.members.length, 1,
"saved relation does not contain exactly one member"
- assert_equal checkrelation.tags.length, 1,
+ assert_equal checkrelation.tags.length, 1,
"saved relation does not contain exactly one tag"
assert_equal changeset_id, checkrelation.changeset.id,
"saved relation does not belong in the changeset it was assigned to"
- assert_equal users(:public_user).id, checkrelation.changeset.user_id,
+ assert_equal users(:public_user).id, checkrelation.changeset.user_id,
"saved relation does not belong to user that created it"
- assert_equal true, checkrelation.visible,
+ assert_equal true, checkrelation.visible,
"saved relation is not visible"
# ok the relation is there but can we also retrieve it?
-
+
get :read, :id => relationid
assert_response :success
-
-
+
+
###
- # create an relation with a node as member, this time test that we don't
+ # create an relation with a node as member, this time test that we don't
# need a role attribute to be included
nid = current_nodes(:used_node_1).id
content "<osm><relation changeset='#{changeset_id}'>" +
"<tag k='test' v='yes' /></relation></osm>"
put :create
# hope for success
- assert_response :success,
+ assert_response :success,
"relation upload did not return success status"
# read id of created relation and search for it
relationid = @response.body
checkrelation = Relation.find(relationid)
- assert_not_nil checkrelation,
+ assert_not_nil checkrelation,
"uploaded relation not found in data base after upload"
# compare values
- assert_equal checkrelation.members.length, 1,
+ assert_equal checkrelation.members.length, 1,
"saved relation does not contain exactly one member"
- assert_equal checkrelation.tags.length, 1,
+ assert_equal checkrelation.tags.length, 1,
"saved relation does not contain exactly one tag"
assert_equal changeset_id, checkrelation.changeset.id,
"saved relation does not belong in the changeset it was assigned to"
- assert_equal users(:public_user).id, checkrelation.changeset.user_id,
+ assert_equal users(:public_user).id, checkrelation.changeset.user_id,
"saved relation does not belong to user that created it"
- assert_equal true, checkrelation.visible,
+ assert_equal true, checkrelation.visible,
"saved relation is not visible"
# ok the relation is there but can we also retrieve it?
-
+
get :read, :id => relationid
assert_response :success
"<tag k='test' v='yes' /></relation></osm>"
put :create
# hope for success
- assert_response :success,
+ assert_response :success,
"relation upload did not return success status"
# read id of created relation and search for it
relationid = @response.body
checkrelation = Relation.find(relationid)
- assert_not_nil checkrelation,
+ assert_not_nil checkrelation,
"uploaded relation not found in data base after upload"
# compare values
- assert_equal checkrelation.members.length, 2,
+ assert_equal checkrelation.members.length, 2,
"saved relation does not have exactly two members"
- assert_equal checkrelation.tags.length, 1,
+ assert_equal checkrelation.tags.length, 1,
"saved relation does not contain exactly one tag"
assert_equal changeset_id, checkrelation.changeset.id,
"saved relation does not belong in the changeset it was assigned to"
- assert_equal users(:public_user).id, checkrelation.changeset.user_id,
+ assert_equal users(:public_user).id, checkrelation.changeset.user_id,
"saved relation does not belong to user that created it"
- assert_equal true, checkrelation.visible,
+ assert_equal true, checkrelation.visible,
"saved relation is not visible"
# ok the relation is there but can we also retrieve it?
get :read, :id => relationid
##
# test that, when tags are updated on a relation, the correct things
- # happen to the correct tables and the API gives sensible results.
+ # happen to the correct tables and the API gives sensible results.
# this is to test a case that gregory marler noticed and posted to
# josm-dev.
## FIXME Move this to an integration test
##
# test that, when tags are updated on a relation when using the diff
- # upload function, the correct things happen to the correct tables
- # and the API gives sensible results. this is to test a case that
+ # upload function, the correct things happen to the correct tables
+ # and the API gives sensible results. this is to test a case that
# gregory marler noticed and posted to josm-dev.
def test_update_relation_tags_via_upload
basic_authorization users(:public_user).email, "test"
"</relation></osm>"
put :create
# expect failure
- assert_response :precondition_failed,
+ assert_response :precondition_failed,
"relation upload with invalid node did not return 'precondition failed'"
assert_equal "Precondition failed: Relation with id cannot be saved due to Node with id 0", @response.body
end
# -------------------------------------
def test_create_invalid_xml
basic_authorization users(:public_user).email, "test"
-
+
# put the relation in a dummy fixture changeset that works
changeset_id = changesets(:public_user_first_change).id
-
+
# create some xml that should return an error
content "<osm><relation changeset='#{changeset_id}'>" +
"<member type='type' ref='#{current_nodes(:used_node_1).id}' role=''/>" +
assert_match(/Cannot parse valid relation from xml string/, @response.body)
assert_match(/The type is not allowed only, /, @response.body)
end
-
-
+
+
# -------------------------------------
# Test deleting relations.
# -------------------------------------
-
+
def test_delete
## First try to delete relation without auth
delete :delete, :id => current_relations(:visible_relation).id
assert_response :unauthorized
-
-
+
+
## Then try with the private user, to make sure that you get a forbidden
basic_authorization(users(:normal_user).email, "test")
-
+
# this shouldn't work, as we should need the payload...
delete :delete, :id => current_relations(:visible_relation).id
assert_response :forbidden
delete :delete, :id => current_relations(:invisible_relation).id
assert_response :forbidden
- # this works now because the relation which was using this one
+ # this works now because the relation which was using this one
# has been deleted.
content(relations(:used_relation).to_xml)
delete :delete, :id => current_relations(:used_relation).id
delete :delete, :id => 0
assert_response :forbidden
-
+
## now set auth for the public user
- basic_authorization(users(:public_user).email, "test");
+ basic_authorization(users(:public_user).email, "test");
# this shouldn't work, as we should need the payload...
delete :delete, :id => current_relations(:visible_relation).id
# this won't work because the relation is in a changeset owned by someone else
content(relations(:used_relation).to_xml)
delete :delete, :id => current_relations(:used_relation).id
- assert_response :conflict,
+ assert_response :conflict,
"shouldn't be able to delete a relation in a changeset owned by someone else (#{@response.body})"
# this won't work because the relation in the payload is different to that passed
delete :delete, :id => current_relations(:used_relation).id
assert_not_equal relations(:public_used_relation).id, current_relations(:used_relation).id
assert_response :bad_request, "shouldn't be able to delete a relation when payload is different to the url"
-
+
# this won't work because the relation is in-use by another relation
content(relations(:public_used_relation).to_xml)
delete :delete, :id => current_relations(:public_used_relation).id
- assert_response :precondition_failed,
+ assert_response :precondition_failed,
"shouldn't be able to delete a relation used in a relation (#{@response.body})"
assert_equal "Precondition failed: The relation 5 is used in relation 6.", @response.body
content(relations(:invisible_relation).to_xml)
delete :delete, :id => current_relations(:invisible_relation).id
assert_response :gone
-
+
# Public visible relation needs to be deleted
content(relations(:public_visible_relation).to_xml)
delete :delete, :id => current_relations(:public_visible_relation).id
assert_response :success
- # this works now because the relation which was using this one
+ # this works now because the relation which was using this one
# has been deleted.
content(relations(:public_used_relation).to_xml)
delete :delete, :id => current_relations(:public_used_relation).id
- assert_response :success,
+ assert_response :success,
"should be able to delete a relation used in an old relation (#{@response.body})"
# this won't work since the relation never existed
new_tag['k'] = "some_new_tag"
new_tag['v'] = "some_new_value"
relation_element << new_tag
-
+
# update changeset ID to point to new changeset
update_changeset(relation_xml, changeset_id)
-
+
# upload the change
content relation_xml
put :update, :id => current_relations(:visible_relation).id
new_member['type'] = element.class.to_s.downcase
new_member['role'] = "some_role"
relation_element << new_member
-
+
# update changeset ID to point to new changeset
update_changeset(relation_xml, changeset_id)
-
+
# upload the change
content relation_xml
put :update, :id => current_relations(:visible_relation).id
assert_response :success, "can't update relation for add #{element.class}/bbox test: #{@response.body}"
- # get it back and check the ordering
+ # get it back and check the ordering
get :read, :id => relation_id
assert_response :success, "can't read back the relation: #{@response.body}"
check_ordering(relation_xml, @response.body)
end
end
end
-
+
##
- # remove a member from a relation and check the bounding box is
+ # remove a member from a relation and check the bounding box is
# only that element.
def test_remove_member_bounding_box
check_changeset_modify(BoundingBox.new(5,5,5,5)) do |changeset_id|
relation_xml.
find("//osm/relation/member[@type='node'][@ref='5']").
first.remove!
-
+
# update changeset ID to point to new changeset
update_changeset(relation_xml, changeset_id)
-
+
# upload the change
content relation_xml
put :update, :id => current_relations(:visible_relation).id
assert_response :success, "can't update relation for remove node/bbox test"
end
end
-
+
##
# check that relations are ordered
def test_relation_member_ordering
basic_authorization(users(:public_user).email, "test")
-
+
doc_str = <<OSM
<osm>
<relation changeset='4'>
end
end
- ##
+ ##
# check that relations can contain duplicate members
def test_relation_member_duplicates
doc_str = <<OSM
doc = XML::Parser.string(doc_str).parse
## First try with the private user
- basic_authorization(users(:normal_user).email, "test");
+ basic_authorization(users(:normal_user).email, "test");
content doc
put :create
assert_response :forbidden
## Now try with the public user
- basic_authorization(users(:public_user).email, "test");
+ basic_authorization(users(:public_user).email, "test");
content doc
put :create
</osm>
OSM
doc = XML::Parser.string(doc_str).parse
- basic_authorization(users(:public_user).email, "test");
+ basic_authorization(users(:public_user).email, "test");
content doc
put :create
##
# remove all the members from a relation. the result is pretty useless, but
# still technically valid.
- def test_remove_all_members
+ def test_remove_all_members
check_changeset_modify(BoundingBox.new(3,3,5,5)) do |changeset_id|
relation_xml = current_relations(:visible_relation).to_xml
relation_xml.
find("//osm/relation/member").
each {|m| m.remove!}
-
+
# update changeset ID to point to new changeset
update_changeset(relation_xml, changeset_id)
-
+
# upload the change
content relation_xml
put :update, :id => current_relations(:visible_relation).id
assert_response :success, "can't update relation for remove all members test"
checkrelation = Relation.find(current_relations(:visible_relation).id)
- assert_not_nil(checkrelation,
+ assert_not_nil(checkrelation,
"uploaded relation not found in database after upload")
assert_equal(0, checkrelation.members.length,
"relation contains members but they should have all been deleted")
end
end
-
+
# ============================================================
# utility functions
# ============================================================
# that the changeset bounding box is +bbox+.
def check_changeset_modify(bbox)
## First test with the private user to check that you get a forbidden
- basic_authorization(users(:normal_user).email, "test");
+ basic_authorization(users(:normal_user).email, "test");
# create a new changeset for this operation, so we are assured
# that the bounding box will be newly-generated.
assert_response :forbidden, "shouldn't be able to create changeset for modify test, as should get forbidden"
end
-
+
## Now do the whole thing with the public user
basic_authorization(users(:public_user).email, "test")
-
+
# create a new changeset for this operation, so we are assured
# that the bounding box will be newly-generated.
changeset_id = with_controller(ChangesetController.new) do
end
##
- # updates the relation (XML) +rel+ and
- # yields the new version of that relation into the block.
+ # updates the relation (XML) +rel+ and
+ # yields the new version of that relation into the block.
# the parsed XML doc is retured.
def with_update(rel)
rel_id = rel.find("//osm/relation").first["id"].to_i
##
# updates the relation (XML) +rel+ via the diff-upload API and
- # yields the new version of that relation into the block.
+ # yields the new version of that relation into the block.
# the parsed XML doc is retured.
def with_update_diff(rel)
rel_id = rel.find("//osm/relation").first["id"].to_i
post :upload, :id => cs_id
assert_response :success, "can't upload diff relation: #{@response.body}"
version = xml_parse(@response.body).find("//diffResult/relation").first["new_version"].to_i
- end
-
+ end
+
# now get the new version
get :read, :id => rel_id
assert_response :success
new_rel = xml_parse(@response.body)
-
+
yield new_rel
-
+
return version
end
##
# returns a k->v hash of tags from an xml doc
- def get_tags_as_hash(a)
+ def get_tags_as_hash(a)
a.find("//osm/relation/tag").sort_by { |v| v['k'] }.inject({}) do |h,v|
h[v['k']] = v['v']
h
end
end
-
+
##
- # assert that all tags on relation documents +a+ and +b+
+ # assert that all tags on relation documents +a+ and +b+
# are equal
def assert_tags_equal(a, b)
# turn the XML doc into tags hashes
assert_equal a_tags.keys, b_tags.keys, "Tag keys should be identical."
a_tags.each do |k, v|
- assert_equal v, b_tags[k],
+ assert_equal v, b_tags[k],
"Tags which were not altered should be the same. " +
"#{a_tags.inspect} != #{b_tags.inspect}"
end
basic_authorization(users(:normal_user).display_name, "test")
content gpx_files(:anon_trace_file).to_xml
put :api_update, :id => gpx_files(:public_trace_file).id
- assert_response :bad_request,
+ assert_response :bad_request,
"should not be able to update a trace with a different ID from the XML"
# And finally try an update that should work
class UserControllerTest < ActionController::TestCase
fixtures :users
-
+
##
# test all routes which lead to this controller
def test_routes
assert_template 'new'
assert_select "form > fieldset > div.form-row > input.field_with_errors#user_email"
end
-
+
def test_user_create_submit_duplicate_name
user = new_user
user.display_name = users(:public_user).display_name
assert_template 'new'
assert_select "form > fieldset > div.form-row > input.field_with_errors#user_display_name"
end
-
+
def test_user_create_submit_duplicate_name_uppercase
user = new_user
user.display_name = users(:public_user).display_name.upcase
assert_equal user.new_email, email.to.first
ActionMailer::Base.deliveries.clear
end
-
+
# Check that the user account page will display and contains some relevant
# information for the user
def test_user_view_account
# Test a non-existent user
get :view, {:display_name => "unknown"}
assert_response :not_found
-
+
# Test a normal user
get :view, {:display_name => "test"}
assert_response :success
assert_select "a[href='/user/test/blocks_by']", 0
assert_select "a[href='/blocks/new/test']", 0
end
-
+
# Test a user who has been blocked
get :view, {:display_name => "blocked"}
assert_response :success
assert_select "a[href='/user/blocked/blocks_by']", 0
assert_select "a[href='/blocks/new/blocked']", 0
end
-
+
# Test a moderator who has applied blocks
get :view, {:display_name => "moderator"}
assert_response :success
# check that nothing is returned when not logged in
get :api_details
assert_response :unauthorized
-
+
# check that we get a response when logged in
basic_authorization(users(:normal_user).email, "test")
get :api_details
assert_select "preference", :count => 0
end
end
-
+
# authenticate as a user with preferences
basic_authorization("test@openstreetmap.org", "test")
# otherwise it should say success
assert_response :success
-
+
# Check the way is correctly returned
assert_select "osm way[id='#{way.id}'][version='#{way.version}'][visible='#{way.visible}']", 1
-
- # check that each node in the way appears once in the output as a
+
+ # check that each node in the way appears once in the output as a
# reference and as the node element.
way.nodes.each do |n|
count = (way.nodes - (way.nodes - [n])).length
# use the first user's open changeset
changeset_id = changesets(:normal_user_first_change).id
-
+
# create a way with pre-existing nodes
content "<osm><way changeset='#{changeset_id}'>" +
- "<nd ref='#{nid1}'/><nd ref='#{nid2}'/>" +
+ "<nd ref='#{nid1}'/><nd ref='#{nid2}'/>" +
"<tag k='test' v='yes' /></way></osm>"
put :create
# hope for success
- assert_response :forbidden,
+ assert_response :forbidden,
"way upload did not return success status"
# read id of created way and search for it
wayid = @response.body
# use the first user's open changeset
changeset_id = changesets(:public_user_first_change).id
-
+
# create a way with pre-existing nodes
content "<osm><way changeset='#{changeset_id}'>" +
- "<nd ref='#{nid1}'/><nd ref='#{nid2}'/>" +
+ "<nd ref='#{nid1}'/><nd ref='#{nid2}'/>" +
"<tag k='test' v='yes' /></way></osm>"
put :create
# hope for success
- assert_response :success,
+ assert_response :success,
"way upload did not return success status"
# read id of created way and search for it
wayid = @response.body
checkway = Way.find(wayid)
- assert_not_nil checkway,
+ assert_not_nil checkway,
"uploaded way not found in data base after upload"
# compare values
- assert_equal checkway.nds.length, 2,
+ assert_equal checkway.nds.length, 2,
"saved way does not contain exactly one node"
- assert_equal checkway.nds[0], nid1,
+ assert_equal checkway.nds[0], nid1,
"saved way does not contain the right node on pos 0"
- assert_equal checkway.nds[1], nid2,
+ assert_equal checkway.nds[1], nid2,
"saved way does not contain the right node on pos 1"
assert_equal checkway.changeset_id, changeset_id,
"saved way does not belong to the correct changeset"
- assert_equal users(:public_user).id, checkway.changeset.user_id,
+ assert_equal users(:public_user).id, checkway.changeset.user_id,
"saved way does not belong to user that created it"
- assert_equal true, checkway.visible,
+ assert_equal true, checkway.visible,
"saved way is not visible"
end
nid1 = current_nodes(:used_node_1).id
# create a way with non-existing node
- content "<osm><way changeset='#{open_changeset_id}'>" +
+ content "<osm><way changeset='#{open_changeset_id}'>" +
"<nd ref='0'/><tag k='test' v='yes' /></way></osm>"
put :create
# expect failure
- assert_response :forbidden,
+ assert_response :forbidden,
"way upload with invalid node using a private user did not return 'forbidden'"
# create a way with no nodes
"<tag k='test' v='yes' /></way></osm>"
put :create
# expect failure
- assert_response :forbidden,
+ assert_response :forbidden,
"way upload with no node using a private userdid not return 'forbidden'"
# create a way inside a closed changeset
"<nd ref='#{nid1}'/></way></osm>"
put :create
# expect failure
- assert_response :forbidden,
- "way upload to closed changeset with a private user did not return 'forbidden'"
+ assert_response :forbidden,
+ "way upload to closed changeset with a private user did not return 'forbidden'"
+
-
## Now test with a public user
basic_authorization users(:public_user).email, "test"
nid1 = current_nodes(:used_node_1).id
# create a way with non-existing node
- content "<osm><way changeset='#{open_changeset_id}'>" +
+ content "<osm><way changeset='#{open_changeset_id}'>" +
"<nd ref='0'/><tag k='test' v='yes' /></way></osm>"
put :create
# expect failure
- assert_response :precondition_failed,
+ assert_response :precondition_failed,
"way upload with invalid node did not return 'precondition failed'"
assert_equal "Precondition failed: Way requires the nodes with id in (0), which either do not exist, or are not visible.", @response.body
"<tag k='test' v='yes' /></way></osm>"
put :create
# expect failure
- assert_response :precondition_failed,
+ assert_response :precondition_failed,
"way upload with no node did not return 'precondition failed'"
assert_equal "Precondition failed: Cannot create way: data is invalid.", @response.body
"<nd ref='#{nid1}'/></way></osm>"
put :create
# expect failure
- assert_response :conflict,
- "way upload to closed changeset did not return 'conflict'"
+ assert_response :conflict,
+ "way upload to closed changeset did not return 'conflict'"
# create a way with a tag which is too long
content "<osm><way changeset='#{open_changeset_id}'>" +
"</way></osm>"
put :create
# expect failure
- assert_response :bad_request,
+ assert_response :bad_request,
"way upload to with too long tag did not return 'bad_request'"
end
# -------------------------------------
# Test deleting ways.
# -------------------------------------
-
+
def test_delete
# first try to delete way without auth
delete :delete, :id => current_ways(:visible_way).id
assert_response :unauthorized
# now set auth using the private user
- basic_authorization(users(:normal_user).email, "test");
+ basic_authorization(users(:normal_user).email, "test");
# this shouldn't work as with the 0.6 api we need pay load to delete
delete :delete, :id => current_ways(:visible_way).id
assert_response :forbidden
-
+
# Now try without having a changeset
content "<osm><way id='#{current_ways(:visible_way).id}'/></osm>"
delete :delete, :id => current_ways(:visible_way).id
assert_response :forbidden
-
+
# try to delete with an invalid (closed) changeset
content update_changeset(current_ways(:visible_way).to_xml,
changesets(:normal_user_closed_change).id)
# this shouldn't work as the way is used in a relation
content current_ways(:used_way).to_xml
delete :delete, :id => current_ways(:used_way).id
- assert_response :forbidden,
+ assert_response :forbidden,
"shouldn't be able to delete a way used in a relation (#{@response.body}), when done by a private user"
# this won't work since the way never existed
delete :delete, :id => 0
assert_response :forbidden
-
+
### Now check with a public user
# now set auth
- basic_authorization(users(:public_user).email, "test");
+ basic_authorization(users(:public_user).email, "test");
# this shouldn't work as with the 0.6 api we need pay load to delete
delete :delete, :id => current_ways(:visible_way).id
assert_response :bad_request
-
+
# Now try without having a changeset
content "<osm><way id='#{current_ways(:visible_way).id}'/></osm>"
delete :delete, :id => current_ways(:visible_way).id
assert_response :bad_request
-
+
# try to delete with an invalid (closed) changeset
content update_changeset(current_ways(:visible_way).to_xml,
changesets(:public_user_closed_change).id)
# this shouldn't work as the way is used in a relation
content current_ways(:used_way).to_xml
delete :delete, :id => current_ways(:used_way).id
- assert_response :precondition_failed,
+ assert_response :precondition_failed,
"shouldn't be able to delete a way used in a relation (#{@response.body})"
assert_equal "Precondition failed: Way 3 is still used by relations 1.", @response.body
# try and upload it
content way_xml
put :update, :id => current_ways(:visible_way).id
- assert_response :forbidden,
+ assert_response :forbidden,
"adding a duplicate tag to a way for a non-public should fail with 'forbidden'"
## Now try with the public user
# try and upload it
content way_xml
put :update, :id => current_ways(:visible_way).id
- assert_response :bad_request,
+ assert_response :bad_request,
"adding a duplicate tag to a way should fail with 'bad request'"
assert_equal "Element way/#{current_ways(:visible_way).id} has duplicate tags with key #{current_way_tags(:t1).k}", @response.body
end
# try and upload it
content way_xml
put :update, :id => current_ways(:visible_way).id
- assert_response :forbidden,
+ assert_response :forbidden,
"adding new duplicate tags to a way using a non-public user should fail with 'forbidden'"
-
+
## Now test with the public user
# setup auth
basic_authorization(users(:public_user).email, "test")
# try and upload it
content way_xml
put :update, :id => current_ways(:visible_way).id
- assert_response :bad_request,
+ assert_response :bad_request,
"adding new duplicate tags to a way should fail with 'bad request'"
assert_equal "Element way/#{current_ways(:visible_way).id} has duplicate tags with key i_am_a_duplicate", @response.body
-
+
end
##
# try and upload it
content way_str
put :create
- assert_response :forbidden,
+ assert_response :forbidden,
"adding new duplicate tags to a way with a non-public user should fail with 'forbidden'"
-
+
## Now do it with a public user
# setup auth
basic_authorization(users(:public_user).email, "test")
# try and upload it
content way_str
put :create
- assert_response :bad_request,
+ assert_response :bad_request,
"adding new duplicate tags to a way should fail with 'bad request'"
assert_equal "Element way/ has duplicate tags with key addr:housenumber", @response.body
end
# test that a call to ways_for_node returns all ways that contain the node
# and none that don't.
def test_ways_for_node
- # in current fixtures ways 1 and 3 all use node 3. ways 2 and 4
+ # in current fixtures ways 1 and 3 all use node 3. ways 2 and 4
# *used* to use it but doesn't.
get :ways_for_node, :id => current_nodes(:used_node_1).id
assert_response :success
found_way_ids = ways_xml.find("//osm/way").collect { |w| w["id"].to_i }
assert_equal expected_way_ids.sort, found_way_ids.sort,
"expected ways for node #{current_nodes(:used_node_1).id} did not match found"
-
+
# check the full ways to ensure we're not missing anything
expected_way_ids.each do |id|
way_xml = ways_xml.find("//osm/way[@id='#{id}']").first
assert_dom_equal "Test <a href=\"#{link}\" rel=\"nofollow\">#{link}</a> is made into a link", html
html = linkify(text.html_safe)
- assert_equal true, html.html_safe?
+ assert_equal true, html.html_safe?
assert_dom_equal "Test <a href=\"#{link}\" rel=\"nofollow\">#{link}</a> is made into a link", html
end
assert_dom_equal text, html
html = linkify(text.html_safe)
- assert_equal true, html.html_safe?
+ assert_equal true, html.html_safe?
assert_dom_equal text, html
end
end
def test_oauth10_web_app
client = client_applications(:oauth_web_app)
- post_via_redirect "/login",
+ post_via_redirect "/login",
:username => client.user.email, :password => "test"
assert_response :success
assert_nil token.invalidated_at
assert_allowed token, client.permissions
- post "/oauth/authorize",
- :oauth_token => token.token,
+ post "/oauth/authorize",
+ :oauth_token => token.token,
:allow_read_prefs => true, :allow_write_prefs => true
assert_response :redirect
assert_redirected_to "http://some.web.app.org/callback?oauth_token=#{token.token}"
assert_nil token.invalidated_at
assert_allowed token, client.permissions
- post "/oauth/authorize",
- :oauth_token => token.token,
- :oauth_callback => "http://another.web.app.org/callback",
+ post "/oauth/authorize",
+ :oauth_token => token.token,
+ :oauth_callback => "http://another.web.app.org/callback",
:allow_write_api => true, :allow_read_gpx => true
assert_response :redirect
assert_redirected_to "http://another.web.app.org/callback?oauth_token=#{token.token}"
def test_oauth10_desktop_app
client = client_applications(:oauth_desktop_app)
- post_via_redirect "/login",
+ post_via_redirect "/login",
:username => client.user.email, :password => "test"
assert_response :success
assert_nil token.invalidated_at
assert_allowed token, client.permissions
- post "/oauth/authorize",
- :oauth_token => token.token,
+ post "/oauth/authorize",
+ :oauth_token => token.token,
:allow_read_prefs => true, :allow_write_prefs => true
assert_response :success
assert_template "authorize_success"
def test_oauth10a_desktop_app
client = client_applications(:oauth_desktop_app)
- post_via_redirect "/login",
+ post_via_redirect "/login",
:username => client.user.email, :password => "test"
assert_response :success
assert_nil token.invalidated_at
assert_allowed token, client.permissions
- post "/oauth/authorize",
- :oauth_token => token.token,
+ post "/oauth/authorize",
+ :oauth_token => token.token,
:allow_read_prefs => true, :allow_write_prefs => true
assert_response :success
assert_template "authorize_success"
def test_log_in_message
get "/changeset/#{changesets(:normal_user_closed_change).id}"
assert_response :success
-
+
assert_select "div#content" do
assert_select "div#sidebar" do
assert_select "div#sidebar_content" do
assert_response :redirect
get "/changeset/#{changesets(:normal_user_closed_change).id}"
-
+
assert_response :success
assert_template 'browse/changeset'
class UserDiariesTest < ActionDispatch::IntegrationTest
fixtures :users, :diary_entries
- # Test the creation of a diary entry, making sure that you are redirected to
+ # Test the creation of a diary entry, making sure that you are redirected to
# login page when not logged in
def test_showing_create_diary_entry
get_via_redirect '/diary/new'
# http://markmail.org/message/wnslvi5xv5moqg7g
@html_document = nil
follow_redirect!
-
+
assert_response :success
assert_template 'diary_entry/edit'
#print @response.body
#print @html_document.to_yaml
- # We will make sure that the form exists here, full
+ # We will make sure that the form exists here, full
# assert testing of the full form should be done in the
# functional tests rather than this integration test
# There are some things that are specific to the integratio
post "/user/save", {'decline' => 'decline', 'referer' => '/'}
assert_redirected_to "/"
follow_redirect!
-
+
# should be carried through to a normal login with a message
assert_response :success
assert !flash[:notice].nil?
# the acceptable quantisation range.
def test_encode_decode
cases = Array.new
- 1000.times do
+ 1000.times do
cases << [ 180.0 * rand - 90.0, 360.0 * rand - 180.0, (18 * rand).to_i ]
end
lon2, lat2, zoom2 = ShortLink.decode(ShortLink.encode(lon, lat, zoom))
# zooms should be identical
assert_equal zoom, zoom2, "Decoding a encoded short link gives different zoom for (#{lat}, #{lon}, #{zoom})."
- # but the location has a quantisation error introduced at roughly
- # one pixel (i.e: zoom + 8). the sqrt(5) is because each position
- # has an extra bit of accuracy in the lat coordinate, due to the
+ # but the location has a quantisation error introduced at roughly
+ # one pixel (i.e: zoom + 8). the sqrt(5) is because each position
+ # has an extra bit of accuracy in the lat coordinate, due to the
# smaller range.
distance = Math.sqrt((lat - lat2) ** 2 + (lon - lon2) ** 2)
max_distance = 360.0 / (1 << (zoom + 8)) * 0.5 * Math.sqrt(5)
end
##
- # test that links are backwards-compatible, so any old links with
+ # test that links are backwards-compatible, so any old links with
# the deprecated @ characters in them still work properly.
def test_deprecated_at_sign
cases = [["~v2juONc--", "@v2juONc--"],
- ["as3I3GpG~-", "as3I3GpG@-"],
- ["D~hV--", "D@hV--"],
+ ["as3I3GpG~-", "as3I3GpG@-"],
+ ["D~hV--", "D@hV--"],
["CO0O~m8--", "CO0O@m8--"]]
cases.each do |new_code, old_code|
- assert_equal ShortLink.decode(old_code), ShortLink.decode(new_code),
+ assert_equal ShortLink.decode(old_code), ShortLink.decode(new_code),
"old (#{old_code}) and new (#{new_code}) should decode to the same location."
end
end
# validations
def test_does_not_accept_invalid_author
comment = changeset_comments(:normal_comment_1)
-
+
comment.author = nil
assert !comment.valid?
def test_changeset_tag_count
assert_equal 2, ChangesetTag.count
end
-
+
def test_length_key_valid
key = "k"
(0..255).each do |i|
assert tag.valid?
end
end
-
+
def test_length_value_valid
val = "v"
(0..255).each do |i|
assert tag.valid?
end
end
-
+
def test_length_key_invalid
["k"*256].each do |k|
tag = ChangesetTag.new
assert tag.errors[:k].any?
end
end
-
+
def test_length_value_invalid
["v"*256].each do |v|
tag = ChangesetTag.new
assert tag.errors[:v].any?
end
end
-
+
def test_empty_tag_invalid
tag = ChangesetTag.new
assert !tag.valid?, "Empty tag should be invalid"
assert tag.errors[:changeset].any?
end
-
+
def test_uniqueness
tag = ChangesetTag.new
tag.changeset_id = changeset_tags(:changeset_1_tag_1).changeset_id
class DiaryCommentTest < ActiveSupport::TestCase
api_fixtures
fixtures :diary_comments
-
+
def test_diary_comment_count
assert_equal 4, DiaryComment.count
end
class DiaryEntryTest < ActiveSupport::TestCase
api_fixtures
fixtures :diary_entries, :diary_comments, :languages
-
+
def test_diary_entry_count
assert_equal 5, DiaryEntry.count
end
-
+
def test_diary_entry_validations
diary_entry_valid({})
diary_entry_valid({:title => ''}, false)
DiaryEntry.visible.find(diary_entries(:deleted_entry).id)
end
end
-
+
def test_diary_entry_comments
assert_equal 0, diary_entries(:normal_user_entry_1).comments.count
assert_equal 4, diary_entries(:normal_user_geo_entry).comments.count
end
-
+
def test_diary_entry_visible_comments
assert_equal 0, diary_entries(:normal_user_entry_1).visible_comments.count
assert_equal 1, diary_entries(:normal_user_geo_entry).visible_comments.count
entry = DiaryEntry.new(diary_entries(:normal_user_entry_1).attributes)
entry.assign_attributes(attrs)
assert_equal result, entry.valid?, "Expected #{attrs.inspect} to be #{result}"
- end
+ end
end
def test_friend_count
assert_equal 1, Friend.count
end
-
+
end
assert message.errors[:sent_on].any?
assert !message.message_read
end
-
+
def test_validating_msgs
message = messages(:unread_message)
assert message.valid?
massage = messages(:read_message)
assert message.valid?
end
-
+
def test_invalid_send_recipient
message = messages(:unread_message)
message.sender = nil
msg = make_message(char, 1)
# if the save throws, thats fine and the test should pass, as we're
# only testing invalid sequences anyway.
- msg.save!
+ msg.save!
- # get the saved message back and check that it is identical - i.e:
+ # get the saved message back and check that it is identical - i.e:
# its OK to accept invalid UTF-8 as long as we return it unmodified.
db_msg = msg.class.find(msg.id)
assert_equal char, db_msg.title, "Database silently truncated message title"
# because we only test invalid sequences it is OK to barf on them
end
end
- end
+ end
def test_from_mail_plain
mail = Mail.new do
class NodeTagTest < ActiveSupport::TestCase
api_fixtures
-
+
def test_tag_count
assert_equal 12, NodeTag.count
node_tag_count(:visible_node, 1)
node_tag_count(:used_node_2, 1)
node_tag_count(:node_with_versions, 2)
end
-
+
def node_tag_count (node, count)
nod = current_nodes(node)
assert_equal count, nod.node_tags.count
end
-
+
def test_length_key_valid
key = "k"
(0..255).each do |i|
assert tag.valid?
end
end
-
+
def test_length_value_valid
val = "v"
(0..255).each do |i|
assert tag.valid?
end
end
-
+
def test_length_key_invalid
["k"*256].each do |i|
tag = NodeTag.new
assert tag.errors[:k].any?
end
end
-
+
def test_length_value_invalid
["k"*256].each do |i|
tag = NodeTag.new
assert tag.errors[:v].any?
end
end
-
+
def test_empty_node_tag_invalid
tag = NodeTag.new
assert !tag.valid?, "Empty tag should be invalid"
assert tag.errors[:node].any?
end
-
+
def test_uniqueness
tag = NodeTag.new
tag.node_id = current_node_tags(:t1).node_id
class NodeTest < ActiveSupport::TestCase
api_fixtures
-
+
def test_node_count
assert_equal 18, Node.count
end
def test_node_too_far_north
invalid_node_test(:node_too_far_north)
end
-
+
def test_node_north_limit
valid_node_test(:node_north_limit)
end
-
+
def test_node_too_far_south
invalid_node_test(:node_too_far_south)
end
-
+
def test_node_south_limit
valid_node_test(:node_south_limit)
end
-
+
def test_node_too_far_west
invalid_node_test(:node_too_far_west)
end
-
+
def test_node_west_limit
valid_node_test(:node_west_limit)
end
-
+
def test_node_too_far_east
invalid_node_test(:node_too_far_east)
end
-
+
def test_node_east_limit
valid_node_test(:node_east_limit)
end
-
+
def test_totally_wrong
invalid_node_test(:node_totally_wrong)
end
-
+
# This helper method will check to make sure that a node is within the world, and
- # has the the same lat, lon and timestamp than what was put into the db by
+ # has the the same lat, lon and timestamp than what was put into the db by
# the fixture
def valid_node_test(nod)
node = current_nodes(nod)
#assert_equal node.tile, QuadTile.tile_for_point(node.lat, node.lon)
assert node.valid?
end
-
- # This helper method will check to make sure that a node is outwith the world,
+
+ # This helper method will check to make sure that a node is outwith the world,
# and has the same lat, lon and timesamp than what was put into the db by the
# fixture
def invalid_node_test(nod)
#assert_equal node.tile, QuadTile.tile_for_point(node.lat, node.lon)
assert_equal false, dbnode.valid?
end
-
+
# Check that you can create a node and store it
def test_create
node_template = Node.new(
:latitude => 12.3456,
:longitude => 65.4321,
:changeset_id => changesets(:normal_user_first_change).id,
- :visible => 1,
+ :visible => 1,
:version => 1
)
assert node_template.create_with_history(users(:normal_user))
assert_equal false, old_node.visible
#assert_equal node_template.tags, old_node.tags
end
-
+
def test_from_xml_no_id
lat = 56.7
lon = -2.3
}
assert_match /ID is required when updating./, message.message
end
-
+
def test_from_xml_no_lat
nolat = "<osm><node id='1' lon='23.3' changeset='2' version='23' /></osm>"
message_create = assert_raise(OSM::APIBadXMLError) {
}
assert_match /lat missing/, message_update.message
end
-
+
def test_from_xml_no_lon
nolon = "<osm><node id='1' lat='23.1' changeset='2' version='23' /></osm>"
message_create = assert_raise(OSM::APIBadXMLError) {
}
assert_match /Changeset id is missing/, message_update.message
end
-
+
def test_from_xml_no_version
no_version = "<osm><node id='123' lat='23' lon='23' changeset='23' /></osm>"
assert_nothing_raised(OSM::APIBadXMLError) {
}
assert_match /Version is required when updating/, message_update.message
end
-
+
def test_from_xml_double_lat
nocs = "<osm><node id='123' lon='23.23' lat='23.1' lat='12' changeset='23' version='23' /></osm>"
message_create = assert_raise(OSM::APIBadXMLError) {
Node.from_xml(nocs, true)
- }
+ }
assert_match /Fatal error: Attribute lat redefined at/, message_create.message
message_update = assert_raise(OSM::APIBadXMLError) {
Node.from_xml(nocs, false)
}
assert_match /Fatal error: Attribute lat redefined at/, message_update.message
end
-
+
def test_from_xml_id_zero
id_list = ["", "0", "00", "0.0", "a"]
id_list.each do |id|
assert_match /ID of node cannot be zero when updating/, message_update.message
end
end
-
+
def test_from_xml_no_text
no_text = ""
message_create = assert_raise(OSM::APIBadXMLError) {
}
assert_match /Must specify a string with one or more characters/, message_update.message
end
-
+
def test_from_xml_no_node
no_node = "<osm></osm>"
message_create = assert_raise(OSM::APIBadXMLError) {
}
assert_match /XML doesn't contain an osm\/node element/, message_update.message
end
-
+
def test_from_xml_no_k_v
nokv = "<osm><node id='23' lat='12.3' lon='23.4' changeset='12' version='23'><tag /></node></osm>"
message_create = assert_raise(OSM::APIBadXMLError) {
}
assert_match /tag is missing key/, message_update.message
end
-
+
def test_from_xml_no_v
no_v = "<osm><node id='23' lat='23.43' lon='23.32' changeset='23' version='32'><tag k='key' /></node></osm>"
message_create = assert_raise(OSM::APIBadXMLError) {
}
assert_match /tag is missing value/, message_update.message
end
-
+
def test_from_xml_duplicate_k
dupk = "<osm><node id='23' lat='23.2' lon='23' changeset='34' version='23'><tag k='dup' v='test' /><tag k='dup' v='tester' /></node></osm>"
message_create = assert_raise(OSM::APIDuplicateTagsError) {
node = current_nodes(:node_with_versions)
tags = Node.find(node.id).node_tags.order(:k)
assert_equal 2, tags.count
- assert_equal "testing", tags[0].k
+ assert_equal "testing", tags[0].k
assert_equal "added in node version 3", tags[0].v
assert_equal "testing two", tags[1].k
assert_equal "modified in node version 4", tags[1].v
def test_nonce_uniqueness
string = "0123456789ABCDEF"
timestamp = Time.now
-
+
nonce1 = OauthNonce.remember(string, timestamp)
assert_not_equal false, nonce1, "First nonce should be unique. Check your test database is empty."
def test_old_node_tag_count
assert_equal 19, OldNodeTag.count, "Unexpected number of fixtures loaded."
end
-
+
def test_length_key_valid
key = "k"
(0..255).each do |i|
assert tag.valid?
end
end
-
+
def test_length_value_valid
val = "v"
(0..255).each do |i|
assert tag.valid?
end
end
-
+
def test_length_key_invalid
["k"*256].each do |i|
tag = OldNodeTag.new
assert tag.errors[:k].any?
end
end
-
+
def test_length_value_invalid
["k"*256].each do |i|
tag = OldNodeTag.new
assert tag.errors[:v].any?
end
end
-
+
def test_empty_tag_invalid
tag = OldNodeTag.new
assert !tag.valid?, "Empty tag should be invalid"
assert tag.errors[:old_node].any?
end
-
+
def test_uniqueness
tag = OldNodeTag.new
tag.node_id = node_tags(:t1).node_id
class OldNodeTest < ActiveSupport::TestCase
api_fixtures
-
+
def test_node_count
assert_equal 23, OldNode.count
end
def test_node_too_far_north
invalid_node_test(:node_too_far_north)
end
-
+
def test_node_north_limit
valid_node_test(:node_north_limit)
end
-
+
def test_node_too_far_south
invalid_node_test(:node_too_far_south)
end
-
+
def test_node_south_limit
valid_node_test(:node_south_limit)
end
-
+
def test_node_too_far_west
invalid_node_test(:node_too_far_west)
end
-
+
def test_node_west_limit
valid_node_test(:node_west_limit)
end
-
+
def test_node_too_far_east
invalid_node_test(:node_too_far_east)
end
-
+
def test_node_east_limit
valid_node_test(:node_east_limit)
end
-
+
def test_totally_wrong
invalid_node_test(:node_totally_wrong)
end
-
+
# This helper method will check to make sure that a node is within the world, and
- # has the the same lat, lon and timestamp than what was put into the db by
+ # has the the same lat, lon and timestamp than what was put into the db by
# the fixture
def valid_node_test(nod)
node = nodes(nod)
#assert_equal node.tile, QuadTile.tile_for_point(nodes(nod).lat, nodes(nod).lon)
assert node.valid?
end
-
- # This helpermethod will check to make sure that a node is outwith the world,
+
+ # This helpermethod will check to make sure that a node is outwith the world,
# and has the same lat, lon and timesamp than what was put into the db by the
# fixture
def invalid_node_test(nod)
node = nodes(:node_with_versions_v3)
tags = OldNode.find(node.id).old_tags.order(:k)
assert_equal 3, tags.count
- assert_equal "testing", tags[0].k
+ assert_equal "testing", tags[0].k
assert_equal "added in node version 3", tags[0].v
assert_equal "testing three", tags[1].k
assert_equal "added in node version 3", tags[1].v
node = nodes(:node_with_versions_v4)
tags = OldNode.find(node.id).old_tags.order(:k)
assert_equal 2, tags.count
- assert_equal "testing", tags[0].k
+ assert_equal "testing", tags[0].k
assert_equal "added in node version 3", tags[0].v
assert_equal "testing two", tags[1].k
assert_equal "modified in node version 4", tags[1].v
class OldRelationTagTest < ActiveSupport::TestCase
api_fixtures
-
+
def test_tag_count
assert_equal 12, OldRelationTag.count
end
-
+
def test_length_key_valid
key = "k"
(0..255).each do |i|
assert tag.valid?
end
end
-
+
def test_length_value_valid
val = "v"
(0..255).each do |i|
assert tag.valid?
end
end
-
+
def test_length_key_invalid
["k"*256].each do |i|
tag = OldRelationTag.new
assert tag.errors[:k].any?
end
end
-
+
def test_length_value_invalid
["k"*256].each do |i|
tag = OldRelationTag.new
assert tag.errors[:v].any?
end
end
-
+
def test_empty_tag_invalid
tag = OldRelationTag.new
assert !tag.valid?, "Empty tag should be invalid"
assert tag.errors[:old_relation].any?
end
-
+
def test_uniqueness
tag = OldRelationTag.new
tag.relation_id = relation_tags(:t1).relation_id
relation = relations(:relation_with_versions_v3)
tags = OldRelation.find(relation.id).old_tags.order(:k)
assert_equal 3, tags.count
- assert_equal "testing", tags[0].k
+ assert_equal "testing", tags[0].k
assert_equal "added in relation version 3", tags[0].v
assert_equal "testing three", tags[1].k
assert_equal "added in relation version 3", tags[1].v
relation = relations(:relation_with_versions_v4)
tags = OldRelation.find(relation.id).old_tags.order(:k)
assert_equal 2, tags.count
- assert_equal "testing", tags[0].k
+ assert_equal "testing", tags[0].k
assert_equal "added in relation version 3", tags[0].v
assert_equal "testing two", tags[1].k
assert_equal "modified in relation version 4", tags[1].v
class OldWayTagTest < ActiveSupport::TestCase
api_fixtures
-
+
def test_tag_count
assert_equal 12, OldWayTag.count
end
-
+
def test_length_key_valid
key = "k"
(0..255).each do |i|
assert tag.valid?
end
end
-
+
def test_length_value_valid
val = "v"
(0..255).each do |i|
assert tag.valid?
end
end
-
+
def test_length_key_invalid
["k"*256].each do |i|
tag = OldWayTag.new
assert tag.errors[:k].any?
end
end
-
+
def test_length_value_invalid
["k"*256].each do |i|
tag = OldWayTag.new
assert tag.errors[:v].any?
end
end
-
+
def test_empty_tag_invalid
tag = OldWayTag.new
assert !tag.valid?, "Empty tag should be invalid"
assert tag.errors[:old_way].any?
end
-
+
def test_uniqueness
tag = OldWayTag.new
tag.way_id = way_tags(:t1).way_id
way = ways(:way_with_versions_v3)
tags = OldWay.find(way.id).old_tags.order(:k)
assert_equal 3, tags.count
- assert_equal "testing", tags[0].k
+ assert_equal "testing", tags[0].k
assert_equal "added in way version 3", tags[0].v
assert_equal "testing three", tags[1].k
assert_equal "added in way version 3", tags[1].v
way = ways(:way_with_versions_v4)
tags = OldWay.find(way.id).old_tags.order(:k)
assert_equal 2, tags.count
- assert_equal "testing", tags[0].k
+ assert_equal "testing", tags[0].k
assert_equal "added in way version 3", tags[0].v
assert_equal "testing two", tags[1].k
assert_equal "modified in way version 4", tags[1].v
class RelationMemberTest < ActiveSupport::TestCase
api_fixtures
-
+
def test_relation_member_count
assert_equal 9, RelationMember.count
end
class RelationTagTest < ActiveSupport::TestCase
api_fixtures
-
+
def test_relation_tag_count
assert_equal 9, RelationTag.count
end
-
+
def test_length_key_valid
key = "k"
(0..255).each do |i|
assert tag.valid?
end
end
-
+
def test_length_value_valid
val = "v"
(0..255).each do |i|
assert tag.valid?
end
end
-
+
def test_length_key_invalid
["k"*256].each do |i|
tag = RelationTag.new
assert tag.errors[:k].any?
end
end
-
+
def test_length_value_invalid
["v"*256].each do |i|
tag = RelationTag.new
assert tag.errors[:v].any?
end
end
-
+
def test_empty_tag_invalid
tag = RelationTag.new
assert !tag.valid?, "Empty relation tag should be invalid"
assert tag.errors[:relation].any?
end
-
+
def test_uniquness
tag = RelationTag.new
tag.relation_id = current_relation_tags(:t1).relation_id
##
# test that tags can be updated and saved uniquely, i.e: tag.save!
- # only affects the single tag that the activerecord object
+ # only affects the single tag that the activerecord object
# represents. this amounts to testing that the primary key is
# unique.
#
# Commenting this out - I attempted to fix it, but composite primary keys
- # wasn't playing nice with the column already called :id. Seemed to be
+ # wasn't playing nice with the column already called :id. Seemed to be
# impossible to have validations on the :id column. If someone knows better
# please fix, otherwise this test is shelved.
#
class RelationTest < ActiveSupport::TestCase
api_fixtures
-
+
def test_relation_count
assert_equal 8, Relation.count
end
-
+
def test_from_xml_no_id
noid = "<osm><relation version='12' changeset='23' /></osm>"
assert_nothing_raised(OSM::APIBadXMLError) {
}
assert_match /ID is required when updating/, message.message
end
-
+
def test_from_xml_no_changeset_id
nocs = "<osm><relation id='123' version='12' /></osm>"
message_create = assert_raise(OSM::APIBadXMLError) {
}
assert_match /Changeset id is missing/, message_update.message
end
-
+
def test_from_xml_no_version
no_version = "<osm><relation id='123' changeset='23' /></osm>"
assert_nothing_raised(OSM::APIBadXMLError) {
}
assert_match /Version is required when updating/, message_update.message
end
-
+
def test_from_xml_id_zero
id_list = ["", "0", "00", "0.0", "a"]
id_list.each do |id|
assert_match /ID of relation cannot be zero when updating/, message_update.message
end
end
-
+
def test_from_xml_no_text
no_text = ""
message_create = assert_raise(OSM::APIBadXMLError) {
}
assert_match /Must specify a string with one or more characters/, message_update.message
end
-
+
def test_from_xml_no_k_v
nokv = "<osm><relation id='23' changeset='23' version='23'><tag /></relation></osm>"
message_create = assert_raise(OSM::APIBadXMLError) {
}
assert_match /tag is missing key/, message_update.message
end
-
+
def test_from_xml_no_v
no_v = "<osm><relation id='23' changeset='23' version='23'><tag k='key' /></relation></osm>"
message_create = assert_raise(OSM::APIBadXMLError) {
}
assert_match /tag is missing value/, message_update.message
end
-
+
def test_from_xml_duplicate_k
dupk = "<osm><relation id='23' changeset='23' version='23'><tag k='dup' v='test'/><tag k='dup' v='tester'/></relation></osm>"
message_create = assert_raise(OSM::APIDuplicateTagsError) {
relation = current_relations(:relation_with_versions)
tags = Relation.find(relation.id).relation_tags.order(:k)
assert_equal 2, tags.count
- assert_equal "testing", tags[0].k
+ assert_equal "testing", tags[0].k
assert_equal "added in relation version 3", tags[0].v
assert_equal "testing two", tags[1].k
assert_equal "modified in relation version 4", tags[1].v
class TraceTest < ActiveSupport::TestCase
api_fixtures
-
+
def setup
@gpx_trace_dir = Object.send("remove_const", "GPX_TRACE_DIR")
Object.const_set("GPX_TRACE_DIR", File.dirname(__FILE__) + "/../traces")
class TracepointTest < ActiveSupport::TestCase
api_fixtures
-
+
def test_tracepoint_count
assert_equal 4, Tracepoint.count
end
-
+
end
class TracetagTest < ActiveSupport::TestCase
api_fixtures
-
+
def test_tracetag_count
assert_equal 4, Tracetag.count
end
assert_not_equal newUP.v, up.v
assert_raise (ActiveRecord::RecordNotUnique) {newUP.save}
end
-
+
def test_check_valid_length
key = "k"
val = "v"
assert_equal val*i, resp.v, "User preference with #{i} #{val} chars (i.e. #{val.length*i} bytes) fails"
end
end
-
+
def test_check_invalid_length
key = "k"
val = "v"
assert !user.errors[:home_lon].any?
assert !user.errors[:home_zoom].any?
end
-
+
def test_unique_email
new_user = User.new(
:email => users(:normal_user).email,
- :status => "active",
+ :status => "active",
:pass_crypt => Digest::MD5.hexdigest('test'),
:display_name => "new user",
:data_public => 1,
assert !new_user.save
assert new_user.errors[:email].include?("has already been taken")
end
-
+
def test_unique_display_name
new_user = User.new(
:email => "tester@openstreetmap.org",
:status => "pending",
:pass_crypt => Digest::MD5.hexdigest('test'),
- :display_name => users(:normal_user).display_name,
+ :display_name => users(:normal_user).display_name,
:data_public => 1,
:description => "desc"
)
assert !new_user.save
assert new_user.errors[:display_name].include?("has already been taken")
end
-
+
def test_email_valid
- ok = %w{ a@s.com test@shaunmcdonald.me.uk hello_local@ping-d.ng
+ ok = %w{ a@s.com test@shaunmcdonald.me.uk hello_local@ping-d.ng
test_local@openstreetmap.org test-local@example.com }
bad = %w{ hi ht@ n@ @.com help@.me.uk help"hi.me.uk も対@応します
輕觸搖晃的遊戲@ah.com も対応します@s.name }
-
+
ok.each do |name|
user = users(:normal_user)
user.email = name
assert user.valid?(:save), user.errors.full_messages.join(",")
end
-
+
bad.each do |name|
user = users(:normal_user)
user.email = name
- assert user.invalid?(:save), "#{name} is valid when it shouldn't be"
+ assert user.invalid?(:save), "#{name} is valid when it shouldn't be"
end
end
-
+
def test_display_name_length
user = users(:normal_user)
user.display_name = "123"
user.display_name = ""
assert !user.valid?
user.display_name = nil
- # Don't understand why it isn't allowing a nil value,
+ # Don't understand why it isn't allowing a nil value,
# when the validates statements specifically allow it
# It appears the database does not allow null values
assert !user.valid?
end
-
+
def test_display_name_valid
- # Due to sanitisation in the view some of these that you might not
+ # Due to sanitisation in the view some of these that you might not
# expact are allowed
# However, would they affect the xml planet dumps?
- ok = [ "Name", "'me", "he\"", "<hr>", "*ho", "\"help\"@",
+ ok = [ "Name", "'me", "he\"", "<hr>", "*ho", "\"help\"@",
"vergrößern", "ルシステムにも対応します", "輕觸搖晃的遊戲" ]
# These need to be 3 chars in length, otherwise the length test above
# should be used.
user.display_name = display_name
assert user.valid?, "#{display_name} is invalid, when it should be"
end
-
+
bad.each do |display_name|
user = users(:normal_user)
user.display_name = display_name
assert !user.valid?, "#{display_name} is valid when it shouldn't be"
end
end
-
+
def test_friend_with
assert users(:normal_user).is_friends_with?(users(:public_user))
assert !users(:normal_user).is_friends_with?(users(:inactive_user))
def test_user_token_count
assert_equal 0, UserToken.count
end
-
+
end
class WayTagTest < ActiveSupport::TestCase
api_fixtures
-
+
def test_way_tag_count
assert_equal 5, WayTag.count
end
-
+
def test_length_key_valid
key = "k"
(0..255).each do |i|
assert tag.valid?
end
end
-
+
def test_length_value_valid
val = "v"
(0..255).each do |i|
assert tag.valid?
end
end
-
+
def test_length_key_invalid
["k"*256].each do |i|
tag = WayTag.new
assert tag.errors[:k].any?
end
end
-
+
def test_length_value_invalid
["v"*256].each do |i|
tag = WayTag.new
assert tag.errors[:v].any?
end
end
-
+
def test_empty_tag_invalid
tag = WayTag.new
assert !tag.valid?, "Empty way tag should be invalid"
assert tag.errors[:way].any?
end
-
+
def test_uniqueness
tag = WayTag.new
tag.way_id = current_way_tags(:t1).way_id
def test_db_count
assert_equal 7, Way.count
end
-
+
def test_bbox
node = current_nodes(:used_node_1)
[ :visible_way,
assert_equal node.bbox.max_lat, way.bbox.max_lat, 'max_lat'
end
end
-
- # Check that the preconditions fail when you are over the defined limit of
+
+ # Check that the preconditions fail when you are over the defined limit of
# the maximum number of nodes in each way.
def test_max_nodes_per_way_limit
# Take one of the current ways and add nodes to it until we are near the limit
way.add_nd_num(current_nodes(:visible_node).id)
assert way.valid?
end
-
+
def test_from_xml_no_id
noid = "<osm><way version='12' changeset='23' /></osm>"
assert_nothing_raised(OSM::APIBadXMLError) {
}
assert_match /ID is required when updating/, message.message
end
-
+
def test_from_xml_no_changeset_id
nocs = "<osm><way id='123' version='23' /></osm>"
message_create = assert_raise(OSM::APIBadXMLError) {
}
assert_match /Changeset id is missing/, message_update.message
end
-
+
def test_from_xml_no_version
no_version = "<osm><way id='123' changeset='23' /></osm>"
assert_nothing_raised(OSM::APIBadXMLError) {
assert_match /ID of way cannot be zero when updating/, message_update.message
end
end
-
+
def test_from_xml_no_text
no_text = ""
message_create = assert_raise(OSM::APIBadXMLError) {
}
assert_match /Must specify a string with one or more characters/, message_update.message
end
-
+
def test_from_xml_no_k_v
nokv = "<osm><way id='23' changeset='23' version='23'><tag /></way></osm>"
message_create = assert_raise(OSM::APIBadXMLError) {
}
assert_match /tag is missing key/, message_update.message
end
-
+
def test_from_xml_no_v
no_v = "<osm><way id='23' changeset='23' version='23'><tag k='key' /></way></osm>"
message_create = assert_raise(OSM::APIBadXMLError) {
}
assert_match /tag is missing value/, message_update.message
end
-
+
def test_from_xml_duplicate_k
dupk = "<osm><way id='23' changeset='23' version='23'><tag k='dup' v='test' /><tag k='dup' v='tester' /></way></osm>"
message_create = assert_raise(OSM::APIDuplicateTagsError) {
way = current_ways(:way_with_versions)
tags = Way.find(way.id).way_tags.order(:k)
assert_equal 2, tags.count
- assert_equal "testing", tags[0].k
+ assert_equal "testing", tags[0].k
assert_equal "added in way version 3", tags[0].v
assert_equal "testing two", tags[1].k
assert_equal "modified in way version 4", tags[1].v
fixtures :relation_members, :relation_tags
set_fixture_class :relation_members => OldRelationMember
set_fixture_class :relation_tags => OldRelationTag
-
+
fixtures :gpx_files, :gps_points, :gpx_file_tags
set_fixture_class :gpx_files => Trace
set_fixture_class :gps_points => Tracepoint
set_fixture_class :gpx_file_tags => Tracetag
fixtures :client_applications
-
+
fixtures :redactions
fixtures :notes, :note_comments
end
##
- # takes a block which is executed in the context of a different
+ # takes a block which is executed in the context of a different
# ActionController instance. this is used so that code can call methods
# on the node controller whilst testing the old_node controller.
def with_controller(new_controller)
end
##
- # for some reason a==b is false, but there doesn't seem to be any
- # difference between the nodes, so i'm checking all the attributes
+ # for some reason a==b is false, but there doesn't seem to be any
+ # difference between the nodes, so i'm checking all the attributes
# manually and blaming it on ActiveRecord
def assert_nodes_are_equal(a, b)
assert_equal a.id, b.id, "node IDs"
def content(c)
@request.env["RAW_POST_DATA"] = c.to_s
end
-
+
# Used to check that the error header and the forbidden responses are given
# when the owner of the changset has their data not marked as public
def assert_require_public_data(msg = "Shouldn't be able to use API when the user's data is not public")
assert_response :forbidden, msg
assert_equal @response.headers['Error'], "You must make your edits public to upload new data", "Wrong error message"
end
-
+
# Not sure this is the best response we could give
def assert_inactive_user(msg = "an inactive user shouldn't be able to access the API")
assert_response :unauthorized, msg
#assert_equal @response.headers['Error'], ""
end
-
+
def assert_no_missing_translations(msg="")
assert_select "span[class=translation_missing]", false, "Missing translation #{msg}"
end
return openid_response_qs
end
-
+
# Add more helper methods to be used by all tests here...
end