From: Anton Melnichuk Date: Thu, 27 Feb 2020 08:15:37 +0000 (+0200) Subject: Merge branch 'master' of github.com:openstreetmap/openstreetmap-website into mobile... X-Git-Tag: live~2820^2~1 X-Git-Url: https://git.openstreetmap.org./rails.git/commitdiff_plain/009a4dbb673507ce06d8933cd836a1284e360330?hp=248ad3ae0584e0a158b7de2c3b5d8bee114509b0 Merge branch 'master' of github.com:openstreetmap/openstreetmap-website into mobile-layout --- diff --git a/.rubocop.yml b/.rubocop.yml index 1ae01086a..77f26d863 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -29,6 +29,9 @@ Metrics/ClassLength: Exclude: - 'test/**/*' +Metrics/ModuleLength: + Max: 150 + Naming/FileName: Exclude: - 'script/deliver-message' diff --git a/app/controllers/api/map_controller.rb b/app/controllers/api/map_controller.rb index b0998f7eb..113554c72 100644 --- a/app/controllers/api/map_controller.rb +++ b/app/controllers/api/map_controller.rb @@ -5,6 +5,8 @@ module Api before_action :check_api_readable around_action :api_call_handle_error, :api_call_timeout + before_action :set_default_request_format + # 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 @@ -90,7 +92,10 @@ module Api response.headers["Content-Disposition"] = "attachment; filename=\"map.osm\"" # Render the result - render :formats => [:xml] + respond_to do |format| + format.xml + format.json + end end end end diff --git a/app/controllers/api/nodes_controller.rb b/app/controllers/api/nodes_controller.rb index 2962ce070..336aebc91 100644 --- a/app/controllers/api/nodes_controller.rb +++ b/app/controllers/api/nodes_controller.rb @@ -13,6 +13,8 @@ module Api before_action :check_api_readable, :except => [:create, :update, :delete] around_action :api_call_handle_error, :api_call_timeout + before_action :set_default_request_format, :except => [:create, :update, :delete] + # Create a node from XML. def create assert_method :put @@ -32,7 +34,10 @@ module Api if @node.visible # Render the result - render :formats => [:xml] + respond_to do |format| + format.xml + format.json + end else head :gone end @@ -73,7 +78,10 @@ module Api @nodes = Node.find(ids) # Render the result - render :formats => [:xml] + respond_to do |format| + format.xml + format.json + end end end end diff --git a/app/controllers/api/old_controller.rb b/app/controllers/api/old_controller.rb index 862d14716..f672e7c49 100644 --- a/app/controllers/api/old_controller.rb +++ b/app/controllers/api/old_controller.rb @@ -16,6 +16,8 @@ module Api before_action :lookup_old_element, :except => [:history] before_action :lookup_old_element_versions, :only => [:history] + before_action :set_default_request_format, :except => [:redact] + 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 @@ -30,7 +32,10 @@ module Api end # Render the result - render :formats => [:xml] + respond_to do |format| + format.xml + format.json + end end def version @@ -41,7 +46,10 @@ module Api response.last_modified = @old_element.timestamp # Render the result - render :formats => [:xml] + respond_to do |format| + format.xml + format.json + end end end diff --git a/app/controllers/api/relations_controller.rb b/app/controllers/api/relations_controller.rb index ba0dd0c6b..329c5e29c 100644 --- a/app/controllers/api/relations_controller.rb +++ b/app/controllers/api/relations_controller.rb @@ -11,6 +11,8 @@ module Api before_action :check_api_readable, :except => [:create, :update, :delete] around_action :api_call_handle_error, :api_call_timeout + before_action :set_default_request_format, :except => [:create, :update, :delete] + def create assert_method :put @@ -26,7 +28,10 @@ module Api response.last_modified = @relation.timestamp if @relation.visible # Render the result - render :formats => [:xml] + respond_to do |format| + format.xml + format.json + end else head :gone end @@ -117,7 +122,10 @@ module Api @relations << relation # Render the result - render :formats => [:xml] + respond_to do |format| + format.xml + format.json + end else head :gone end @@ -133,7 +141,10 @@ module Api @relations = Relation.find(ids) # Render the result - render :formats => [:xml] + respond_to do |format| + format.xml + format.json + end end def relations_for_way @@ -160,7 +171,10 @@ module Api end # Render the result - render :formats => [:xml] + respond_to do |format| + format.xml + format.json + end end end end diff --git a/app/controllers/api/ways_controller.rb b/app/controllers/api/ways_controller.rb index 9af087d83..a7c876710 100644 --- a/app/controllers/api/ways_controller.rb +++ b/app/controllers/api/ways_controller.rb @@ -11,6 +11,8 @@ module Api before_action :check_api_readable, :except => [:create, :update, :delete] around_action :api_call_handle_error, :api_call_timeout + before_action :set_default_request_format, :except => [:create, :update, :delete] + def create assert_method :put @@ -28,7 +30,10 @@ module Api if @way.visible # Render the result - render :formats => [:xml] + respond_to do |format| + format.xml + format.json + end else head :gone end @@ -75,7 +80,10 @@ module Api end # Render the result - render :formats => [:xml] + respond_to do |format| + format.xml + format.json + end else head :gone end @@ -93,7 +101,10 @@ module Api @ways = Way.find(ids) # Render the result - render :formats => [:xml] + respond_to do |format| + format.xml + format.json + end end ## @@ -106,7 +117,10 @@ module Api @ways = Way.where(:id => wayids, :visible => true) # Render the result - render :formats => [:xml] + respond_to do |format| + format.xml + format.json + end end end end diff --git a/app/controllers/api_controller.rb b/app/controllers/api_controller.rb index 44efdc071..64514a432 100644 --- a/app/controllers/api_controller.rb +++ b/app/controllers/api_controller.rb @@ -3,6 +3,56 @@ class ApiController < ApplicationController private + ## + # Set default request format to xml unless a client requests a specific format, + # which can be done via (a) URL suffix and/or (b) HTTP Accept header, where + # the URL suffix always takes precedence over the Accept header. + def set_default_request_format + unless params[:format] + accept_header = request.headers["HTTP_ACCEPT"] + if accept_header.nil? + # e.g. unit tests don't set an Accept: header by default, force XML in this case + request.format = "xml" + return + end + + req_mimetypes = [] + + # Some clients (JOSM) send Accept headers which cannot be parsed by Rails, example: *; q=.2 + # To be fair, JOSM's Accept header doesn't adhere to RFC 7231, section 5.3.1, et al. either + # As a workaround for backwards compatibility, we're assuming XML format + begin + req_mimetypes = Mime::Type.parse(accept_header) + rescue Mime::Type::InvalidMimeType + request.format = "xml" + return + end + + # req_mimetypes contains all Accept header MIME types with descending priority + req_mimetypes.each do |mime| + if mime.symbol == :xml + request.format = "xml" + break + end + + if mime.symbol == :json + request.format = "json" + break + end + + # Any format, not explicitly requesting XML or JSON -> assume XML as default + if mime == "*/*" + request.format = "xml" + break + end + + # In case the client requests some other format besides XML, JSON and */*, + # we deliberately don't set request.format. The framework will return an + # ActionController::UnknownFormat error to the client later on in this case. + end + end + end + def authorize(realm = "Web Password", errormessage = "Couldn't authenticate you") # make the current_user object from any auth sources we have setup_user_auth diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index bee5e8169..f419460ee 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -185,6 +185,8 @@ class ApplicationController < ActionController::Base def api_call_handle_error yield + rescue ActionController::UnknownFormat + head :not_acceptable rescue ActiveRecord::RecordNotFound => e head :not_found rescue LibXML::XML::Error, ArgumentError => e diff --git a/app/helpers/browse_tags_helper.rb b/app/helpers/browse_tags_helper.rb index bbf6f3cf7..4f73eb9d7 100644 --- a/app/helpers/browse_tags_helper.rb +++ b/app/helpers/browse_tags_helper.rb @@ -21,6 +21,8 @@ module BrowseTagsHelper link_to h(wmc[:title]), wmc[:url], :title => t("browse.tag_details.wikimedia_commons_link", :page => wmc[:title]) elsif url = wiki_link("tag", "#{key}=#{value}") link_to h(value), url, :title => t("browse.tag_details.wiki_link.tag", :key => key, :value => value) + elsif email = email_link(key, value) + link_to(h(email[:email]), email[:url], :title => t("browse.tag_details.email_link", :email => email[:email])) elsif phones = telephone_links(key, value) # similarly, telephone_links() returns an array of phone numbers phones = phones.map do |p| @@ -123,6 +125,25 @@ module BrowseTagsHelper nil end + def email_link(_key, value) + # Does the value look like an email? eg "someone@domain.tld" + + # Uses Ruby built-in regexp to validate email. + # This will not catch certain valid emails containing comments, whitespace characters, + # and quoted strings. + # (see: https://github.com/ruby/ruby/blob/master/lib/uri/mailto.rb) + + # remove any leading and trailing whitespace + email = value.strip + + if email.match?(URI::MailTo::EMAIL_REGEXP) + # add 'mailto:'' prefix + return { :email => email, :url => "mailto:#{email}" } + end + + nil + end + def telephone_links(_key, value) # Does it look like a global phone number? eg "+1 (234) 567-8901 " # or a list of alternate numbers separated by ; diff --git a/app/models/concerns/geo_record.rb b/app/models/concerns/geo_record.rb index 91533ece4..447ee19df 100644 --- a/app/models/concerns/geo_record.rb +++ b/app/models/concerns/geo_record.rb @@ -12,6 +12,10 @@ module GeoRecord def to_s format("%.7f", self) end + + def as_json(_) + format("%.7f", self).to_f + end end # This scaling factor is used to convert between the float lat/lon that is diff --git a/app/views/api/_root_attributes.json.jbuilder b/app/views/api/_root_attributes.json.jbuilder new file mode 100644 index 000000000..d8fbef9fd --- /dev/null +++ b/app/views/api/_root_attributes.json.jbuilder @@ -0,0 +1,5 @@ +json.version Settings.api_version +json.generator Settings.generator +json.copyright Settings.copyright_owner +json.attribution Settings.attribution_url +json.license Settings.license_url diff --git a/app/views/api/map/_bounds.json.jbuilder b/app/views/api/map/_bounds.json.jbuilder new file mode 100644 index 000000000..16fdbeb0f --- /dev/null +++ b/app/views/api/map/_bounds.json.jbuilder @@ -0,0 +1,6 @@ +json.bounds do + json.minlat GeoRecord::Coord.new(@bounds.min_lat) + json.minlon GeoRecord::Coord.new(@bounds.min_lon) + json.maxlat GeoRecord::Coord.new(@bounds.max_lat) + json.maxlon GeoRecord::Coord.new(@bounds.max_lon) +end diff --git a/app/views/api/map/index.json.jbuilder b/app/views/api/map/index.json.jbuilder new file mode 100644 index 000000000..7cc983aef --- /dev/null +++ b/app/views/api/map/index.json.jbuilder @@ -0,0 +1,9 @@ +json.partial! "root_attributes" + +json.partial! "bounds" + +all = @nodes + @ways + @relations + +json.elements(all) do |obj| + json.partial! obj +end diff --git a/app/views/api/nodes/_node.json.jbuilder b/app/views/api/nodes/_node.json.jbuilder new file mode 100644 index 000000000..e48d5f17c --- /dev/null +++ b/app/views/api/nodes/_node.json.jbuilder @@ -0,0 +1,15 @@ +json.type "node" +json.id node.id +if node.visible + json.lat GeoRecord::Coord.new(node.lat) + json.lon GeoRecord::Coord.new(node.lon) +end +json.timestamp node.timestamp.xmlschema +json.version node.version +json.changeset node.changeset_id +json.user node.changeset.user.display_name +json.uid node.changeset.user_id + +json.visible node.visible unless node.visible + +json.tags node.tags unless node.tags.empty? diff --git a/app/views/api/nodes/index.json.jbuilder b/app/views/api/nodes/index.json.jbuilder new file mode 100644 index 000000000..3e3ceb4cc --- /dev/null +++ b/app/views/api/nodes/index.json.jbuilder @@ -0,0 +1,5 @@ +json.partial! "api/root_attributes" + +json.elements(@nodes) do |node| + json.partial! node +end diff --git a/app/views/api/nodes/show.json.jbuilder b/app/views/api/nodes/show.json.jbuilder new file mode 100644 index 000000000..9974da82f --- /dev/null +++ b/app/views/api/nodes/show.json.jbuilder @@ -0,0 +1,5 @@ +json.partial! "api/root_attributes" + +json.elements([@node]) do |node| + json.partial! node +end diff --git a/app/views/api/old_nodes/_old_node.json.jbuilder b/app/views/api/old_nodes/_old_node.json.jbuilder new file mode 100644 index 000000000..211d50332 --- /dev/null +++ b/app/views/api/old_nodes/_old_node.json.jbuilder @@ -0,0 +1,15 @@ +json.type "node" +json.id old_node.node_id +if old_node.visible + json.lat GeoRecord::Coord.new(old_node.lat) + json.lon GeoRecord::Coord.new(old_node.lon) +end +json.timestamp old_node.timestamp.xmlschema +json.version old_node.version +json.changeset old_node.changeset_id +json.user old_node.changeset.user.display_name +json.uid old_node.changeset.user_id + +json.visible old_node.visible unless old_node.visible + +json.tags old_node.tags unless old_node.tags.empty? diff --git a/app/views/api/old_nodes/history.json.jbuilder b/app/views/api/old_nodes/history.json.jbuilder new file mode 100644 index 000000000..96e8cca2d --- /dev/null +++ b/app/views/api/old_nodes/history.json.jbuilder @@ -0,0 +1,5 @@ +json.partial! "api/root_attributes" + +json.elements(@elems) do |old_node| + json.partial! old_node +end diff --git a/app/views/api/old_nodes/version.json.jbuilder b/app/views/api/old_nodes/version.json.jbuilder new file mode 100644 index 000000000..f63e07d43 --- /dev/null +++ b/app/views/api/old_nodes/version.json.jbuilder @@ -0,0 +1,5 @@ +json.partial! "api/root_attributes" + +json.elements([@old_element]) do |old_node| + json.partial! old_node +end diff --git a/app/views/api/old_relations/_old_relation.json.jbuilder b/app/views/api/old_relations/_old_relation.json.jbuilder new file mode 100644 index 000000000..c52ca20de --- /dev/null +++ b/app/views/api/old_relations/_old_relation.json.jbuilder @@ -0,0 +1,19 @@ +json.type "relation" +json.id old_relation.relation_id +json.timestamp old_relation.timestamp.xmlschema +json.version old_relation.version +json.changeset old_relation.changeset_id +json.user old_relation.changeset.user.display_name +json.uid old_relation.changeset.user_id + +json.visible old_relation.visible unless old_relation.visible + +unless old_relation.relation_members.empty? + json.members(old_relation.relation_members) do |m| + json.type m.member_type.downcase + json.ref m.member_id + json.role m.member_role + end +end + +json.tags old_relation.tags unless old_relation.tags.empty? diff --git a/app/views/api/old_relations/history.json.jbuilder b/app/views/api/old_relations/history.json.jbuilder new file mode 100644 index 000000000..311a80a86 --- /dev/null +++ b/app/views/api/old_relations/history.json.jbuilder @@ -0,0 +1,5 @@ +json.partial! "api/root_attributes" + +json.elements(@elems) do |old_relation| + json.partial! old_relation +end diff --git a/app/views/api/old_relations/version.json.jbuilder b/app/views/api/old_relations/version.json.jbuilder new file mode 100644 index 000000000..5b33e4b85 --- /dev/null +++ b/app/views/api/old_relations/version.json.jbuilder @@ -0,0 +1,5 @@ +json.partial! "api/root_attributes" + +json.elements([@old_element]) do |old_relation| + json.partial! old_relation +end diff --git a/app/views/api/old_ways/_old_way.json.jbuilder b/app/views/api/old_ways/_old_way.json.jbuilder new file mode 100644 index 000000000..b2e79f879 --- /dev/null +++ b/app/views/api/old_ways/_old_way.json.jbuilder @@ -0,0 +1,13 @@ +json.type "way" +json.id old_way.way_id +json.timestamp old_way.timestamp.xmlschema +json.version old_way.version +json.changeset old_way.changeset_id +json.user old_way.changeset.user.display_name +json.uid old_way.changeset.user_id + +json.visible old_way.visible unless old_way.visible + +json.nodes old_way.nds unless old_way.nds.empty? + +json.tags old_way.tags unless old_way.tags.empty? diff --git a/app/views/api/old_ways/history.json.jbuilder b/app/views/api/old_ways/history.json.jbuilder new file mode 100644 index 000000000..b5cf80d09 --- /dev/null +++ b/app/views/api/old_ways/history.json.jbuilder @@ -0,0 +1,5 @@ +json.partial! "api/root_attributes" + +json.elements(@elems) do |old_way| + json.partial! old_way +end diff --git a/app/views/api/old_ways/version.json.jbuilder b/app/views/api/old_ways/version.json.jbuilder new file mode 100644 index 000000000..c66488526 --- /dev/null +++ b/app/views/api/old_ways/version.json.jbuilder @@ -0,0 +1,5 @@ +json.partial! "api/root_attributes" + +json.elements([@old_element]) do |old_way| + json.partial! old_way +end diff --git a/app/views/api/relations/_relation.json.jbuilder b/app/views/api/relations/_relation.json.jbuilder new file mode 100644 index 000000000..52263ce37 --- /dev/null +++ b/app/views/api/relations/_relation.json.jbuilder @@ -0,0 +1,19 @@ +json.type "relation" +json.id relation.id +json.timestamp relation.timestamp.xmlschema +json.version relation.version +json.changeset relation.changeset_id +json.user relation.changeset.user.display_name +json.uid relation.changeset.user_id + +json.visible relation.visible unless relation.visible + +unless relation.relation_members.empty? + json.members(relation.relation_members) do |m| + json.type m.member_type.downcase + json.ref m.member_id + json.role m.member_role + end +end + +json.tags relation.tags unless relation.tags.empty? diff --git a/app/views/api/relations/full.json.jbuilder b/app/views/api/relations/full.json.jbuilder new file mode 100644 index 000000000..98cbbfc40 --- /dev/null +++ b/app/views/api/relations/full.json.jbuilder @@ -0,0 +1,7 @@ +json.partial! "api/root_attributes" + +all = @nodes + @ways + @relations + +json.elements(all) do |obj| + json.partial! obj +end diff --git a/app/views/api/relations/index.json.jbuilder b/app/views/api/relations/index.json.jbuilder new file mode 100644 index 000000000..f170cb150 --- /dev/null +++ b/app/views/api/relations/index.json.jbuilder @@ -0,0 +1,5 @@ +json.partial! "api/root_attributes" + +json.elements(@relations) do |relation| + json.partial! relation +end diff --git a/app/views/api/relations/relations_for_node.json.jbuilder b/app/views/api/relations/relations_for_node.json.jbuilder new file mode 100644 index 000000000..f170cb150 --- /dev/null +++ b/app/views/api/relations/relations_for_node.json.jbuilder @@ -0,0 +1,5 @@ +json.partial! "api/root_attributes" + +json.elements(@relations) do |relation| + json.partial! relation +end diff --git a/app/views/api/relations/relations_for_relation.json.jbuilder b/app/views/api/relations/relations_for_relation.json.jbuilder new file mode 100644 index 000000000..f170cb150 --- /dev/null +++ b/app/views/api/relations/relations_for_relation.json.jbuilder @@ -0,0 +1,5 @@ +json.partial! "api/root_attributes" + +json.elements(@relations) do |relation| + json.partial! relation +end diff --git a/app/views/api/relations/relations_for_way.json.jbuilder b/app/views/api/relations/relations_for_way.json.jbuilder new file mode 100644 index 000000000..f170cb150 --- /dev/null +++ b/app/views/api/relations/relations_for_way.json.jbuilder @@ -0,0 +1,5 @@ +json.partial! "api/root_attributes" + +json.elements(@relations) do |relation| + json.partial! relation +end diff --git a/app/views/api/relations/show.json.jbuilder b/app/views/api/relations/show.json.jbuilder new file mode 100644 index 000000000..7f85d0f25 --- /dev/null +++ b/app/views/api/relations/show.json.jbuilder @@ -0,0 +1,5 @@ +json.partial! "api/root_attributes" + +json.elements([@relation]) do |relation| + json.partial! relation +end diff --git a/app/views/api/ways/_way.json.jbuilder b/app/views/api/ways/_way.json.jbuilder new file mode 100644 index 000000000..11e796bc8 --- /dev/null +++ b/app/views/api/ways/_way.json.jbuilder @@ -0,0 +1,13 @@ +json.type "way" +json.id way.id +json.timestamp way.timestamp.xmlschema +json.version way.version +json.changeset way.changeset_id +json.user way.changeset.user.display_name +json.uid way.changeset.user_id + +json.visible way.visible unless way.visible + +json.nodes way.nodes.ids unless way.nodes.ids.empty? + +json.tags way.tags unless way.tags.empty? diff --git a/app/views/api/ways/full.json.jbuilder b/app/views/api/ways/full.json.jbuilder new file mode 100644 index 000000000..bebad5e9f --- /dev/null +++ b/app/views/api/ways/full.json.jbuilder @@ -0,0 +1,7 @@ +json.partial! "api/root_attributes" + +all = @nodes + [@way] + +json.elements(all) do |obj| + json.partial! obj +end diff --git a/app/views/api/ways/index.json.jbuilder b/app/views/api/ways/index.json.jbuilder new file mode 100644 index 000000000..19e59cfb8 --- /dev/null +++ b/app/views/api/ways/index.json.jbuilder @@ -0,0 +1,5 @@ +json.partial! "api/root_attributes" + +json.elements(@ways) do |way| + json.partial! way +end diff --git a/app/views/api/ways/show.json.jbuilder b/app/views/api/ways/show.json.jbuilder new file mode 100644 index 000000000..acb93c1e7 --- /dev/null +++ b/app/views/api/ways/show.json.jbuilder @@ -0,0 +1,5 @@ +json.partial! "api/root_attributes" + +json.elements([@way]) do |way| + json.partial! way +end diff --git a/app/views/api/ways/ways_for_node.json.jbuilder b/app/views/api/ways/ways_for_node.json.jbuilder new file mode 100644 index 000000000..19e59cfb8 --- /dev/null +++ b/app/views/api/ways/ways_for_node.json.jbuilder @@ -0,0 +1,5 @@ +json.partial! "api/root_attributes" + +json.elements(@ways) do |way| + json.partial! way +end diff --git a/config/locales/de.yml b/config/locales/de.yml index 213891256..4a11885ba 100644 --- a/config/locales/de.yml +++ b/config/locales/de.yml @@ -739,7 +739,7 @@ de: farmyard: landwirtschaftliche Betriebsfläche forest: Wald garages: Garagen - grass: Wiese + grass: Gras greenfield: unerschlossenes Bauland industrial: Industriegebiet landfill: Deponie @@ -843,7 +843,7 @@ de: forest: Wald geyser: Geysir glacier: Gletscher - grassland: Wiese + grassland: Grasland heath: Heide hill: Hügel island: Insel diff --git a/config/locales/fit.yml b/config/locales/fit.yml index 5f7c29b04..992457630 100644 --- a/config/locales/fit.yml +++ b/config/locales/fit.yml @@ -600,7 +600,7 @@ fit: gpx_notification: greeting: Hei! your_gpx_file: Ylöslattaamasi GPX-fiili - with_description: ', jonka kuvvaus on' + with_description: ', jonka kuvvaus oon' failure: failed_to_import: 'epäonnistui importeerata. Täsä virhe:' more_info_1: Lissää tietoja GPX-importeerausongelmista ja miten niitä voi @@ -1097,8 +1097,8 @@ fit: title: Luodaan uusi redaktio show: description: 'Kuvvaus:' - heading: Näytetään redaktio ”%{title}” - title: Näytetään redaktio + heading: Näytethään redaktio ”%{title}” + title: Näytethään redaktio user: 'Luoja:' edit: Mookkaa tätä laitosta destroy: Ota poies tämä redaktio diff --git a/config/locales/ne.yml b/config/locales/ne.yml index 780ef6a5f..92da1e102 100644 --- a/config/locales/ne.yml +++ b/config/locales/ne.yml @@ -1049,7 +1049,7 @@ ne: title: नियमहरू ! traces: new: - upload_gpx: 'GPX फाइल अपलोड गर्ने:' + upload_gpx: 'जिपिएक्स फाइल उर्ध्वभरण गर्नुहाेस्:' description: 'विवरण:' tags: ट्यागहरूः tags_help: अल्पविरामले छुट्याएको diff --git a/db/functions/Makefile b/db/functions/Makefile index 6a3fbc0b9..a1259fc55 100644 --- a/db/functions/Makefile +++ b/db/functions/Makefile @@ -1,7 +1,8 @@ +BUNDLE ?= bundle PG_CONFIG ?= pg_config DESTDIR ?= . -QTDIR=$(shell bundle show quad_tile | tail -n 1)/ext/quad_tile +QTDIR=$(shell ${BUNDLE} show quad_tile | tail -n 1)/ext/quad_tile OS=$(shell uname -s) ifeq (${OS},Darwin) diff --git a/test/controllers/api/map_controller_test.rb b/test/controllers/api/map_controller_test.rb index db83aaa9f..9f14cc7fd 100644 --- a/test/controllers/api/map_controller_test.rb +++ b/test/controllers/api/map_controller_test.rb @@ -23,6 +23,87 @@ module Api { :path => "/api/0.6/map", :method => :get }, { :controller => "api/map", :action => "index" } ) + assert_routing( + { :path => "/api/0.6/map.json", :method => :get }, + { :controller => "api/map", :action => "index", :format => "json" } + ) + end + + ## + # test http accept headers + def test_http_accept_header + node = create(:node) + + minlon = node.lon - 0.1 + minlat = node.lat - 0.1 + maxlon = node.lon + 0.1 + maxlat = node.lat + 0.1 + bbox = "#{minlon},#{minlat},#{maxlon},#{maxlat}" + + # Accept: XML format -> use XML + http_accept_format("text/xml") + get :index, :params => { :bbox => bbox } + assert_response :success, "Expected success with the map call" + assert_equal "application/xml; charset=utf-8", @response.header["Content-Type"] + + # Accept: Any format -> use XML + http_accept_format("*/*") + get :index, :params => { :bbox => bbox } + assert_response :success, "Expected success with the map call" + assert_equal "application/xml; charset=utf-8", @response.header["Content-Type"] + + # Accept: Any format, .json URL suffix -> use json + http_accept_format("*/*") + get :index, :params => { :bbox => bbox, :format => "json" } + assert_response :success, "Expected success with the map call" + assert_equal "application/json; charset=utf-8", @response.header["Content-Type"] + + # Accept: Firefox header -> use XML + http_accept_format("text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8") + get :index, :params => { :bbox => bbox } + assert_response :success, "Expected success with the map call" + assert_equal "application/xml; charset=utf-8", @response.header["Content-Type"] + + # Accept: JOSM header text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2 -> use XML + # Note: JOSM's header does not comply with RFC 7231, section 5.3.1 + http_accept_format("text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2") + get :index, :params => { :bbox => bbox } + assert_response :success, "Expected success with the map call" + assert_equal "application/xml; charset=utf-8", @response.header["Content-Type"] + + # Accept: text/plain, */* -> use XML + http_accept_format("text/plain, */*") + get :index, :params => { :bbox => bbox } + assert_response :success, "Expected success with the map call" + assert_equal "application/xml; charset=utf-8", @response.header["Content-Type"] + + # Accept: text/* -> use XML + http_accept_format("text/*") + get :index, :params => { :bbox => bbox } + assert_response :success, "Expected success with the map call" + assert_equal "application/xml; charset=utf-8", @response.header["Content-Type"] + + # Accept: json, */* format -> use json + http_accept_format("application/json, */*") + get :index, :params => { :bbox => bbox } + assert_response :success, "Expected success with the map call" + assert_equal "application/json; charset=utf-8", @response.header["Content-Type"] + + # Accept: json format -> use json + http_accept_format("application/json") + get :index, :params => { :bbox => bbox } + assert_response :success, "Expected success with the map call" + assert_equal "application/json; charset=utf-8", @response.header["Content-Type"] + + # text/json is in invalid format, return HTTP 406 Not acceptable + http_accept_format("text/json") + get :index, :params => { :bbox => bbox } + assert_response :not_acceptable, "text/json should fail" + + # image/jpeg is a format which we don't support, return HTTP 406 Not acceptable + http_accept_format("image/jpeg") + get :index, :params => { :bbox => bbox } + assert_response :not_acceptable, "text/json should fail" end # ------------------------------------- @@ -63,6 +144,54 @@ module Api end end + def test_map_json + node = create(:node, :lat => 7, :lon => 7) + tag = create(:node_tag, :node => node) + way1 = create(:way_node, :node => node).way + way2 = create(:way_node, :node => node).way + relation = create(:relation_member, :member => node).relation + + # Need to split the min/max lat/lon out into their own variables here + # so that we can test they are returned later. + minlon = node.lon - 0.1 + minlat = node.lat - 0.1 + maxlon = node.lon + 0.1 + maxlat = node.lat + 0.1 + bbox = "#{minlon},#{minlat},#{maxlon},#{maxlat}" + get :index, :params => { :bbox => bbox, :format => "json" } + if $VERBOSE + print @request.to_yaml + print @response.body + end + assert_response :success, "Expected success with the map call" + js = ActiveSupport::JSON.decode(@response.body) + assert_not_nil js + + assert_equal Settings.api_version, js["version"] + assert_equal Settings.generator, js["generator"] + assert_equal GeoRecord::Coord.new(minlon), js["bounds"]["minlon"] + assert_equal GeoRecord::Coord.new(minlat), js["bounds"]["minlat"] + assert_equal GeoRecord::Coord.new(maxlon), js["bounds"]["maxlon"] + assert_equal GeoRecord::Coord.new(maxlat), js["bounds"]["maxlat"] + + result_nodes = js["elements"].select { |a| a["type"] == "node" } + .select { |a| a["id"] == node.id } + .select { |a| a["lat"] == GeoRecord::Coord.new(node.lat) } + .select { |a| a["lon"] == GeoRecord::Coord.new(node.lon) } + .select { |a| a["version"] == node.version } + .select { |a| a["changeset"] == node.changeset_id } + .select { |a| a["timestamp"] == node.timestamp.xmlschema } + assert_equal result_nodes.count, 1 + result_node = result_nodes.first + + assert_equal result_node["tags"], tag.k => tag.v + assert_equal 2, (js["elements"].count { |a| a["type"] == "way" }) + assert_equal 1, (js["elements"].count { |a| a["type"] == "way" && a["id"] == way1.id }) + assert_equal 1, (js["elements"].count { |a| a["type"] == "way" && a["id"] == way2.id }) + assert_equal 1, (js["elements"].count { |a| a["type"] == "relation" }) + assert_equal 1, (js["elements"].count { |a| a["type"] == "relation" && a["id"] == relation.id }) + 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 diff --git a/test/controllers/api/nodes_controller_test.rb b/test/controllers/api/nodes_controller_test.rb index aee41d515..e2174a126 100644 --- a/test/controllers/api/nodes_controller_test.rb +++ b/test/controllers/api/nodes_controller_test.rb @@ -13,6 +13,10 @@ module Api { :path => "/api/0.6/node/1", :method => :get }, { :controller => "api/nodes", :action => "show", :id => "1" } ) + assert_routing( + { :path => "/api/0.6/node/1.json", :method => :get }, + { :controller => "api/nodes", :action => "show", :id => "1", :format => "json" } + ) assert_routing( { :path => "/api/0.6/node/1", :method => :put }, { :controller => "api/nodes", :action => "update", :id => "1" } @@ -25,6 +29,10 @@ module Api { :path => "/api/0.6/nodes", :method => :get }, { :controller => "api/nodes", :action => "index" } ) + assert_routing( + { :path => "/api/0.6/nodes.json", :method => :get }, + { :controller => "api/nodes", :action => "index", :format => "json" } + ) end def test_create @@ -464,6 +472,19 @@ module Api assert_select "node[id='#{node5.id}'][visible='false']", :count => 1 end + # test a working call with json format + get :index, :params => { :nodes => "#{node1.id},#{node2.id},#{node3.id},#{node4.id},#{node5.id}", :format => "json" } + + js = ActiveSupport::JSON.decode(@response.body) + assert_not_nil js + assert_equal 5, js["elements"].count + assert_equal 5, (js["elements"].count { |a| a["type"] == "node" }) + assert_equal 1, (js["elements"].count { |a| a["id"] == node1.id && a["visible"].nil? }) + assert_equal 1, (js["elements"].count { |a| a["id"] == node2.id && a["visible"] == false }) + assert_equal 1, (js["elements"].count { |a| a["id"] == node3.id && a["visible"].nil? }) + assert_equal 1, (js["elements"].count { |a| a["id"] == node4.id && a["visible"].nil? }) + assert_equal 1, (js["elements"].count { |a| a["id"] == node5.id && a["visible"] == false }) + # check error when a non-existent node is included get :index, :params => { :nodes => "#{node1.id},#{node2.id},#{node3.id},#{node4.id},#{node5.id},0" } assert_response :not_found diff --git a/test/controllers/api/old_nodes_controller_test.rb b/test/controllers/api/old_nodes_controller_test.rb index 941787d0a..76e78ffad 100644 --- a/test/controllers/api/old_nodes_controller_test.rb +++ b/test/controllers/api/old_nodes_controller_test.rb @@ -17,6 +17,14 @@ module Api { :path => "/api/0.6/node/1/2", :method => :get }, { :controller => "api/old_nodes", :action => "version", :id => "1", :version => "2" } ) + assert_routing( + { :path => "/api/0.6/node/1/history.json", :method => :get }, + { :controller => "api/old_nodes", :action => "history", :id => "1", :format => "json" } + ) + assert_routing( + { :path => "/api/0.6/node/1/2.json", :method => :get }, + { :controller => "api/old_nodes", :action => "version", :id => "1", :version => "2", :format => "json" } + ) assert_routing( { :path => "/api/0.6/node/1/2/redact", :method => :post }, { :controller => "api/old_nodes", :action => "redact", :id => "1", :version => "2" } diff --git a/test/controllers/api/old_relations_controller_test.rb b/test/controllers/api/old_relations_controller_test.rb index 40a80248c..19e8ae357 100644 --- a/test/controllers/api/old_relations_controller_test.rb +++ b/test/controllers/api/old_relations_controller_test.rb @@ -13,6 +13,14 @@ module Api { :path => "/api/0.6/relation/1/2", :method => :get }, { :controller => "api/old_relations", :action => "version", :id => "1", :version => "2" } ) + assert_routing( + { :path => "/api/0.6/relation/1/history.json", :method => :get }, + { :controller => "api/old_relations", :action => "history", :id => "1", :format => "json" } + ) + assert_routing( + { :path => "/api/0.6/relation/1/2.json", :method => :get }, + { :controller => "api/old_relations", :action => "version", :id => "1", :version => "2", :format => "json" } + ) assert_routing( { :path => "/api/0.6/relation/1/2/redact", :method => :post }, { :controller => "api/old_relations", :action => "redact", :id => "1", :version => "2" } diff --git a/test/controllers/api/old_ways_controller_test.rb b/test/controllers/api/old_ways_controller_test.rb index 73e968f30..cd676a960 100644 --- a/test/controllers/api/old_ways_controller_test.rb +++ b/test/controllers/api/old_ways_controller_test.rb @@ -13,6 +13,14 @@ module Api { :path => "/api/0.6/way/1/2", :method => :get }, { :controller => "api/old_ways", :action => "version", :id => "1", :version => "2" } ) + assert_routing( + { :path => "/api/0.6/way/1/history.json", :method => :get }, + { :controller => "api/old_ways", :action => "history", :id => "1", :format => "json" } + ) + assert_routing( + { :path => "/api/0.6/way/1/2.json", :method => :get }, + { :controller => "api/old_ways", :action => "version", :id => "1", :version => "2", :format => "json" } + ) assert_routing( { :path => "/api/0.6/way/1/2/redact", :method => :post }, { :controller => "api/old_ways", :action => "redact", :id => "1", :version => "2" } diff --git a/test/controllers/api/relations_controller_test.rb b/test/controllers/api/relations_controller_test.rb index b7c17a176..da18099bd 100644 --- a/test/controllers/api/relations_controller_test.rb +++ b/test/controllers/api/relations_controller_test.rb @@ -13,10 +13,18 @@ module Api { :path => "/api/0.6/relation/1/full", :method => :get }, { :controller => "api/relations", :action => "full", :id => "1" } ) + assert_routing( + { :path => "/api/0.6/relation/1/full.json", :method => :get }, + { :controller => "api/relations", :action => "full", :id => "1", :format => "json" } + ) assert_routing( { :path => "/api/0.6/relation/1", :method => :get }, { :controller => "api/relations", :action => "show", :id => "1" } ) + assert_routing( + { :path => "/api/0.6/relation/1.json", :method => :get }, + { :controller => "api/relations", :action => "show", :id => "1", :format => "json" } + ) assert_routing( { :path => "/api/0.6/relation/1", :method => :put }, { :controller => "api/relations", :action => "update", :id => "1" } @@ -29,6 +37,10 @@ module Api { :path => "/api/0.6/relations", :method => :get }, { :controller => "api/relations", :action => "index" } ) + assert_routing( + { :path => "/api/0.6/relations.json", :method => :get }, + { :controller => "api/relations", :action => "index", :format => "json" } + ) assert_routing( { :path => "/api/0.6/node/1/relations", :method => :get }, @@ -42,6 +54,18 @@ module Api { :path => "/api/0.6/relation/1/relations", :method => :get }, { :controller => "api/relations", :action => "relations_for_relation", :id => "1" } ) + assert_routing( + { :path => "/api/0.6/node/1/relations.json", :method => :get }, + { :controller => "api/relations", :action => "relations_for_node", :id => "1", :format => "json" } + ) + assert_routing( + { :path => "/api/0.6/way/1/relations.json", :method => :get }, + { :controller => "api/relations", :action => "relations_for_way", :id => "1", :format => "json" } + ) + assert_routing( + { :path => "/api/0.6/relation/1/relations.json", :method => :get }, + { :controller => "api/relations", :action => "relations_for_relation", :id => "1", :format => "json" } + ) end # ------------------------------------- @@ -187,6 +211,18 @@ module Api assert_select "relation[id='#{relation4.id}'][visible='true']", :count => 1 end + # test a working call with json format + get :index, :params => { :relations => "#{relation1.id},#{relation2.id},#{relation3.id},#{relation4.id}", :format => "json" } + + js = ActiveSupport::JSON.decode(@response.body) + assert_not_nil js + assert_equal 4, js["elements"].count + assert_equal 4, (js["elements"].count { |a| a["type"] == "relation" }) + assert_equal 1, (js["elements"].count { |a| a["id"] == relation1.id && a["visible"].nil? }) + assert_equal 1, (js["elements"].count { |a| a["id"] == relation2.id && a["visible"] == false }) + assert_equal 1, (js["elements"].count { |a| a["id"] == relation3.id && a["visible"].nil? }) + assert_equal 1, (js["elements"].count { |a| a["id"] == relation4.id && a["visible"].nil? }) + # check error when a non-existent relation is included get :index, :params => { :relations => "#{relation1.id},#{relation2.id},#{relation3.id},#{relation4.id},0" } assert_response :not_found diff --git a/test/controllers/api/ways_controller_test.rb b/test/controllers/api/ways_controller_test.rb index 433b43f27..e4b9f3663 100644 --- a/test/controllers/api/ways_controller_test.rb +++ b/test/controllers/api/ways_controller_test.rb @@ -13,10 +13,18 @@ module Api { :path => "/api/0.6/way/1/full", :method => :get }, { :controller => "api/ways", :action => "full", :id => "1" } ) + assert_routing( + { :path => "/api/0.6/way/1/full.json", :method => :get }, + { :controller => "api/ways", :action => "full", :id => "1", :format => "json" } + ) assert_routing( { :path => "/api/0.6/way/1", :method => :get }, { :controller => "api/ways", :action => "show", :id => "1" } ) + assert_routing( + { :path => "/api/0.6/way/1.json", :method => :get }, + { :controller => "api/ways", :action => "show", :id => "1", :format => "json" } + ) assert_routing( { :path => "/api/0.6/way/1", :method => :put }, { :controller => "api/ways", :action => "update", :id => "1" } @@ -29,6 +37,10 @@ module Api { :path => "/api/0.6/ways", :method => :get }, { :controller => "api/ways", :action => "index" } ) + assert_routing( + { :path => "/api/0.6/ways.json", :method => :get }, + { :controller => "api/ways", :action => "index", :format => "json" } + ) end # ------------------------------------- @@ -104,6 +116,18 @@ module Api assert_select "way[id='#{way4.id}'][visible='true']", :count => 1 end + # test a working call with json format + get :index, :params => { :ways => "#{way1.id},#{way2.id},#{way3.id},#{way4.id}", :format => "json" } + + js = ActiveSupport::JSON.decode(@response.body) + assert_not_nil js + assert_equal 4, js["elements"].count + assert_equal 4, (js["elements"].count { |a| a["type"] == "way" }) + assert_equal 1, (js["elements"].count { |a| a["id"] == way1.id && a["visible"].nil? }) + assert_equal 1, (js["elements"].count { |a| a["id"] == way2.id && a["visible"] == false }) + assert_equal 1, (js["elements"].count { |a| a["id"] == way3.id && a["visible"].nil? }) + assert_equal 1, (js["elements"].count { |a| a["id"] == way4.id && a["visible"].nil? }) + # check error when a non-existent way is included get :index, :params => { :ways => "#{way1.id},#{way2.id},#{way3.id},#{way4.id},0" } assert_response :not_found diff --git a/test/helpers/browse_tags_helper_test.rb b/test/helpers/browse_tags_helper_test.rb index a6390df38..fb90eb51d 100644 --- a/test/helpers/browse_tags_helper_test.rb +++ b/test/helpers/browse_tags_helper_test.rb @@ -221,6 +221,57 @@ class BrowseTagsHelperTest < ActionView::TestCase assert_nil link end + def test_email_link + email = email_link("foo", "Test") + assert_nil email + + email = email_link("email", "123") + assert_nil email + + email = email_link("email", "Abc.example.com") + assert_nil email + + email = email_link("email", "a@b@c.com") + assert_nil email + + email = email_link("email", "just\"not\"right@example.com") + assert_nil email + + email = email_link("email", "123 abcdefg@space.com") + assert_nil email + + email = email_link("email", "test@ abc") + assert_nil email + + email = email_link("email", "using;semicolon@test.com") + assert_nil email + + email = email_link("email", "x@example.com") + assert_equal "x@example.com", email[:email] + assert_equal "mailto:x@example.com", email[:url] + + email = email_link("email", "other.email-with-hyphen@example.com") + assert_equal "other.email-with-hyphen@example.com", email[:email] + assert_equal "mailto:other.email-with-hyphen@example.com", email[:url] + + email = email_link("email", "user.name+tag+sorting@example.com") + assert_equal "user.name+tag+sorting@example.com", email[:email] + assert_equal "mailto:user.name+tag+sorting@example.com", email[:url] + + email = email_link("email", "dash-in@both-parts.com") + assert_equal "dash-in@both-parts.com", email[:email] + assert_equal "mailto:dash-in@both-parts.com", email[:url] + + email = email_link("email", "example@s.example") + assert_equal "example@s.example", email[:email] + assert_equal "mailto:example@s.example", email[:url] + + # Strips whitespace at ends + email = email_link("email", " test@email.com ") + assert_equal "test@email.com", email[:email] + assert_equal "mailto:test@email.com", email[:url] + end + def test_telephone_links links = telephone_links("foo", "Test") assert_nil links diff --git a/test/test_helper.rb b/test/test_helper.rb index 378d49bb9..08f01e8e7 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -115,6 +115,12 @@ module ActiveSupport @request.env["HTTP_AUTHORIZATION"] = format("Basic %{auth}", :auth => Base64.encode64("#{user}:#{pass}")) end + ## + # set request header for HTTP Accept + def http_accept_format(format) + @request.env["HTTP_ACCEPT"] = format + end + ## # set request readers to ask for a particular error format def error_format(format)