]> git.openstreetmap.org Git - rails.git/commitdiff
Merge remote-tracking branch 'upstream/pull/2051'
authorTom Hughes <tom@compton.nu>
Thu, 8 Nov 2018 17:51:23 +0000 (17:51 +0000)
committerTom Hughes <tom@compton.nu>
Thu, 8 Nov 2018 17:51:23 +0000 (17:51 +0000)
75 files changed:
.rubocop_todo.yml
Gemfile
Gemfile.lock
Vendorfile
app/controllers/api_controller.rb
app/controllers/changeset_comments_controller.rb [new file with mode: 0644]
app/controllers/changeset_controller.rb
app/controllers/diary_entries_controller.rb [moved from app/controllers/diary_entry_controller.rb with 82% similarity]
app/controllers/nodes_controller.rb [moved from app/controllers/node_controller.rb with 98% similarity]
app/controllers/old_nodes_controller.rb [moved from app/controllers/old_node_controller.rb with 84% similarity]
app/controllers/old_relations_controller.rb [moved from app/controllers/old_relation_controller.rb with 83% similarity]
app/controllers/old_ways_controller.rb [moved from app/controllers/old_way_controller.rb with 84% similarity]
app/controllers/relations_controller.rb [moved from app/controllers/relation_controller.rb with 99% similarity]
app/controllers/ways_controller.rb [moved from app/controllers/way_controller.rb with 98% similarity]
app/models/concerns/geo_record.rb
app/views/browse/feature.html.erb
app/views/browse/history.html.erb
app/views/changeset_comments/_comment.html.erb [moved from app/views/changeset/_comment.html.erb with 51% similarity]
app/views/changeset_comments/_comments.rss.builder [moved from app/views/changeset/_comments.rss.builder with 82% similarity]
app/views/changeset_comments/index.rss.builder [moved from app/views/changeset/comments_feed.rss.builder with 70% similarity]
app/views/changeset_comments/timeout.atom.builder [new file with mode: 0644]
app/views/changeset_comments/timeout.html.erb [new file with mode: 0644]
app/views/diary_entries/_diary_comment.html.erb [moved from app/views/diary_entry/_diary_comment.html.erb with 100% similarity]
app/views/diary_entries/_diary_entry.html.erb [moved from app/views/diary_entry/_diary_entry.html.erb with 95% similarity]
app/views/diary_entries/_diary_index_entry.html.erb [moved from app/views/diary_entry/_diary_index_entry.html.erb with 100% similarity]
app/views/diary_entries/_location.html.erb [moved from app/views/diary_entry/_location.html.erb with 100% similarity]
app/views/diary_entries/comments.html.erb [moved from app/views/diary_entry/comments.html.erb with 100% similarity]
app/views/diary_entries/edit.html.erb [moved from app/views/diary_entry/edit.html.erb with 96% similarity]
app/views/diary_entries/index.html.erb [moved from app/views/diary_entry/index.html.erb with 87% similarity]
app/views/diary_entries/no_such_entry.html.erb [moved from app/views/diary_entry/no_such_entry.html.erb with 100% similarity]
app/views/diary_entries/rss.rss.builder [moved from app/views/diary_entry/rss.rss.builder with 100% similarity]
app/views/diary_entries/show.html.erb [moved from app/views/diary_entry/show.html.erb with 100% similarity]
app/views/users/show.html.erb
config/locales/ar.yml
config/locales/bn.yml
config/locales/br.yml
config/locales/da.yml
config/locales/de.yml
config/locales/el.yml
config/locales/en.yml
config/locales/eo.yml
config/locales/es.yml
config/locales/fa.yml
config/locales/fr.yml
config/locales/hu.yml
config/locales/it.yml
config/locales/ko.yml
config/locales/mk.yml
config/locales/mo.yml
config/locales/nl.yml
config/locales/pt-BR.yml
config/locales/pt-PT.yml
config/locales/ru.yml
config/locales/tr.yml
config/locales/zh-TW.yml
config/routes.rb
test/controllers/api_controller_test.rb
test/controllers/browse_controller_test.rb
test/controllers/changeset_comments_controller_test.rb [new file with mode: 0644]
test/controllers/changeset_controller_test.rb
test/controllers/diary_entries_controller_test.rb [moved from test/controllers/diary_entry_controller_test.rb with 94% similarity]
test/controllers/geocoder_controller_test.rb
test/controllers/nodes_controller_test.rb [moved from test/controllers/node_controller_test.rb with 98% similarity]
test/controllers/old_nodes_controller_test.rb [moved from test/controllers/old_node_controller_test.rb with 96% similarity]
test/controllers/old_relations_controller_test.rb [moved from test/controllers/old_relation_controller_test.rb with 97% similarity]
test/controllers/old_ways_controller_test.rb [moved from test/controllers/old_way_controller_test.rb with 97% similarity]
test/controllers/redactions_controller_test.rb
test/controllers/relations_controller_test.rb [moved from test/controllers/relation_controller_test.rb with 97% similarity]
test/controllers/ways_controller_test.rb [moved from test/controllers/way_controller_test.rb with 98% similarity]
test/helpers/application_helper_test.rb
test/integration/user_diaries_test.rb
test/models/redaction_test.rb
test/system/report_diary_comment_test.rb
test/system/report_diary_entry_test.rb
vendor/assets/leaflet/leaflet.locate.js

index 7d2c583eb73c4ebff19e52adc3367559e83757c2..7232d199b03b52a27137d55691389f75b6413f87 100644 (file)
@@ -48,7 +48,7 @@ Metrics/BlockNesting:
 # Offense count: 63
 # Configuration parameters: CountComments.
 Metrics/ClassLength:
-  Max: 1801
+  Max: 1627
 
 # Offense count: 72
 Metrics/CyclomaticComplexity:
@@ -177,7 +177,7 @@ Style/FrozenStringLiteralComment:
 # Cop supports --auto-correct.
 Style/IfUnlessModifier:
   Exclude:
-    - 'app/controllers/way_controller.rb'
+    - 'app/controllers/ways_controller.rb'
 
 # Offense count: 70
 # Cop supports --auto-correct.
diff --git a/Gemfile b/Gemfile
index 05bfc6cbd3e6d14ea36f335a468cf6767038de70..5eb559113b883aa8aa54b6f482cb5773b6a6565a 100644 (file)
--- a/Gemfile
+++ b/Gemfile
@@ -45,6 +45,7 @@ gem "image_optim_rails"
 
 # Load rails plugins
 gem "actionpack-page_caching"
+gem "active_record_union"
 gem "cancancan"
 gem "composite_primary_keys", "~> 11.0.0"
 gem "delayed_job_active_record"
index 72f769929033edf0790dbfe20be7567cfda32b40..6472d586ac1667e25ddb628a839e513553ad666e 100644 (file)
@@ -29,6 +29,8 @@ GEM
       erubi (~> 1.4)
       rails-dom-testing (~> 2.0)
       rails-html-sanitizer (~> 1.0, >= 1.0.3)
+    active_record_union (1.3.0)
+      activerecord (>= 4.0)
     activejob (5.2.0)
       activesupport (= 5.2.0)
       globalid (>= 0.3.6)
@@ -66,7 +68,7 @@ GEM
     bootsnap (1.3.2)
       msgpack (~> 1.0)
     builder (3.2.3)
-    cancancan (2.1.3)
+    cancancan (2.3.0)
     canonical-rails (0.2.4)
       rails (>= 4.1, < 5.3)
     capybara (2.18.0)
@@ -88,7 +90,7 @@ GEM
     coffee-script-source (1.12.2)
     composite_primary_keys (11.0.3)
       activerecord (~> 5.2.0)
-    concurrent-ruby (1.0.5)
+    concurrent-ruby (1.1.3)
     coveralls (0.8.22)
       json (>= 1.8, < 3)
       simplecov (~> 0.16.1)
@@ -177,7 +179,7 @@ GEM
       mini_mime (>= 0.1.1)
     marcel (0.3.3)
       mimemagic (~> 0.3.2)
-    method_source (0.9.0)
+    method_source (0.9.1)
     mime-types (3.2.2)
       mime-types-data (~> 3.2015)
     mime-types-data (3.2018.0812)
@@ -255,7 +257,7 @@ GEM
     puma (3.12.0)
     quad_tile (1.0.1)
     r2 (0.2.7)
-    rack (2.0.5)
+    rack (2.0.6)
     rack-cors (1.0.2)
     rack-openid (1.3.1)
       rack (>= 1.1.0)
@@ -346,7 +348,7 @@ GEM
       actionpack (>= 4.0)
       activesupport (>= 4.0)
       sprockets (>= 3.0.0)
-    term-ansicolor (1.6.0)
+    term-ansicolor (1.7.0)
       tins (~> 1.0)
     terrapin (0.6.0)
       climate_control (>= 0.0.3, < 1.0)
@@ -356,7 +358,7 @@ GEM
     thor (0.19.4)
     thread_safe (0.3.6)
     tilt (2.0.8)
-    tins (1.17.0)
+    tins (1.18.0)
     tzinfo (1.2.5)
       thread_safe (~> 0.1)
     uglifier (4.1.19)
@@ -382,6 +384,7 @@ DEPENDENCIES
   SystemTimer (>= 1.1.3)
   aasm
   actionpack-page_caching
+  active_record_union
   annotate
   autoprefixer-rails (~> 8.6.3)
   better_errors
index 15a8eba1b04b72b3d7698f0c3d184492787da434..85eb49b9b2ba613779a0b4711c51670831682f40 100644 (file)
@@ -31,7 +31,7 @@ folder 'vendor/assets' do
       folder 'img', 'src/img'
     end
 
-    from 'git://github.com/domoritz/leaflet-locatecontrol.git', :tag => 'v0.62.0' do
+    from 'git://github.com/domoritz/leaflet-locatecontrol.git', :tag => 'v0.64.0' do
       file 'leaflet.locate.js', 'src/L.Control.Locate.js'
     end
 
index 81b8bca5323f3cbe33bb1a2c990679b8a9ca5cce..d97feace24d748afa86be812e582493561818d62 100644 (file)
@@ -30,7 +30,9 @@ class ApiController < ApplicationController
     end
 
     # get all the points
-    points = Tracepoint.bbox(bbox).offset(offset).limit(TRACEPOINTS_PER_PAGE).order("gpx_id DESC, trackid ASC, timestamp ASC")
+    ordered_points = Tracepoint.bbox(bbox).joins(:trace).where(:gpx_files => { :visibility => %w[trackable identifiable] }).order("gpx_id DESC, trackid ASC, timestamp ASC")
+    unordered_points = Tracepoint.bbox(bbox).joins(:trace).where(:gpx_files => { :visibility => %w[public private] }).order("gps_points.latitude", "gps_points.longitude", "gps_points.timestamp")
+    points = ordered_points.union_all(unordered_points).offset(offset).limit(TRACEPOINTS_PER_PAGE)
 
     doc = XML::Document.new
     doc.encoding = XML::Encoding::UTF_8
diff --git a/app/controllers/changeset_comments_controller.rb b/app/controllers/changeset_comments_controller.rb
new file mode 100644 (file)
index 0000000..6a563f9
--- /dev/null
@@ -0,0 +1,125 @@
+class ChangesetCommentsController < ApplicationController
+  before_action :authorize_web, :only => [:index]
+  before_action :set_locale, :only => [:index]
+  before_action :authorize, :only => [:create, :destroy, :restore]
+  before_action :require_moderator, :only => [:destroy, :restore]
+  before_action :require_allow_write_api, :only => [:create, :destroy, :restore]
+  before_action :require_public_data, :only => [:create]
+  before_action :check_api_writable, :only => [:create, :destroy, :restore]
+  before_action :check_api_readable, :except => [:create, :index]
+  before_action(:only => [:index]) { |c| c.check_database_readable(true) }
+  around_action :api_call_handle_error, :except => [:index]
+  around_action :api_call_timeout, :except => [:index]
+  around_action :web_timeout, :only => [:index]
+
+  ##
+  # Add a comment to a changeset
+  def create
+    # Check the arguments are sane
+    raise OSM::APIBadUserInput, "No id was given" unless params[:id]
+    raise OSM::APIBadUserInput, "No text was given" if params[:text].blank?
+
+    # Extract the arguments
+    id = params[:id].to_i
+    body = params[:text]
+
+    # Find the changeset and check it is valid
+    changeset = Changeset.find(id)
+    raise OSM::APIChangesetNotYetClosedError, changeset if changeset.is_open?
+
+    # Add a comment to the changeset
+    comment = changeset.comments.create(:changeset => changeset,
+                                        :body => body,
+                                        :author => current_user)
+
+    # Notify current subscribers of the new comment
+    changeset.subscribers.visible.each do |user|
+      Notifier.changeset_comment_notification(comment, user).deliver_later if current_user != user
+    end
+
+    # Add the commenter to the subscribers if necessary
+    changeset.subscribers << current_user unless changeset.subscribers.exists?(current_user.id)
+
+    # Return a copy of the updated changeset
+    render :xml => changeset.to_xml.to_s
+  end
+
+  ##
+  # Sets visible flag on comment to false
+  def destroy
+    # Check the arguments are sane
+    raise OSM::APIBadUserInput, "No id was given" unless params[:id]
+
+    # Extract the arguments
+    id = params[:id].to_i
+
+    # Find the changeset
+    comment = ChangesetComment.find(id)
+
+    # Hide the comment
+    comment.update(:visible => false)
+
+    # Return a copy of the updated changeset
+    render :xml => comment.changeset.to_xml.to_s
+  end
+
+  ##
+  # Sets visible flag on comment to true
+  def restore
+    # Check the arguments are sane
+    raise OSM::APIBadUserInput, "No id was given" unless params[:id]
+
+    # Extract the arguments
+    id = params[:id].to_i
+
+    # Find the changeset
+    comment = ChangesetComment.find(id)
+
+    # Unhide the comment
+    comment.update(:visible => true)
+
+    # Return a copy of the updated changeset
+    render :xml => comment.changeset.to_xml.to_s
+  end
+
+  ##
+  # Get a feed of recent changeset comments
+  def index
+    if params[:id]
+      # Extract the arguments
+      id = params[:id].to_i
+
+      # Find the changeset
+      changeset = Changeset.find(id)
+
+      # Return comments for this changeset only
+      @comments = changeset.comments.includes(:author, :changeset).limit(comments_limit)
+    else
+      # Return comments
+      @comments = ChangesetComment.includes(:author, :changeset).where(:visible => true).order("created_at DESC").limit(comments_limit).preload(:changeset)
+    end
+
+    # Render the result
+    respond_to do |format|
+      format.rss
+    end
+  rescue OSM::APIBadUserInput
+    head :bad_request
+  end
+
+  private
+
+  ##
+  # Get the maximum number of comments to return
+  def comments_limit
+    if params[:limit]
+      if params[:limit].to_i.positive? && params[:limit].to_i <= 10000
+        params[:limit].to_i
+      else
+        raise OSM::APIBadUserInput, "Comments limit must be between 1 and 10000"
+      end
+    else
+      100
+    end
+  end
+end
index 4ce205fd1513698dbfc9adeca3d5a48414a99ff0..7c9944f631effda92b800144e1ff74a9bb8039a8 100644 (file)
@@ -5,18 +5,17 @@ class ChangesetController < ApplicationController
   require "xml/libxml"
 
   skip_before_action :verify_authenticity_token, :except => [:index]
-  before_action :authorize_web, :only => [:index, :feed, :comments_feed]
-  before_action :set_locale, :only => [:index, :feed, :comments_feed]
-  before_action :authorize, :only => [:create, :update, :upload, :close, :comment, :subscribe, :unsubscribe, :hide_comment, :unhide_comment]
-  before_action :require_moderator, :only => [:hide_comment, :unhide_comment]
-  before_action :require_allow_write_api, :only => [:create, :update, :upload, :close, :comment, :subscribe, :unsubscribe, :hide_comment, :unhide_comment]
-  before_action :require_public_data, :only => [:create, :update, :upload, :close, :comment, :subscribe, :unsubscribe]
-  before_action :check_api_writable, :only => [:create, :update, :upload, :comment, :subscribe, :unsubscribe, :hide_comment, :unhide_comment]
-  before_action :check_api_readable, :except => [:create, :update, :upload, :download, :query, :index, :feed, :comment, :subscribe, :unsubscribe, :comments_feed]
-  before_action(:only => [:index, :feed, :comments_feed]) { |c| c.check_database_readable(true) }
-  around_action :api_call_handle_error, :except => [:index, :feed, :comments_feed]
-  around_action :api_call_timeout, :except => [:index, :feed, :comments_feed, :upload]
-  around_action :web_timeout, :only => [:index, :feed, :comments_feed]
+  before_action :authorize_web, :only => [:index, :feed]
+  before_action :set_locale, :only => [:index, :feed]
+  before_action :authorize, :only => [:create, :update, :upload, :close, :subscribe, :unsubscribe]
+  before_action :require_allow_write_api, :only => [:create, :update, :upload, :close, :subscribe, :unsubscribe]
+  before_action :require_public_data, :only => [:create, :update, :upload, :close, :subscribe, :unsubscribe]
+  before_action :check_api_writable, :only => [:create, :update, :upload, :subscribe, :unsubscribe]
+  before_action :check_api_readable, :except => [:create, :update, :upload, :download, :query, :index, :feed, :subscribe, :unsubscribe]
+  before_action(:only => [:index, :feed]) { |c| c.check_database_readable(true) }
+  around_action :api_call_handle_error, :except => [:index, :feed]
+  around_action :api_call_timeout, :except => [:index, :feed, :upload]
+  around_action :web_timeout, :only => [:index, :feed]
 
   # Helper methods for checking consistency
   include ConsistencyValidations
@@ -310,38 +309,6 @@ class ChangesetController < ApplicationController
     index
   end
 
-  ##
-  # Add a comment to a changeset
-  def comment
-    # Check the arguments are sane
-    raise OSM::APIBadUserInput, "No id was given" unless params[:id]
-    raise OSM::APIBadUserInput, "No text was given" if params[:text].blank?
-
-    # Extract the arguments
-    id = params[:id].to_i
-    body = params[:text]
-
-    # Find the changeset and check it is valid
-    changeset = Changeset.find(id)
-    raise OSM::APIChangesetNotYetClosedError, changeset if changeset.is_open?
-
-    # Add a comment to the changeset
-    comment = changeset.comments.create(:changeset => changeset,
-                                        :body => body,
-                                        :author => current_user)
-
-    # Notify current subscribers of the new comment
-    changeset.subscribers.visible.each do |user|
-      Notifier.changeset_comment_notification(comment, user).deliver_later if current_user != user
-    end
-
-    # Add the commenter to the subscribers if necessary
-    changeset.subscribers << current_user unless changeset.subscribers.exists?(current_user.id)
-
-    # Return a copy of the updated changeset
-    render :xml => changeset.to_xml.to_s
-  end
-
   ##
   # Adds a subscriber to the changeset
   def subscribe
@@ -382,69 +349,6 @@ class ChangesetController < ApplicationController
     render :xml => changeset.to_xml.to_s
   end
 
-  ##
-  # Sets visible flag on comment to false
-  def hide_comment
-    # Check the arguments are sane
-    raise OSM::APIBadUserInput, "No id was given" unless params[:id]
-
-    # Extract the arguments
-    id = params[:id].to_i
-
-    # Find the changeset
-    comment = ChangesetComment.find(id)
-
-    # Hide the comment
-    comment.update(:visible => false)
-
-    # Return a copy of the updated changeset
-    render :xml => comment.changeset.to_xml.to_s
-  end
-
-  ##
-  # Sets visible flag on comment to true
-  def unhide_comment
-    # Check the arguments are sane
-    raise OSM::APIBadUserInput, "No id was given" unless params[:id]
-
-    # Extract the arguments
-    id = params[:id].to_i
-
-    # Find the changeset
-    comment = ChangesetComment.find(id)
-
-    # Unhide the comment
-    comment.update(:visible => true)
-
-    # Return a copy of the updated changeset
-    render :xml => comment.changeset.to_xml.to_s
-  end
-
-  ##
-  # Get a feed of recent changeset comments
-  def comments_feed
-    if params[:id]
-      # Extract the arguments
-      id = params[:id].to_i
-
-      # Find the changeset
-      changeset = Changeset.find(id)
-
-      # Return comments for this changeset only
-      @comments = changeset.comments.includes(:author, :changeset).limit(comments_limit)
-    else
-      # Return comments
-      @comments = ChangesetComment.includes(:author, :changeset).where(:visible => true).order("created_at DESC").limit(comments_limit).preload(:changeset)
-    end
-
-    # Render the result
-    respond_to do |format|
-      format.rss
-    end
-  rescue OSM::APIBadUserInput
-    head :bad_request
-  end
-
   private
 
   #------------------------------------------------------------
@@ -577,18 +481,4 @@ class ChangesetController < ApplicationController
   def conditions_nonempty(changesets)
     changesets.where("num_changes > 0")
   end
-
-  ##
-  # Get the maximum number of comments to return
-  def comments_limit
-    if params[:limit]
-      if params[:limit].to_i.positive? && params[:limit].to_i <= 10000
-        params[:limit].to_i
-      else
-        raise OSM::APIBadUserInput, "Comments limit must be between 1 and 10000"
-      end
-    else
-      100
-    end
-  end
 end
similarity index 82%
rename from app/controllers/diary_entry_controller.rb
rename to app/controllers/diary_entries_controller.rb
index 70cb1654da8c9d0f7adf5b56197d482d81d54626..456ce99adc92499713a5e7995c37789b65b477e1 100644 (file)
@@ -1,4 +1,4 @@
-class DiaryEntryController < ApplicationController
+class DiaryEntriesController < ApplicationController
   layout "site", :except => :rss
 
   before_action :authorize_web
@@ -12,7 +12,7 @@ class DiaryEntryController < ApplicationController
   before_action :allow_thirdparty_images, :only => [:new, :edit, :index, :show, :comments]
 
   def new
-    @title = t "diary_entry.new.title"
+    @title = t "diary_entries.new.title"
 
     if request.post?
       @diary_entry = DiaryEntry.new(entry_params)
@@ -44,7 +44,7 @@ class DiaryEntryController < ApplicationController
   end
 
   def edit
-    @title = t "diary_entry.edit.title"
+    @title = t "diary_entries.edit.title"
     @diary_entry = DiaryEntry.find(params[:id])
 
     if current_user != @diary_entry.user
@@ -105,7 +105,7 @@ class DiaryEntryController < ApplicationController
       @user = User.active.find_by(:display_name => params[:display_name])
 
       if @user
-        @title = t "diary_entry.index.user_title", :user => @user.display_name
+        @title = t "diary_entries.index.user_title", :user => @user.display_name
         @entries = @user.diary_entries
       else
         render_unknown_user params[:display_name]
@@ -113,7 +113,7 @@ class DiaryEntryController < ApplicationController
       end
     elsif params[:friends]
       if current_user
-        @title = t "diary_entry.index.title_friends"
+        @title = t "diary_entries.index.title_friends"
         @entries = DiaryEntry.where(:user_id => current_user.friend_users)
       else
         require_user
@@ -121,7 +121,7 @@ class DiaryEntryController < ApplicationController
       end
     elsif params[:nearby]
       if current_user
-        @title = t "diary_entry.index.title_nearby"
+        @title = t "diary_entries.index.title_nearby"
         @entries = DiaryEntry.where(:user_id => current_user.nearby)
       else
         require_user
@@ -131,10 +131,10 @@ class DiaryEntryController < ApplicationController
       @entries = DiaryEntry.joins(:user).where(:users => { :status => %w[active confirmed] })
 
       if params[:language]
-        @title = t "diary_entry.index.in_language_title", :language => Language.find(params[:language]).english_name
+        @title = t "diary_entries.index.in_language_title", :language => Language.find(params[:language]).english_name
         @entries = @entries.where(:language_code => params[:language])
       else
-        @title = t "diary_entry.index.title"
+        @title = t "diary_entries.index.title"
       end
     end
 
@@ -156,9 +156,9 @@ class DiaryEntryController < ApplicationController
 
       if user
         @entries = user.diary_entries
-        @title = t("diary_entry.feed.user.title", :user => user.display_name)
-        @description = t("diary_entry.feed.user.description", :user => user.display_name)
-        @link = url_for :controller => "diary_entry", :action => "index", :display_name => user.display_name, :host => SERVER_URL, :protocol => SERVER_PROTOCOL
+        @title = t("diary_entries.feed.user.title", :user => user.display_name)
+        @description = t("diary_entries.feed.user.description", :user => user.display_name)
+        @link = url_for :action => "index", :display_name => user.display_name, :host => SERVER_URL, :protocol => SERVER_PROTOCOL
       else
         head :not_found
         return
@@ -168,13 +168,13 @@ class DiaryEntryController < ApplicationController
 
       if params[:language]
         @entries = @entries.where(:language_code => params[:language])
-        @title = t("diary_entry.feed.language.title", :language_name => Language.find(params[:language]).english_name)
-        @description = t("diary_entry.feed.language.description", :language_name => Language.find(params[:language]).english_name)
-        @link = url_for :controller => "diary_entry", :action => "index", :language => params[:language], :host => SERVER_URL, :protocol => SERVER_PROTOCOL
+        @title = t("diary_entries.feed.language.title", :language_name => Language.find(params[:language]).english_name)
+        @description = t("diary_entries.feed.language.description", :language_name => Language.find(params[:language]).english_name)
+        @link = url_for :action => "index", :language => params[:language], :host => SERVER_URL, :protocol => SERVER_PROTOCOL
       else
-        @title = t("diary_entry.feed.all.title")
-        @description = t("diary_entry.feed.all.description")
-        @link = url_for :controller => "diary_entry", :action => "index", :host => SERVER_URL, :protocol => SERVER_PROTOCOL
+        @title = t("diary_entries.feed.all.title")
+        @description = t("diary_entries.feed.all.description")
+        @link = url_for :action => "index", :host => SERVER_URL, :protocol => SERVER_PROTOCOL
       end
     end
 
@@ -184,9 +184,9 @@ class DiaryEntryController < ApplicationController
   def show
     @entry = @user.diary_entries.visible.where(:id => params[:id]).first
     if @entry
-      @title = t "diary_entry.show.title", :user => params[:display_name], :title => @entry.title
+      @title = t "diary_entries.show.title", :user => params[:display_name], :title => @entry.title
     else
-      @title = t "diary_entry.no_such_entry.title", :id => params[:id]
+      @title = t "diary_entries.no_such_entry.title", :id => params[:id]
       render :action => "no_such_entry", :status => :not_found
     end
   end
similarity index 98%
rename from app/controllers/node_controller.rb
rename to app/controllers/nodes_controller.rb
index 84b814a34529fae1cd3c5be327b418e5c47a04b3..baa6d8195abd92491f57d3e1794d6adeb119ab30 100644 (file)
@@ -1,6 +1,6 @@
 # The NodeController is the RESTful interface to Node objects
 
-class NodeController < ApplicationController
+class NodesController < ApplicationController
   require "xml/libxml"
 
   skip_before_action :verify_authenticity_token
similarity index 84%
rename from app/controllers/old_node_controller.rb
rename to app/controllers/old_nodes_controller.rb
index a32e299fe6a2481833b901fd3995ceec475809d5..43c8b6b7572719b1c9a14fbc1afefb2c43a3acd7 100644 (file)
@@ -1,4 +1,4 @@
-class OldNodeController < OldController
+class OldNodesController < OldController
   private
 
   def lookup_old_element
similarity index 83%
rename from app/controllers/old_relation_controller.rb
rename to app/controllers/old_relations_controller.rb
index 78eca324cb4cb819e0450f089b179de947b074f3..40c450376a8e435cc8981c44cd9892ce15160653 100644 (file)
@@ -1,4 +1,4 @@
-class OldRelationController < OldController
+class OldRelationsController < OldController
   private
 
   def lookup_old_element
similarity index 84%
rename from app/controllers/old_way_controller.rb
rename to app/controllers/old_ways_controller.rb
index 1daab997ae2c4f72899e9d9276df89880d1af423..c8185c633dd7c605deb58bbc3134f047a37d1a65 100644 (file)
@@ -1,4 +1,4 @@
-class OldWayController < OldController
+class OldWaysController < OldController
   private
 
   def lookup_old_element
similarity index 99%
rename from app/controllers/relation_controller.rb
rename to app/controllers/relations_controller.rb
index 059fb8d7e5bc32a7dca26128a705b800c4b0c16d..b9108cea1c5fb8f72245479ea28fde4fff5eb251 100644 (file)
@@ -1,4 +1,4 @@
-class RelationController < ApplicationController
+class RelationsController < ApplicationController
   require "xml/libxml"
 
   skip_before_action :verify_authenticity_token
similarity index 98%
rename from app/controllers/way_controller.rb
rename to app/controllers/ways_controller.rb
index e48073e10063073cfb72a28756d074efa0407403..39129ebf3486494f9be7bf76f036747c86c03bf4 100644 (file)
@@ -1,4 +1,4 @@
-class WayController < ApplicationController
+class WaysController < ApplicationController
   require "xml/libxml"
 
   skip_before_action :verify_authenticity_token
index 06049c2951b25876999cc7e3ee0fc070bacd97e6..dbda2960f65ce6ad72d7eaf996b9bbee76fc57e0 100644 (file)
@@ -22,7 +22,7 @@ module GeoRecord
   SCALE = 10000000
 
   included do
-    scope :bbox, ->(bbox) { where(OSM.sql_for_area(bbox)) }
+    scope :bbox, ->(bbox) { where(OSM.sql_for_area(bbox, "#{table_name}.")) }
     before_save :update_tile
   end
 
index 38657f4d1fb8f976868bb375b94e0feb206b7088..c3fadbe312e26a516fcb2d623f9bc3cf0a48dc75 100644 (file)
@@ -8,7 +8,7 @@
 <%= render :partial => @type, :object => @feature %>
 
 <div class='secondary-actions'>
-  <%= link_to(t('browse.download_xml'), :controller => @type, :action => "read") %>
+  <%= link_to(t('browse.download_xml'), :controller => @type.pluralize, :action => "read") %>
   &middot;
   <%= link_to(t('browse.view_history'), :action => "#{@type}_history") %>
 </div>
index 5f5dd4db3274b789890cac68a562ad72cfd3e191..6cf0a35698fc6e8eadcdf9337a54692a0dc9665b 100644 (file)
@@ -8,7 +8,7 @@
 <%= render :partial => @type, :collection => @feature.send("old_#{@type}s").reverse %>
 
 <div class='secondary-actions'>
-  <%= link_to(t('browse.download_xml'), :controller => "old_#{@type}", :action => "history") %>
+  <%= link_to(t('browse.download_xml'), :controller => "old_#{@type.pluralize}", :action => "history") %>
   &middot;
   <%= link_to(t('browse.view_details'), :action => @type) %>
 </div>
similarity index 51%
rename from app/views/changeset/_comment.html.erb
rename to app/views/changeset_comments/_comment.html.erb
index dfd91167b486e02831464253c2cb31c377b0d1ea..32a4b9229de1c4e2e039c36c0f75ead908067c39 100644 (file)
@@ -1,6 +1,6 @@
-<h2><%= t "changeset.rss.comment", :author => comment.author.display_name, 
+<h2><%= t ".comment", :author => comment.author.display_name,
   :changeset_id => comment.changeset.id.to_s %></h2>
 <div class="changeset-comment" style="margin-top: 5px">
-  <div class="changeset-comment-description" style="font-size: smaller; color: #999999"><%= t "changeset.rss.commented_at_by_html", :when => friendly_date(comment.created_at), :user => comment.author.display_name %></div>
+  <div class="changeset-comment-description" style="font-size: smaller; color: #999999"><%= t ".commented_at_by_html", :when => friendly_date(comment.created_at), :user => comment.author.display_name %></div>
   <div class="changeset-comment-text"><%= comment.body %></div>
 </div>
similarity index 82%
rename from app/views/changeset/_comments.rss.builder
rename to app/views/changeset_comments/_comments.rss.builder
index 5c683c86d8ec224fe42ddd6d1bd5d5dc16e019ed..8848b9a80ddc8328de356936fe8bd9936cea441f 100644 (file)
@@ -1,6 +1,6 @@
 comments.each do |comment|
   xml.item do
-    xml.title t("changeset.rss.comment", :author => comment.author.display_name, :changeset_id => comment.changeset.id.to_s)
+    xml.title t(".comment", :author => comment.author.display_name, :changeset_id => comment.changeset.id.to_s)
 
     xml.link url_for(:controller => "browse", :action => "changeset", :id => comment.changeset.id, :anchor => "c#{comment.id}", :only_path => false)
     xml.guid url_for(:controller => "browse", :action => "changeset", :id => comment.changeset.id, :anchor => "c#{comment.id}", :only_path => false)
similarity index 70%
rename from app/views/changeset/comments_feed.rss.builder
rename to app/views/changeset_comments/index.rss.builder
index f6d304a4cbd9bf8c6a4da50d1dba7341cbd23650..acaa54727279e21a7a6816c5f8d39fad26b5bce8 100644 (file)
@@ -2,9 +2,9 @@ xml.rss("version" => "2.0",
         "xmlns:dc" => "http://purl.org/dc/elements/1.1/") do
   xml.channel do
     if @changeset
-      xml.title t("changeset.rss.title_particular", :changeset_id => @changeset.id)
+      xml.title t(".title_particular", :changeset_id => @changeset.id)
     else
-      xml.title t("changeset.rss.title_all")
+      xml.title t(".title_all")
     end
     xml.link url_for(:controller => "site", :action => "index", :only_path => false)
 
diff --git a/app/views/changeset_comments/timeout.atom.builder b/app/views/changeset_comments/timeout.atom.builder
new file mode 100644 (file)
index 0000000..b5eeeed
--- /dev/null
@@ -0,0 +1,12 @@
+atom_feed(:language => I18n.locale, :schema_date => 2009,
+          :id => url_for(params.merge(:only_path => false)),
+          :root_url => url_for(params.merge(:only_path => false, :format => nil)),
+          "xmlns:georss" => "http://www.georss.org/georss") do |feed|
+  feed.title @title
+
+  feed.subtitle :type => "xhtml" do |xhtml|
+    xhtml.p do |p|
+      p << t(".sorry")
+    end
+  end
+end
diff --git a/app/views/changeset_comments/timeout.html.erb b/app/views/changeset_comments/timeout.html.erb
new file mode 100644 (file)
index 0000000..84432bc
--- /dev/null
@@ -0,0 +1 @@
+<p><%= t '.sorry' %></p>
similarity index 95%
rename from app/views/diary_entry/_diary_entry.html.erb
rename to app/views/diary_entries/_diary_entry.html.erb
index ec2f22601ce625925ec8dbe6fea0dea465d2744d..e41eeae662dc5d5167e6149b3d5bbc19e49f3ffc 100644 (file)
@@ -7,7 +7,7 @@
     <h2><%= link_to h(diary_entry.title), diary_entry_path(diary_entry.user, diary_entry) %></h2>
 
     <small class='deemphasize'>
-      <%= raw(t '.posted_by', :link_user => (link_to h(diary_entry.user.display_name), user_path(diary_entry.user)), :created => l(diary_entry.created_at, :format => :blog), :language_link => (link_to h(diary_entry.language.name), :controller => 'diary_entry', :action => 'index', :display_name => nil, :language => diary_entry.language_code)) %>
+      <%= raw(t '.posted_by', :link_user => (link_to h(diary_entry.user.display_name), user_path(diary_entry.user)), :created => l(diary_entry.created_at, :format => :blog), :language_link => (link_to h(diary_entry.language.name), :controller => 'diary_entries', :action => 'index', :display_name => nil, :language => diary_entry.language_code)) %>
     </small>
 
   </div>
similarity index 96%
rename from app/views/diary_entry/edit.html.erb
rename to app/views/diary_entries/edit.html.erb
index d408938e5ac8aafd8e49a700e13f66fe5d9c9ed1..b46dadf1cfd3dde7f8df3ec0bda403ba3b9c3edb 100644 (file)
@@ -43,7 +43,7 @@
     </fieldset>
 
     <% if action_name == 'new' %>
-      <%= submit_tag t('diary_entry.new.publish_button') %>
+      <%= submit_tag t('diary_entries.new.publish_button') %>
     <% else %>
       <%= submit_tag t('.save_button') %>
     <% end %>
similarity index 87%
rename from app/views/diary_entry/index.html.erb
rename to app/views/diary_entries/index.html.erb
index 021cb205847ffa466f061536507100f9d7372da4..63a805b3c5be2679740e5a5b74f81142946584de 100644 (file)
       <% if @user %>
         <% if @user == current_user %>
           <div>
-            <li><%= link_to image_tag("new.png", :class => "small_icon", :border=>0) + t('.new'), {:controller => 'diary_entry', :action => 'new'}, {:title => t('.new_title')} %></li>
+            <li><%= link_to image_tag("new.png", :class => "small_icon", :border=>0) + t('.new'), diary_new_path, {:title => t('.new_title')} %></li>
           </div>
         <% end %>
       <% else %>
         <% if current_user %>
           <div>
-            <li><%= link_to image_tag("new.png", :class => "small_icon", :border=>0) + t('.new'), {:controller => 'diary_entry', :action => 'new'}, {:title => t('.new_title')} %></li>
+            <li><%= link_to image_tag("new.png", :class => "small_icon", :border=>0) + t('.new'), diary_new_path, {:title => t('.new_title')} %></li>
           </div>
         <% end %>
       <% end %>
index 7aa3abd2782b958ee8761ca7edf25f7d1d44e052..c7a41b687b71c300068a07fc58a308c70cda7374 100644 (file)
             <span class='count-number'><%= number_with_delimiter(current_user.traces.size) %></span>
           </li>
           <li>
-            <%= link_to t('.my diary'), :controller => 'diary_entry', :action => 'index', :display_name => current_user.display_name %>
+            <%= link_to t('.my diary'), :controller => 'diary_entries', :action => 'index', :display_name => current_user.display_name %>
             <span class='count-number'><%= number_with_delimiter(current_user.diary_entries.size) %></span>
           </li>
           <li>
-            <%= link_to t('.my comments' ), :controller => 'diary_entry', :action => 'comments', :display_name => current_user.display_name %>
+            <%= link_to t('.my comments' ), :controller => 'diary_entries', :action => 'comments', :display_name => current_user.display_name %>
           </li>
           <li>
             <%= link_to t('.my settings'), :controller => 'users', :action => 'account', :display_name => current_user.display_name %>
             <%= link_to t('.send message'), new_message_path(@user) %>
           </li>
           <li>
-            <%= link_to t('.diary'), :controller => 'diary_entry', :action => 'index', :display_name => @user.display_name %>
+            <%= link_to t('.diary'), :controller => 'diary_entries', :action => 'index', :display_name => @user.display_name %>
             <span class='count-number'><%= number_with_delimiter(@user.diary_entries.size) %></span>
           </li>
           <li>
-            <%= link_to t('.comments'), :controller => 'diary_entry', :action => 'comments', :display_name => @user.display_name %>
+            <%= link_to t('.comments'), :controller => 'diary_entries', :action => 'comments', :display_name => @user.display_name %>
           </li>
           <li>
             <% if current_user and current_user.is_friends_with?(@user) %>
index 718f301192510d563a31f1fefb75c97e9cceb883..8f39978bba12a192e996df6e340e8a9a85eaba13 100644 (file)
@@ -2662,4 +2662,9 @@ ar:
         هذا التنقيح قبل تدميره.
       flash: التنقيح تم تدميره.
       error: حدث خطأ في تدمير هذا التنقيح.
+  validations:
+    leading_whitespace: لديه مسافة بيضاء أمامية
+    trailing_whitespace: لديه مسافة بيضاء زائدة
+    invalid_characters: يحتوي على أحرف غير صالحة
+    url_characters: يحتوي على أحرف يو آر إل خاصة (%{characters})
 ...
index b248348721fc0fc2c513577adf00b34524b45bd4..ec97318efe720625eb7ee92fd86c00c1b2dfbdc5 100644 (file)
@@ -6,6 +6,7 @@
 # Author: Bodhisattwa
 # Author: Ehsanulhb
 # Author: Elias Ahmmad
+# Author: Gronthokeet
 # Author: Kayser Ahmad
 # Author: Nasir8891
 # Author: R4bb1
@@ -314,10 +315,12 @@ bn:
       edit_link: এই ভুক্তি সম্পাদনা করুন
       hide_link: এই ভুক্তি লুকান
       confirm: নিশ্চিত করুন
+      report: এই ভুক্তির বিরুদ্ধে অভিযোগ করুন
     diary_comment:
       comment_from: '%{comment_created_at}-এ %{link_user} কর্তৃক মন্তব্য'
       hide_link: এই মন্তব্যটি লুকান
       confirm: নিশ্চিত করুন
+      report: এই মন্তব্যের বিরুদ্ধে অভিযোগ করুন
     location:
       location: 'অবস্থান:'
       view: দেখাও
@@ -361,6 +364,7 @@ bn:
           aerodrome: বিমানশালা
           apron: বর্হিবাস
           gate: প্রবেশপথ
+          hangar: বিমান রাখার স্থান
           helipad: হেলিপ্যাড
           parking_position: পার্কিং-এর স্থান
           runway: রানওয়ে
@@ -421,6 +425,7 @@ bn:
           office: দপ্তর
           parking: পার্কিং
           parking_entrance: পার্কিং প্রবেশপথ
+          parking_space: গাড়ি রাখার স্থান
           pharmacy: ঔষধালয়
           place_of_worship: উপাসনালয়
           police: পুলিশ
@@ -456,6 +461,7 @@ bn:
           youth_centre: যুব কেন্দ্র
         boundary:
           administrative: প্রশাসনিক সীমানা
+          census: আদমশুমারি এলাকা
           national_park: জাতীয় উদ্যান
           protected_area: সুরক্ষিত এলাকা
         bridge:
@@ -479,8 +485,10 @@ bn:
           "yes": কারুকাজ দোকান
         emergency:
           ambulance_station: রুগ্নবাহিকা স্টেশন
+          defibrillator: ডিফাইব্রিলেটর
           landing_site: জরুরি অবতরণ ক্ষেত্র
           phone: জরুরি ফোন
+          water_tank: জরুরি পানির ট্যাংক
           "yes": জরুরী
         highway:
           abandoned: পরিত্যক্ত মহাসড়ক
@@ -493,6 +501,7 @@ bn:
           emergency_access_point: জরুরি প্রবেশ স্থল
           footway: ফুটপাথ
           milestone: মাইলফলক
+          motorway: মোটরপথ
           path: পাথ
           pedestrian: পাদচারী পথ
           platform: প্লাটফর্ম
@@ -508,12 +517,13 @@ bn:
           service: পার্শ্ব সড়ক
           speed_camera: গতিমাপক ক্যামেরা
           steps: ধাপ
-          stop: à¦¥à¦¾à¦\95ার চিহ্ন
+          stop: à¦¥à¦¾à¦®ার চিহ্ন
           street_lamp: রাস্তার বাতি
           tertiary: প্রশাখা সড়ক
           tertiary_link: প্রশাখা সড়ক
           track: নির্ধারিত পথ
           traffic_signals: ট্রাফিক সংকেত
+          trail: চলাচলের নিশানা
           trunk: মূল সড়ক
           trunk_link: মূল সড়ক
           unclassified: অশ্রেণীকৃত সড়ক
@@ -523,6 +533,7 @@ bn:
           battlefield: যুদ্ধক্ষেত্র
           boundary_stone: সীমানাজ্ঞাপক পাথর
           building: ঐতিহাসিক ভবন
+          bunker: আপদকালীন ভূগর্ভস্থ আশ্রয়স্থল
           castle: কেল্লা
           church: গির্জা
           city_gate: নগর দ্বার
@@ -540,6 +551,8 @@ bn:
           stone: প্রস্তর
           tomb: সমাধি
           tower: মিনার
+          wreck: ভগ্নাবশেষ
+          "yes": ঐতিহাসিক স্থান
         junction:
           "yes": জংশন
         landuse:
@@ -571,27 +584,49 @@ bn:
           "yes": ব্যবহার্য ভূমি
         leisure:
           beach_resort: সৈকতীয় রিসোর্ট
+          bird_hide: পক্ষীদর্শন স্থান
           common: সাধারণ ভূমি
           dog_park: কুকুর উদ্যান
           fishing: মৎস শিকারের এলাকা
+          fitness_centre: শরীরচর্চা কেন্দ্র
           garden: বাগান
           golf_course: গল্ফ মাঠ
+          horse_riding: অশ্বারোহণ
+          miniature_golf: ক্ষুদ্রাকৃতির গল্ফ
           nature_reserve: সংরক্ষিত প্রাকৃতিক ভূমি
           park: উদ্যান
+          pitch: খেলার পিচ
           playground: খেলার মাঠ
           recreation_ground: চিত্তবিনোদন মাঠ
           resort: রিসোর্ট
+          sauna: বাষ্পস্নান
+          slipway: নৌকা ছাড়ার পথ
           sports_centre: ক্রীড়া কেন্দ্র
           stadium: ক্রিড়াঙ্গন
           swimming_pool: সুইমিং পুল
           water_park: বারি উদ্যান
           "yes": অবসর
         man_made:
+          adit: খনি সুড়ঙ্গ
+          beehive: মৌমাছির কৃত্রিম বাসা
+          breakwater: বেড়িবাঁধ
           bridge: সেতু
+          bunker_silo: গাড়ি ভর্তি ও খালি করার জায়গা
+          chimney: চিম্নী
+          crane: কপিকল
+          dyke: বাঁধ
+          flagpole: সতর্কীকরণ পতাকা
           lighthouse: বাতিঘর
+          mast: টাওয়ার
           mine: খনি
+          monitoring_station: আবহাওয়া পর্যবেক্ষ্ণ কেন্দ্র
+          petroleum_well: তেলের খনি
           pipeline: পাইপলাইন
+          silo: সিলো
+          surveillance: নজরদারী ক্যামেরা
           tower: টাওয়ার
+          water_tower: পানির ট্যাংক
+          water_well: পানির কূপ
           works: কারখানা
           "yes": মনুষ্য-নির্মিত
         military:
@@ -1324,15 +1359,26 @@ bn:
         rest_of_world: অন্যান্য দেশসমূহ
     show:
       my edits: আমার সম্পাদনা
+      my messages: আমার বার্তাসমূহ
       my profile: আমার প্রোফাইল
       my settings: আমার সেটিংস
+      my comments: আমার মন্তব্যস্মূহ
       oauth settings: OAuth সেটিংস
+      send message: বার্তা পাঠান
+      diary: দিনলিপি
       edits: সম্পাদনাসমূহ
+      remove as friend: আনফ্রেন্ড
+      add as friend: বন্ধু যোগ করুন
+      mapper since: থেকে ম্যাপ বানাচ্ছেন
+      ct undecided: সিদ্ধান্তহীন
+      ct declined: বাতিলকৃত
       email address: 'ই-মেইল ঠিকানা:'
       description: বিবরণ
+      user location: ব্যবহারকারীর অবস্থান
       settings_link_text: সেটিংস
       my friends: আমার বন্ধুগণ
       no friends: আপনি বন্ধুতালিকায় কাউকে যুক্ত করেননি।
+      nearby users: কাছাকাছি অন্য ব্যবহারকারী
       block_history: সক্রিয় বাধাসমূহ
       moderator_history: প্রদত্ত বাধাগুলি
       comments: মন্তব্যসমূহ
index faf77a5151b7908f7ecb83adb1e95a54699c682b..2541d0c641ef5c2b72aa3e55c76137b20c0ed190 100644 (file)
@@ -219,6 +219,7 @@ br:
       reopened_by_anonymous: Adweredekaet gant un den dianv <abbr title='%{exact_time}'>%{when}
         zo</abbr>
       hidden_by: Kuzhet gant %{user} <abbr title='%{exact_time}'>%{when} zo</abbr>
+      report: Disklêriañ an notenn-mañ
     query:
       title: Arc'hweladurioù enklask
       introduction: Klikit war ar gartenn evit kavout arc'hweladurioù e-kichen.
@@ -959,6 +960,7 @@ br:
     update:
       new_report: Enrollet mat eo bet ho tanevell
       successful_update: Hizivaet mat eo bet ho tanevell
+      provide_details: Reiñ ar munudoù goulennet
     show:
       title: '%{status} Kudenn #%{issue_id}'
       reports:
@@ -983,6 +985,25 @@ br:
   issue_comments:
     create:
       comment_created: Krouet mat eo bet hoc'h evezhiadenn.
+  reports:
+    new:
+      title_html: Danevell %{link}
+      missing_params: N'haller ket krouiñ un danevell nevez
+      details: Roit muioc'h a vunudoù diwar-benn ar gudenn (dre ret)
+      disclaimer:
+        not_just_mistake: Sur oc'h n'eo ket ar gudenn-se ur fazi hepken.
+      categories:
+        diary_entry:
+          other_label: All
+        diary_comment:
+          other_label: All
+        user:
+          other_label: All
+        note:
+          other_label: All
+    create:
+      successful_report: Enrollet mat eo bet ho tanevell
+      provide_details: Roit ar munudoù goulennet mar plij
   layouts:
     logo:
       alt_text: Logo OpenStreetMap
@@ -996,6 +1017,7 @@ br:
     edit: Aozañ
     history: Istor
     export: Ezporzhiañ
+    issues: Kudennoù
     data: Roadennoù
     export_data: Ezporzhiañ roadennoù
     gps_traces: Roudoù GPS
@@ -1683,8 +1705,10 @@ br:
       tags_help: bevennet gant virgulennoù
       visibility: 'Gwelusted :'
       visibility_help: Petra a dalvez ?
+      visibility_help_url: https://wiki.openstreetmap.org/wiki/FR:Visibilit%C3%A9_des_traces_GPS
       upload_button: Enporzhiañ
       help: Skoazell
+      help_url: https://wiki.openstreetmap.org/wiki/FR:Upload
     create:
       upload_trace: Kas ar roud GPS
       trace_uploaded: Kaset eo bet ho restr GPX hag emañ en gortoz a vezañ ensoc'het
@@ -1731,8 +1755,9 @@ br:
       delete_trace: Dilemel ar roudenn-mañ
       trace_not_found: N'eo ket bet kavet ar roud !
       visibility: 'Gwelusted :'
+      confirm_delete: Diverkañ ar roudenn-mañ
     trace_paging_nav:
-      showing_page: Page %{page}
+      showing_page: Pajenn %{page}
       older: ↓Roudoù kozh
       newer: ↓Roudoù nevez
     trace:
@@ -1753,6 +1778,7 @@ br:
       map: kartenn
     index:
       public_traces: Roudoù GPS foran
+      my_traces: Ma roudennoù GPS
       public_traces_from: Roudoù GPS foran gant %{user}
       description: Furchal ar roud GPS pellgarget nevez zo
       tagged_with: ' balizennet gant %{tags}'
@@ -1761,6 +1787,7 @@ br:
         ar <abajenn wiki>href='https://wiki.openstreetmap.org/wiki/Beginners_Guide_1.2i</a>.
       upload_trace: Kas ur roud
       see_all_traces: Gwelet an holl roudoù
+      see_my_traces: Gwelet ma roudennoù
     delete:
       scheduled_for_deletion: Roudenn da vezañ dilamet
     make_public:
@@ -1781,8 +1808,13 @@ br:
     require_cookies:
       cookies_needed: Diweredekaet eo an toupinoù ganeoc'h war a seblant - gweredekait
         an toupinoù en ho merdeer a-raok mont pelloc'h, mar plij.
+    require_admin:
+      not_an_admin: Ret eo deoc'h bezañ merour evit kas an ober-mañ da benn.
     require_moderator:
       not_a_moderator: Ret eo deoc'h bezañ habaskaer evit kas an ober-mañ da benn.
+    require_moderator_or_admin:
+      not_a_moderator_or_admin: Ret eo deoc'h bezañ habaskaer pe merour evit kas an
+        ober-mañ da benn.
     setup_user_auth:
       blocked_zero_hour: Ur gemennadenn vallus zo war lec'hienn OpenStreetMap evidoc'h.
         Ret eo deoc'h lenn ar gemennadenn-se a-raok gallout enrollañ ho kemmoù.
@@ -2001,10 +2033,12 @@ br:
       consider_pd: Ouzhpenn an asant amañ a-us, ez anavezan emañ ma zegasadennoù en
         domani foran
       consider_pd_why: petra eo se ?
+      consider_pd_why_url: https://www.osmfoundation.org/wiki/License/Why_would_I_want_my_contributions_to_be_public_domain
       guidance: 'Titouroù da skoazellañ kompren an termenoù-mañ : a <a href="%{summary}">diverradenn
         lennus gant mab-den</a> hag un nebeud <a href="%{translations}">troidigezhioù
         anfurmel</a>'
       agree: Mat eo din
+      declined: https://wiki.openstreetmap.org/wiki/Contributor_Terms_Declined
       decline: Nac'h
       you need to accept or decline: Lennit da gentañ Termenoù ar berzhidi nevez ha
         goude-se nac'hit pe asantit evit gallout kenderc'hel.
@@ -2055,6 +2089,7 @@ br:
       if set location: Lakait ho lec'h-annez war ar bajenn %{settings_link} da welet
         an implijerien war-dro.
       settings_link_text: arventennoù
+      my friends: Ma mignoned
       no friends: N'hoc'h eus ouzhpennet mignon ebet c'hoazh.
       km away: war-hed %{count} km
       m away: war-hed %{count} m
@@ -2124,6 +2159,7 @@ br:
         review link text: Heuilhit al liamm-mañ evel ma karot evit sellet ouzh diferadennoù
           nevez ar c'henlabourer hag asantiñ dezho.
         agreed_with_pd: Disklêriet hoc'h eus ivez emañ ho tegasadennoù en domani foran.
+        link: https://www.osmfoundation.org/wiki/License/Contributor_Terms
         link text: Petra eo se ?
       profile description: 'Deskrivadur ar profil :'
       preferred languages: 'Yezhoù gwellañ karet :'
@@ -2498,12 +2534,20 @@ br:
       distance: Hed
       errors:
         no_route: Ne c'haller ket kavout un hent etre an daou lec'h-mañ.
-        no_place: Ho tigarez, ne c'haller ket kavout al lec'h-mañ.
+        no_place: 'Ho tigarez, ne c''haller ket kavout al lec''h-mañ : %{place}.'
       instructions:
         continue_without_exit: Kenderc'hel war%{name}
         slight_right_without_exit: Troit un tammig a-zehoù war %{name}
         offramp_right_with_name: Kemer ar vretell dehou %{name}
+        offramp_right_with_directions: Kemer ar vretell dehou war-zu %{directions}
+        offramp_right_with_name_directions: Kemer ar vretell dehou war %{name}, war-zu
+          %{directions}
         onramp_right_without_exit: Troit a-zehoù war ar bretell war %{name}
+        onramp_right_with_directions: Troit a-zehoù war ar vretell war-zu %{directions}
+        onramp_right_with_name_directions: Troit a-zehou war ar vretell war %{name},
+          war-zu %{directions}
+        onramp_right_without_directions: Treiñ a-zehou war ar vretell
+        onramp_right: Troit a gleiz war ar vretell
         endofroad_right_without_exit: E penn an hent, troit a-zezhoù war %{name}
         merge_right_without_exit: Mont a-zehoù war %{name}
         fork_right_without_exit: Er forc'h-hent, troit a-zehoù war %{name}
@@ -2512,8 +2556,17 @@ br:
         uturn_without_exit: Grit hanter dro war %{name}
         sharp_left_without_exit: Troit prim a-gleiz war %{name}
         turn_left_without_exit: Treiñ a-gleiz war %{name}
+        offramp_left: Troit a gleiz war ar vretell
         offramp_left_with_name: Kemer ar vretell gleiz betek %{name}
+        offramp_left_with_directions: Troit a-gleiz war ar vretell war-zu %{directions}
+        offramp_left_with_name_directions: Troit a-gleiz war ar vretell war %{name},
+          war-zu %{directions}
         onramp_left_without_exit: Troit a-gleiz war ar vretell war %{name}
+        onramp_left_with_directions: Troit a-gleiz war ar vretell war-zu %{directions}
+        onramp_left_with_name_directions: Troit a-gleiz war ar vretell war %{name},
+          war-zu %{directions}
+        onramp_left_without_directions: Troit a-gleiz war ar vretell
+        onramp_left: Troit a-gleiz war ar vretell
         endofroad_left_without_exit: E penn an hent, troit a-gleiz war %{name}
         merge_left_without_exit: Mont a-gleiz war %{name}
         fork_left_without_exit: Er forc'h-hent, troit a-gleiz war %{name}
@@ -2523,7 +2576,7 @@ br:
         roundabout_without_exit: Er c'hroashent-tro, troit %{name}
         leave_roundabout_without_exit: Kuitaat ar c'roashent-tro - %{name}
         stay_roundabout_without_exit: Chom war ar c'hroashent-tro -%{name}
-        start_without_exit: Loc'hañ e dibenn %{name}
+        start_without_exit: Loc'hañ war %{name}
         destination_without_exit: Tizhout al lec'h
         against_oneway_without_exit: Mont gant ar straed untu war %{name}
         end_oneway_without_exit: Dibenn an tremen untun war %{name}
index 8f662f344737bf404ef3930c0d57c79a902a987c..7966d36f000a39cf10c768249db84cf434e5b98f 100644 (file)
@@ -967,6 +967,7 @@ da:
       reported_user: Rapporteret bruger
       not_updated: Ikke opdateret
       search: Søg
+      search_guidance: 'Søgning blandt sager:'
       user_not_found: Brugeren findes ikke
       status: Status
       reports: Rapporter
@@ -2641,4 +2642,6 @@ da:
         der tilhører denne omarbejdelse, før du sletter den.
       flash: Omarbejdelse slettet.
       error: Der opstod en fejl under sletning af denne omarbejdelse.
+  validations:
+    invalid_characters: indholder ugyldige tegn
 ...
index d0e38546b19ee5a189467138a66bfc7bb28aef24..666592b07f3b052cfcfc4027d09765326ed242c2 100644 (file)
@@ -2793,4 +2793,9 @@ de:
         zugehörigen Versionen zurück, bevor du die Redaction löschst.
       flash: Redaction wurde gelöscht.
       error: Beim Löschen dieser Redaction ist ein Fehler aufgetreten.
+  validations:
+    leading_whitespace: hat anführendes Leerzeichen
+    trailing_whitespace: hat anhängendes Leerzeichen
+    invalid_characters: enthält ungültige Zeichen
+    url_characters: enthält besondere URL-Zeichen (%{characters})
 ...
index 57f0a26cc81a3eae4ee1aaadff4d62c6a926a237..ad4f8ee47d0aa9978dcc398be5ba5b6818c9bf20 100644 (file)
@@ -2764,4 +2764,6 @@ el:
         σε αυτή τη σύνταξη πριν την καταστρέψετε.
       flash: Η παράληψη καταστραφεί.
       error: Εμφανίστηκε ένα σφάλμα που καταστρέφει αυτή τη σύνταξη.
+  validations:
+    invalid_characters: περιέχει μη έγκυρους χαρακτήρες
 ...
index a9370018aabba1ad6ddecff6fdd0f786c208f044..197c6308ccb3385c0250396a5ad791bd8c2cce00 100644 (file)
@@ -242,14 +242,18 @@ en:
       load_more: "Load more"
     timeout:
       sorry: "Sorry, the list of changesets you requested took too long to retrieve."
-    rss:
-      title_all: OpenStreetMap changeset discussion
-      title_particular: "OpenStreetMap changeset #%{changeset_id} discussion"
+  changeset_comments:
+    comment:
       comment: "New comment on changeset #%{changeset_id} by %{author}"
-      commented_at_html: "Updated %{when} ago"
       commented_at_by_html: "Updated %{when} ago by %{user}"
-      full: Full discussion
-  diary_entry:
+    comments:
+      comment: "New comment on changeset #%{changeset_id} by %{author}"
+    index:
+      title_all: OpenStreetMap changeset discussion
+      title_particular: "OpenStreetMap changeset #%{changeset_id} discussion"
+    timeout:
+      sorry: "Sorry, the list of changeset comments you requested took too long to retrieve."
+  diary_entries:
     new:
       title: New Diary Entry
       publish_button: "Publish"
index f10147286550324f6a1e521402c907da3c2c0e63..9c7462781794928faea3e8dc6ac899ad35fda2ed 100644 (file)
@@ -665,7 +665,7 @@ eo:
           monitoring_station: Observada stacio
           petroleum_well: Naftoŝakto
           pier: Marponto
-          pipeline: Tubolinio
+          pipeline: Konduktubo
           silo: Tur-stokejo
           storage_tank: Rezervujo
           surveillance: Supergardo
index e0aa65cef4d78a33dbc18eb9abfbb568d2f9e04d..3b7bee66c7e2798b405a1246d446afd3c98ef30f 100644 (file)
@@ -2757,4 +2757,6 @@ es:
         previas pertenecientes a esta redacción antes de destruirla.
       flash: Redacción destruida.
       error: Se produjo un error al destruir esta redacción
+  validations:
+    invalid_characters: contiene caracteres no válidos
 ...
index 2f4b77dc6cac7a18ca1c5c313a1244b525ec4115..bc47886e68efa327a637e1c6993bc97df92bc394 100644 (file)
@@ -1248,8 +1248,8 @@ fa:
         english_link: اصل انگلیسی
       native:
         title: درباره این صفحه
-        text: شما در حال مشاهده ویرایش انگلیسی قانون کپی‌رایت هستید.  برای دیدن %{native_link}  می
-          توانید به عقب باز گردید یا خواندن متن کپی رایت و %{mapping_link} را متوقف
+        text: شما در حال مشاهدهٔ ویرایش انگلیسی قانون کپی‌رایت هستید. برای دیدن %{native_link}
+          می‌توانید به عقب بازگردید یا مطالعه دربارهٔ کپی‌رایت را رها و %{mapping_link}
           کنید.
         native_link: نسخهٔ فارسی
         mapping_link: شروع به نقشه‌کشی
@@ -1693,7 +1693,7 @@ fa:
       owner: 'مالک:'
       description: 'شرح:'
       tags: 'برچسب‌ها:'
-      none: هیچ کدام
+      none: هیچ
       edit_trace: ویرایش این رد
       delete_trace: حذف این رد
       trace_not_found: رد یافت نشد!
index 193ae8c68c871c0f4b864a6de78e315bfcc90a38..4a17b3af17c6515785d41ef613d1ceb5130947a6 100644 (file)
@@ -2792,4 +2792,9 @@ fr:
         appartenant à ce masquage avant de le supprimer.
       flash: Masquage supprimé.
       error: Une erreur est survenue lors de la suppression de ce masquage.
+  validations:
+    leading_whitespace: a des espaces au début
+    trailing_whitespace: a des espaces à la fin
+    invalid_characters: contient des caractères non valides
+    url_characters: contient des caractères d’URL spéciaux (%{characters})
 ...
index 4dc589c1e642f21ce4f7a9255e7523b182574f68..6497880709d9817eb0c32e0e8c23dd054cb5a171 100644 (file)
@@ -27,6 +27,7 @@
 # Author: Tacsipacsi
 # Author: Uno20001
 # Author: Urbalazs
+# Author: Zizzerus
 ---
 hu:
   time:
@@ -2535,4 +2536,6 @@ hu:
         mielőtt törlöd ezt a módosítást.
       flash: Módosítás törölve.
       error: Hiba történt a művelet végrehajtása során.
+  validations:
+    invalid_characters: érvénytelen karaktereket tartalmaz
 ...
index 2fa9107ea74a6dfe1e01d11522b8dd59a0527e4f..3d5f50e919fc5a88d11bc8e1654995f3d7b626d6 100644 (file)
@@ -1883,6 +1883,7 @@ it:
         other: File GPX con %{count} punti da %{user}
       description_without_count: File GPX da %{user}
   application:
+    permission_denied: Non disponi dei permessi necessari per eseguire questa azione
     require_cookies:
       cookies_needed: Pare che tu abbia i cookie non abilitati - abilita i cookie
         nel tuo browser prima di continuare.
@@ -2731,4 +2732,7 @@ it:
         appartenenti a questa revisione prima di eliminarla.
       flash: Revisione eliminata.
       error: Si è verificato un errore durante l'eliminazione.
+  validations:
+    invalid_characters: contiene caratteri non validi
+    url_characters: contiene caratteri URL speciali (%{characters})
 ...
index 9ed3f177a266baeab8015630c6226d5c2fea9ece..2308a17f40a2bd2b95e01bbe82f712f4704e1308 100644 (file)
@@ -2580,4 +2580,7 @@ ko:
       not_empty: 교정이 비어 있지 않습니다. 파기하기 전에 이 교정에 속하는 모든 판을 교정 취소하세요.
       flash: 교정을 파기했습니다.
       error: 이 교정을 파기하는 중에 오류가 발생했습니다.
+  validations:
+    invalid_characters: 유효하지 않은 문자가 포함됨
+    url_characters: 특정 URL 문자 포함 (%{characters})
 ...
index d459f11f577c9f89eb2ac80c53df6301dcbae6c7..009ad478182782abdc0d8d1c56f6255a13c72be2 100644 (file)
@@ -2692,4 +2692,9 @@ mk:
         на оваа редакција пред да ја поништите.
       flash: Редакцијата е поништена.
       error: Се појави грешка при поништувањето на редакцијата.
+  validations:
+    leading_whitespace: има почетна белина
+    trailing_whitespace: има завршна белина
+    invalid_characters: содржи неважечки знаци
+    url_characters: содржи посебни знаци во URL-то (%{characters})
 ...
index 91282eddeb362c2c720b3598c72f1737d02cb21d..c1f97515992b4730767007b68b58b0f68497b571 100644 (file)
@@ -576,6 +576,9 @@ mo:
   site:
     export:
       title: Експортаре
+  traces:
+    edit:
+      save_button: Апликаря модификэрилор
   users:
     login:
       title: Презентаци-вэ
@@ -650,10 +653,20 @@ mo:
       openid:
         link text: че май есте ши аста?
       public editing:
+        heading: 'Редактаря публикэ:'
         enabled link text: че май есте ши аста?
       contributor terms:
         link text: че май есте ши аста?
+      profile description: 'Дескриеря профилулуй:'
+      preferred languages: 'Лимбиле преферате:'
       preferred editor: 'Редактор преферат:'
+      image: 'Имаӂине:'
       gravatar:
+        gravatar: Фолосиря Граватарулуй
         link text: че май есте ши аста?
+      new image: Адэугаря имаӂиний
+      home location: 'Локул де решединцэ:'
+      latitude: 'Латитудине:'
+      longitude: 'Лонӂитудине:'
+      save changes button: Апликаря модификэрилор
 ...
index 28b3d7f598b9a7710f8a98f9efbaefebdda82b4e..0e997fafb199c0f3060b94ec05e6c7a4f7b69faf 100644 (file)
@@ -523,6 +523,7 @@ nl:
           "yes": Ambachtswinkel
         emergency:
           ambulance_station: Ambulancepost
+          assembly_point: Verzamelplaats
           defibrillator: Defibrillator
           landing_site: Noodlandingsbaan
           phone: Noodtelefoon
@@ -887,6 +888,7 @@ nl:
           stationery: Kantoorartikelenwinkel
           supermarket: Supermarkt
           tailor: Kleermaker
+          ticket: Ticketwinkel
           tobacco: Tabakswinkel
           toys: Speelgoedwinkel
           travel_agency: Reisbureau
@@ -1808,6 +1810,7 @@ nl:
       map: kaart
     index:
       public_traces: Openbare GPS-traces
+      my_traces: Mijn GPS-tracks
       public_traces_from: Openbare GPS-traces van %{user}
       description: Recente GPS-trackuploads bekijken
       tagged_with: ' gelabeld met %{tags}'
@@ -1815,6 +1818,7 @@ nl:
         trace</a> of kom meer te weten over GPS tracen op de <a href='https://wiki.openstreetmap.org/wiki/Beginners_Guide_1.2'>wikipagina</a>.
       upload_trace: Trace uploaden
       see_all_traces: Alle traces bekijken
+      see_my_traces: Weergeef mijn tracks
     delete:
       scheduled_for_deletion: Trace staat op de lijst voor verwijdering
     make_public:
@@ -2635,4 +2639,7 @@ nl:
         betrokken zijn voordat u die vernietigt.
       flash: De redigering is vernietigd.
       error: Er is een fout opgetreden tijdens het verwijderen van de redigering.
+  validations:
+    invalid_characters: bevat ongeldige karakters
+    url_characters: bevat speciale URL karakters (%{characters})
 ...
index ca3969dfce9598bee05a1dc52e54f23951a832ea..f8d690a64c972031bfe878f611bb01afbf34176c 100644 (file)
@@ -2744,4 +2744,9 @@ pt-BR:
         a esta anulação antes de destruí-la.
       flash: Redação destruída.
       error: Houve um erro ao destruir esta anulação.
+  validations:
+    leading_whitespace: tem espaço em branco líder
+    trailing_whitespace: tem espaço em branco à direita
+    invalid_characters: contém caracteres inválidos
+    url_characters: contém caracteres de URL especiais (%{characters})
 ...
index 96127154586850e348b899996c1ab5dc41ea2dc4..63a7ec070607949667af8c3f172cc30d236095dd 100644 (file)
@@ -2734,4 +2734,9 @@ pt-PT:
         as versões pertencentes a esta supressão antes de a eliminar
       flash: Supressão eliminada.
       error: Ocorreu um erro ao tentar eliminar esta supressão.
+  validations:
+    leading_whitespace: tem espaços no início
+    trailing_whitespace: tem espaços no fim
+    invalid_characters: contém caracteres inválidos
+    url_characters: contém caracteres especiais dos URL (%{characters})
 ...
index 8fe3d372e3d0d859db5120f98a4d04dbdb0e53d9..02e3a6d1056a1b9ec7abfd02a09abcc31e74bd6a 100644 (file)
@@ -37,6 +37,7 @@
 # Author: Irus
 # Author: Kaganer
 # Author: Komzpa
+# Author: Link2xt
 # Author: Lockal
 # Author: Macofe
 # Author: Mavl
@@ -1908,6 +1909,7 @@ ru:
         other: GPX-файл с %{count} точками от %{user}
       description_without_count: GPX-файл от %{user}
   application:
+    permission_denied: У вас нет прав для выполнения этого действия
     require_cookies:
       cookies_needed: Похоже, что у вас выключены куки. Пожалуйста, включите куки
         в вашем браузере, прежде чем продолжить.
@@ -2771,4 +2773,7 @@ ru:
         принадлежащих к этому исправлению перед удалением.
       flash: Исправление уничтожено.
       error: Произошла ошибка при уничтожении этого исправления.
+  validations:
+    invalid_characters: содержит недопустимые символы
+    url_characters: содержит специальные символы в URL (%{characters})
 ...
index 555cc6ff033f9f8ea9251162930ffd6e48bdca62..6d107bd5c12a2107cd86a3f068d4ecfc9080c8ff 100644 (file)
@@ -1900,6 +1900,7 @@ tr:
         other: '%{user} tarafından %{count} noktalı GPX dosyası'
       description_without_count: '%{user} tarafından GPX dosyası'
   application:
+    permission_denied: Bu eyleme erişme izniniz yok
     require_cookies:
       cookies_needed: Çerezleri devre dışı bırakmış görünüyorsunuz - devam etmeden
         önce lütfen tarayıcınızda çerezleri etkinleştirin.
@@ -2684,6 +2685,9 @@ tr:
         against_oneway_without_exit: '%{name}X üzerinde tek yönlü git'
         end_oneway_without_exit: '%{name} için tek yönün sonu'
         roundabout_with_exit: Dönel kavşakta %{exit}. çıkışı kullanarak %{name} üzerine
+        roundabout_with_exit_ordinal: Dönel kavşakta %{exit} çıkışı kullanarak %{name}
+          üzerine
+        exit_roundabout: '%{name} giden kavşaktan çıkın'
         unnamed: adsız yol
         courtesy: Yolculuğun izniyle %{link}x
         exit_counts:
@@ -2744,4 +2748,7 @@ tr:
         sürümlerini tekrar düzenleyin.
       flash: Redaksiyon kaldırıldı.
       error: Bu redaksiyon kaldırılırken bir hata oluştu.
+  validations:
+    invalid_characters: geçersiz karakterler içeriyor
+    url_characters: özel URL karakterleri içerir (%{characters})
 ...
index 6dfe3523cc27a2457c87b595b9ae5776eefd35ca..349817a90ae5f6eeeb14856edd95a19ed045c2f9 100644 (file)
@@ -2488,4 +2488,9 @@ zh-TW:
       not_empty: 修訂尚未清空。請在銷毀前清除所有此修訂的版本。
       flash: 修訂已銷毀。
       error: 銷毀此修訂時發生錯誤。
+  validations:
+    leading_whitespace: 前頭有空白
+    trailing_whitespace: 後端有空白
+    invalid_characters: 包含無效字元
+    url_characters: 包含特定 URL 字元(%{characters})
 ...
index 7d9c8dbec9f5778d7b61ff602b9275b62baf281c..78146606429787f6ec7fd78c74a628ce7b9f0341 100644 (file)
@@ -16,42 +16,42 @@ OpenStreetMap::Application.routes.draw do
     put "changeset/:id" => "changeset#update", :id => /\d+/
     put "changeset/:id/close" => "changeset#close", :id => /\d+/
     get "changesets" => "changeset#query"
-    post "changeset/:id/comment" => "changeset#comment", :as => :changeset_comment, :id => /\d+/
-    post "changeset/comment/:id/hide" => "changeset#hide_comment", :as => :changeset_comment_hide, :id => /\d+/
-    post "changeset/comment/:id/unhide" => "changeset#unhide_comment", :as => :changeset_comment_unhide, :id => /\d+/
-
-    put "node/create" => "node#create"
-    get "node/:id/ways" => "way#ways_for_node", :id => /\d+/
-    get "node/:id/relations" => "relation#relations_for_node", :id => /\d+/
-    get "node/:id/history" => "old_node#history", :id => /\d+/
-    post "node/:id/:version/redact" => "old_node#redact", :version => /\d+/, :id => /\d+/
-    get "node/:id/:version" => "old_node#version", :id => /\d+/, :version => /\d+/
-    get "node/:id" => "node#read", :id => /\d+/
-    put "node/:id" => "node#update", :id => /\d+/
-    delete "node/:id" => "node#delete", :id => /\d+/
-    get "nodes" => "node#nodes"
-
-    put "way/create" => "way#create"
-    get "way/:id/history" => "old_way#history", :id => /\d+/
-    get "way/:id/full" => "way#full", :id => /\d+/
-    get "way/:id/relations" => "relation#relations_for_way", :id => /\d+/
-    post "way/:id/:version/redact" => "old_way#redact", :version => /\d+/, :id => /\d+/
-    get "way/:id/:version" => "old_way#version", :id => /\d+/, :version => /\d+/
-    get "way/:id" => "way#read", :id => /\d+/
-    put "way/:id" => "way#update", :id => /\d+/
-    delete "way/:id" => "way#delete", :id => /\d+/
-    get "ways" => "way#ways"
-
-    put "relation/create" => "relation#create"
-    get "relation/:id/relations" => "relation#relations_for_relation", :id => /\d+/
-    get "relation/:id/history" => "old_relation#history", :id => /\d+/
-    get "relation/:id/full" => "relation#full", :id => /\d+/
-    post "relation/:id/:version/redact" => "old_relation#redact", :version => /\d+/, :id => /\d+/
-    get "relation/:id/:version" => "old_relation#version", :id => /\d+/, :version => /\d+/
-    get "relation/:id" => "relation#read", :id => /\d+/
-    put "relation/:id" => "relation#update", :id => /\d+/
-    delete "relation/:id" => "relation#delete", :id => /\d+/
-    get "relations" => "relation#relations"
+    post "changeset/:id/comment" => "changeset_comments#create", :as => :changeset_comment, :id => /\d+/
+    post "changeset/comment/:id/hide" => "changeset_comments#destroy", :as => :changeset_comment_hide, :id => /\d+/
+    post "changeset/comment/:id/unhide" => "changeset_comments#restore", :as => :changeset_comment_unhide, :id => /\d+/
+
+    put "node/create" => "nodes#create"
+    get "node/:id/ways" => "ways#ways_for_node", :id => /\d+/
+    get "node/:id/relations" => "relations#relations_for_node", :id => /\d+/
+    get "node/:id/history" => "old_nodes#history", :id => /\d+/
+    post "node/:id/:version/redact" => "old_nodes#redact", :version => /\d+/, :id => /\d+/
+    get "node/:id/:version" => "old_nodes#version", :id => /\d+/, :version => /\d+/
+    get "node/:id" => "nodes#read", :id => /\d+/
+    put "node/:id" => "nodes#update", :id => /\d+/
+    delete "node/:id" => "nodes#delete", :id => /\d+/
+    get "nodes" => "nodes#nodes"
+
+    put "way/create" => "ways#create"
+    get "way/:id/history" => "old_ways#history", :id => /\d+/
+    get "way/:id/full" => "ways#full", :id => /\d+/
+    get "way/:id/relations" => "relations#relations_for_way", :id => /\d+/
+    post "way/:id/:version/redact" => "old_ways#redact", :version => /\d+/, :id => /\d+/
+    get "way/:id/:version" => "old_ways#version", :id => /\d+/, :version => /\d+/
+    get "way/:id" => "ways#read", :id => /\d+/
+    put "way/:id" => "ways#update", :id => /\d+/
+    delete "way/:id" => "ways#delete", :id => /\d+/
+    get "ways" => "ways#ways"
+
+    put "relation/create" => "relations#create"
+    get "relation/:id/relations" => "relations#relations_for_relation", :id => /\d+/
+    get "relation/:id/history" => "old_relations#history", :id => /\d+/
+    get "relation/:id/full" => "relations#full", :id => /\d+/
+    post "relation/:id/:version/redact" => "old_relations#redact", :version => /\d+/, :id => /\d+/
+    get "relation/:id/:version" => "old_relations#version", :id => /\d+/, :version => /\d+/
+    get "relation/:id" => "relations#read", :id => /\d+/
+    put "relation/:id" => "relations#update", :id => /\d+/
+    delete "relation/:id" => "relations#delete", :id => /\d+/
+    get "relations" => "relations#relations"
 
     get "map" => "api#map"
 
@@ -116,7 +116,7 @@ OpenStreetMap::Application.routes.draw do
   get "/relation/:id" => "browse#relation", :id => /\d+/, :as => :relation
   get "/relation/:id/history" => "browse#relation_history", :id => /\d+/
   get "/changeset/:id" => "browse#changeset", :as => :changeset, :id => /\d+/
-  get "/changeset/:id/comments/feed" => "changeset#comments_feed", :as => :changeset_comments_feed, :id => /\d*/, :defaults => { :format => "rss" }
+  get "/changeset/:id/comments/feed" => "changeset_comments#index", :as => :changeset_comments_feed, :id => /\d*/, :defaults => { :format => "rss" }
   get "/note/:id" => "browse#note", :id => /\d+/, :as => "browse_note"
   get "/note/new" => "browse#new_note"
   get "/user/:display_name/history" => "changeset#index"
@@ -152,7 +152,7 @@ OpenStreetMap::Application.routes.draw do
   get "/about" => "site#about"
   get "/history" => "changeset#index"
   get "/history/feed" => "changeset#feed", :defaults => { :format => :atom }
-  get "/history/comments/feed" => "changeset#comments_feed", :as => :changesets_comments_feed, :defaults => { :format => "rss" }
+  get "/history/comments/feed" => "changeset_comments#index", :as => :changesets_comments_feed, :defaults => { :format => "rss" }
   get "/export" => "site#export"
   match "/login" => "users#login", :via => [:get, :post]
   match "/logout" => "users#logout", :via => [:get, :post]
@@ -214,24 +214,24 @@ OpenStreetMap::Application.routes.draw do
   post "/trace/:id/delete" => "traces#delete", :id => /\d+/
 
   # diary pages
-  match "/diary/new" => "diary_entry#new", :via => [:get, :post]
-  get "/diary/friends" => "diary_entry#index", :friends => true, :as => "friend_diaries"
-  get "/diary/nearby" => "diary_entry#index", :nearby => true, :as => "nearby_diaries"
-  get "/user/:display_name/diary/rss" => "diary_entry#rss", :defaults => { :format => :rss }
-  get "/diary/:language/rss" => "diary_entry#rss", :defaults => { :format => :rss }
-  get "/diary/rss" => "diary_entry#rss", :defaults => { :format => :rss }
-  get "/user/:display_name/diary/comments/:page" => "diary_entry#comments", :page => /[1-9][0-9]*/
-  get "/user/:display_name/diary/comments/" => "diary_entry#comments"
-  get "/user/:display_name/diary" => "diary_entry#index"
-  get "/diary/:language" => "diary_entry#index"
-  get "/diary" => "diary_entry#index"
-  get "/user/:display_name/diary/:id" => "diary_entry#show", :id => /\d+/, :as => :diary_entry
-  post "/user/:display_name/diary/:id/newcomment" => "diary_entry#comment", :id => /\d+/
-  match "/user/:display_name/diary/:id/edit" => "diary_entry#edit", :via => [:get, :post], :id => /\d+/
-  post "/user/:display_name/diary/:id/hide" => "diary_entry#hide", :id => /\d+/, :as => :hide_diary_entry
-  post "/user/:display_name/diary/:id/hidecomment/:comment" => "diary_entry#hidecomment", :id => /\d+/, :comment => /\d+/, :as => :hide_diary_comment
-  post "/user/:display_name/diary/:id/subscribe" => "diary_entry#subscribe", :as => :diary_entry_subscribe, :id => /\d+/
-  post "/user/:display_name/diary/:id/unsubscribe" => "diary_entry#unsubscribe", :as => :diary_entry_unsubscribe, :id => /\d+/
+  match "/diary/new" => "diary_entries#new", :via => [:get, :post]
+  get "/diary/friends" => "diary_entries#index", :friends => true, :as => "friend_diaries"
+  get "/diary/nearby" => "diary_entries#index", :nearby => true, :as => "nearby_diaries"
+  get "/user/:display_name/diary/rss" => "diary_entries#rss", :defaults => { :format => :rss }
+  get "/diary/:language/rss" => "diary_entries#rss", :defaults => { :format => :rss }
+  get "/diary/rss" => "diary_entries#rss", :defaults => { :format => :rss }
+  get "/user/:display_name/diary/comments/:page" => "diary_entries#comments", :page => /[1-9][0-9]*/
+  get "/user/:display_name/diary/comments/" => "diary_entries#comments"
+  get "/user/:display_name/diary" => "diary_entries#index"
+  get "/diary/:language" => "diary_entries#index"
+  get "/diary" => "diary_entries#index"
+  get "/user/:display_name/diary/:id" => "diary_entries#show", :id => /\d+/, :as => :diary_entry
+  post "/user/:display_name/diary/:id/newcomment" => "diary_entries#comment", :id => /\d+/
+  match "/user/:display_name/diary/:id/edit" => "diary_entries#edit", :via => [:get, :post], :id => /\d+/
+  post "/user/:display_name/diary/:id/hide" => "diary_entries#hide", :id => /\d+/, :as => :hide_diary_entry
+  post "/user/:display_name/diary/:id/hidecomment/:comment" => "diary_entries#hidecomment", :id => /\d+/, :comment => /\d+/, :as => :hide_diary_comment
+  post "/user/:display_name/diary/:id/subscribe" => "diary_entries#subscribe", :as => :diary_entry_subscribe, :id => /\d+/
+  post "/user/:display_name/diary/:id/unsubscribe" => "diary_entries#unsubscribe", :as => :diary_entry_unsubscribe, :id => /\d+/
 
   # user pages
   get "/user/:display_name" => "users#show", :as => "user"
index 11d850ac35f67edfab51a043b96b9970005cccd5..cdc20a1aad0d0de4cfea0796e1b904ca7329550b 100644 (file)
@@ -1,5 +1,4 @@
 require "test_helper"
-require "api_controller"
 
 class ApiControllerTest < ActionController::TestCase
   def setup
index d6bde97d6add65bdcbaa9dc90088875f1a625640..7cb55b0eccd87cd584585b248a743af73d5268e9 100644 (file)
@@ -1,5 +1,4 @@
 require "test_helper"
-require "browse_controller"
 
 class BrowseControllerTest < ActionController::TestCase
   ##
diff --git a/test/controllers/changeset_comments_controller_test.rb b/test/controllers/changeset_comments_controller_test.rb
new file mode 100644 (file)
index 0000000..10dfb1f
--- /dev/null
@@ -0,0 +1,251 @@
+require "test_helper"
+
+class ChangesetCommentsControllerTest < ActionController::TestCase
+  ##
+  # test all routes which lead to this controller
+  def test_routes
+    assert_routing(
+      { :path => "/api/0.6/changeset/1/comment", :method => :post },
+      { :controller => "changeset_comments", :action => "create", :id => "1" }
+    )
+    assert_routing(
+      { :path => "/api/0.6/changeset/comment/1/hide", :method => :post },
+      { :controller => "changeset_comments", :action => "destroy", :id => "1" }
+    )
+    assert_routing(
+      { :path => "/api/0.6/changeset/comment/1/unhide", :method => :post },
+      { :controller => "changeset_comments", :action => "restore", :id => "1" }
+    )
+    assert_routing(
+      { :path => "/changeset/1/comments/feed", :method => :get },
+      { :controller => "changeset_comments", :action => "index", :id => "1", :format => "rss" }
+    )
+    assert_routing(
+      { :path => "/history/comments/feed", :method => :get },
+      { :controller => "changeset_comments", :action => "index", :format => "rss" }
+    )
+  end
+
+  ##
+  # create comment success
+  def test_create_comment_success
+    user = create(:user)
+    user2 = create(:user)
+    private_user = create(:user, :data_public => false)
+    suspended_user = create(:user, :suspended)
+    deleted_user = create(:user, :deleted)
+    private_user_closed_changeset = create(:changeset, :closed, :user => private_user)
+
+    basic_authorization user.email, "test"
+
+    assert_difference "ChangesetComment.count", 1 do
+      assert_no_difference "ActionMailer::Base.deliveries.size" do
+        perform_enqueued_jobs do
+          post :create, :params => { :id => private_user_closed_changeset.id, :text => "This is a comment" }
+        end
+      end
+    end
+    assert_response :success
+
+    changeset = create(:changeset, :closed, :user => private_user)
+    changeset.subscribers.push(private_user)
+    changeset.subscribers.push(user)
+    changeset.subscribers.push(suspended_user)
+    changeset.subscribers.push(deleted_user)
+
+    assert_difference "ChangesetComment.count", 1 do
+      assert_difference "ActionMailer::Base.deliveries.size", 1 do
+        perform_enqueued_jobs do
+          post :create, :params => { :id => changeset.id, :text => "This is a comment" }
+        end
+      end
+    end
+    assert_response :success
+
+    email = ActionMailer::Base.deliveries.first
+    assert_equal 1, email.to.length
+    assert_equal "[OpenStreetMap] #{user.display_name} has commented on one of your changesets", email.subject
+    assert_equal private_user.email, email.to.first
+
+    ActionMailer::Base.deliveries.clear
+
+    basic_authorization user2.email, "test"
+
+    assert_difference "ChangesetComment.count", 1 do
+      assert_difference "ActionMailer::Base.deliveries.size", 2 do
+        perform_enqueued_jobs do
+          post :create, :params => { :id => changeset.id, :text => "This is a comment" }
+        end
+      end
+    end
+    assert_response :success
+
+    email = ActionMailer::Base.deliveries.find { |e| e.to.first == private_user.email }
+    assert_not_nil email
+    assert_equal 1, email.to.length
+    assert_equal "[OpenStreetMap] #{user2.display_name} has commented on one of your changesets", email.subject
+
+    email = ActionMailer::Base.deliveries.find { |e| e.to.first == user.email }
+    assert_not_nil email
+    assert_equal 1, email.to.length
+    assert_equal "[OpenStreetMap] #{user2.display_name} has commented on a changeset you are interested in", email.subject
+
+    ActionMailer::Base.deliveries.clear
+  end
+
+  ##
+  # create comment fail
+  def test_create_comment_fail
+    # unauthorized
+    post :create, :params => { :id => create(:changeset, :closed).id, :text => "This is a comment" }
+    assert_response :unauthorized
+
+    basic_authorization create(:user).email, "test"
+
+    # bad changeset id
+    assert_no_difference "ChangesetComment.count" do
+      post :create, :params => { :id => 999111, :text => "This is a comment" }
+    end
+    assert_response :not_found
+
+    # not closed changeset
+    assert_no_difference "ChangesetComment.count" do
+      post :create, :params => { :id => create(:changeset).id, :text => "This is a comment" }
+    end
+    assert_response :conflict
+
+    # no text
+    assert_no_difference "ChangesetComment.count" do
+      post :create, :params => { :id => create(:changeset, :closed).id }
+    end
+    assert_response :bad_request
+
+    # empty text
+    assert_no_difference "ChangesetComment.count" do
+      post :create, :params => { :id => create(:changeset, :closed).id, :text => "" }
+    end
+    assert_response :bad_request
+  end
+
+  ##
+  # test hide comment fail
+  def test_destroy_comment_fail
+    # unauthorized
+    comment = create(:changeset_comment)
+    assert_equal true, comment.visible
+
+    post :destroy, :params => { :id => comment.id }
+    assert_response :unauthorized
+    assert_equal true, comment.reload.visible
+
+    basic_authorization create(:user).email, "test"
+
+    # not a moderator
+    post :destroy, :params => { :id => comment.id }
+    assert_response :forbidden
+    assert_equal true, comment.reload.visible
+
+    basic_authorization create(:moderator_user).email, "test"
+
+    # bad comment id
+    post :destroy, :params => { :id => 999111 }
+    assert_response :not_found
+    assert_equal true, comment.reload.visible
+  end
+
+  ##
+  # test hide comment succes
+  def test_hide_comment_success
+    comment = create(:changeset_comment)
+    assert_equal true, comment.visible
+
+    basic_authorization create(:moderator_user).email, "test"
+
+    post :destroy, :params => { :id => comment.id }
+    assert_response :success
+    assert_equal false, comment.reload.visible
+  end
+
+  ##
+  # test unhide comment fail
+  def test_restore_comment_fail
+    # unauthorized
+    comment = create(:changeset_comment, :visible => false)
+    assert_equal false, comment.visible
+
+    post :restore, :params => { :id => comment.id }
+    assert_response :unauthorized
+    assert_equal false, comment.reload.visible
+
+    basic_authorization create(:user).email, "test"
+
+    # not a moderator
+    post :restore, :params => { :id => comment.id }
+    assert_response :forbidden
+    assert_equal false, comment.reload.visible
+
+    basic_authorization create(:moderator_user).email, "test"
+
+    # bad comment id
+    post :restore, :params => { :id => 999111 }
+    assert_response :not_found
+    assert_equal false, comment.reload.visible
+  end
+
+  ##
+  # test unhide comment succes
+  def test_unhide_comment_success
+    comment = create(:changeset_comment, :visible => false)
+    assert_equal false, comment.visible
+
+    basic_authorization create(:moderator_user).email, "test"
+
+    post :restore, :params => { :id => comment.id }
+    assert_response :success
+    assert_equal true, comment.reload.visible
+  end
+
+  ##
+  # test comments feed
+  def test_feed
+    changeset = create(:changeset, :closed)
+    create_list(:changeset_comment, 3, :changeset => changeset)
+
+    get :index, :params => { :format => "rss" }
+    assert_response :success
+    assert_equal "application/rss+xml", @response.content_type
+    assert_select "rss", :count => 1 do
+      assert_select "channel", :count => 1 do
+        assert_select "item", :count => 3
+      end
+    end
+
+    get :index, :params => { :format => "rss", :limit => 2 }
+    assert_response :success
+    assert_equal "application/rss+xml", @response.content_type
+    assert_select "rss", :count => 1 do
+      assert_select "channel", :count => 1 do
+        assert_select "item", :count => 2
+      end
+    end
+
+    get :index, :params => { :id => changeset.id, :format => "rss" }
+    assert_response :success
+    assert_equal "application/rss+xml", @response.content_type
+    assert_select "rss", :count => 1 do
+      assert_select "channel", :count => 1 do
+        assert_select "item", :count => 3
+      end
+    end
+  end
+
+  ##
+  # test comments feed
+  def test_feed_bad_limit
+    get :index, :params => { :format => "rss", :limit => 0 }
+    assert_response :bad_request
+
+    get :index, :params => { :format => "rss", :limit => 100001 }
+    assert_response :bad_request
+  end
+end
index fdb689978f7fc1cebbc9dad700d81457204af10b..7dc479cad825a96965d1a17ff5b50fc726b03a7e 100644 (file)
@@ -41,26 +41,10 @@ class ChangesetControllerTest < ActionController::TestCase
       { :path => "/api/0.6/changeset/1/close", :method => :put },
       { :controller => "changeset", :action => "close", :id => "1" }
     )
-    assert_routing(
-      { :path => "/api/0.6/changeset/1/comment", :method => :post },
-      { :controller => "changeset", :action => "comment", :id => "1" }
-    )
-    assert_routing(
-      { :path => "/api/0.6/changeset/comment/1/hide", :method => :post },
-      { :controller => "changeset", :action => "hide_comment", :id => "1" }
-    )
-    assert_routing(
-      { :path => "/api/0.6/changeset/comment/1/unhide", :method => :post },
-      { :controller => "changeset", :action => "unhide_comment", :id => "1" }
-    )
     assert_routing(
       { :path => "/api/0.6/changesets", :method => :get },
       { :controller => "changeset", :action => "query" }
     )
-    assert_routing(
-      { :path => "/changeset/1/comments/feed", :method => :get },
-      { :controller => "changeset", :action => "comments_feed", :id => "1", :format => "rss" }
-    )
     assert_routing(
       { :path => "/user/name/history", :method => :get },
       { :controller => "changeset", :action => "index", :display_name => "name" }
@@ -85,10 +69,6 @@ class ChangesetControllerTest < ActionController::TestCase
       { :path => "/history/feed", :method => :get },
       { :controller => "changeset", :action => "feed", :format => :atom }
     )
-    assert_routing(
-      { :path => "/history/comments/feed", :method => :get },
-      { :controller => "changeset", :action => "comments_feed", :format => "rss" }
-    )
   end
 
   # -----------------------
@@ -1528,7 +1508,7 @@ CHANGESET
     changeset_id = @response.body.to_i
 
     # add a single node to it
-    with_controller(NodeController.new) do
+    with_controller(NodesController.new) do
       content "<osm><node lon='1' lat='2' changeset='#{changeset_id}'/></osm>"
       put :create
       assert_response :success, "Couldn't create node."
@@ -1543,7 +1523,7 @@ CHANGESET
     assert_select "osm>changeset[max_lat='2.0000000']", 1
 
     # add another node to it
-    with_controller(NodeController.new) do
+    with_controller(NodesController.new) do
       content "<osm><node lon='2' lat='1' changeset='#{changeset_id}'/></osm>"
       put :create
       assert_response :success, "Couldn't create second node."
@@ -1558,7 +1538,7 @@ CHANGESET
     assert_select "osm>changeset[max_lat='2.0000000']", 1
 
     # add (delete) a way to it, which contains a point at (3,3)
-    with_controller(WayController.new) do
+    with_controller(WaysController.new) do
       content update_changeset(way.to_xml, changeset_id)
       put :delete, :params => { :id => way.id }
       assert_response :success, "Couldn't delete a way."
@@ -1838,7 +1818,7 @@ CHANGESET
     changeset.num_changes = Changeset::MAX_ELEMENTS - offset
     changeset.save!
 
-    with_controller(NodeController.new) do
+    with_controller(NodesController.new) do
       # create a new node
       content "<osm><node changeset='#{cs_id}' lat='0.0' lon='0.0'/></osm>"
       put :create
@@ -2139,107 +2119,6 @@ CHANGESET
     assert_select "osmChange node[id='#{node.id}'][version='1']", 0
   end
 
-  ##
-  # create comment success
-  def test_create_comment_success
-    user = create(:user)
-    user2 = create(:user)
-    private_user = create(:user, :data_public => false)
-    suspended_user = create(:user, :suspended)
-    deleted_user = create(:user, :deleted)
-    private_user_closed_changeset = create(:changeset, :closed, :user => private_user)
-
-    basic_authorization user.email, "test"
-
-    assert_difference "ChangesetComment.count", 1 do
-      assert_no_difference "ActionMailer::Base.deliveries.size" do
-        perform_enqueued_jobs do
-          post :comment, :params => { :id => private_user_closed_changeset.id, :text => "This is a comment" }
-        end
-      end
-    end
-    assert_response :success
-
-    changeset = create(:changeset, :closed, :user => private_user)
-    changeset.subscribers.push(private_user)
-    changeset.subscribers.push(user)
-    changeset.subscribers.push(suspended_user)
-    changeset.subscribers.push(deleted_user)
-
-    assert_difference "ChangesetComment.count", 1 do
-      assert_difference "ActionMailer::Base.deliveries.size", 1 do
-        perform_enqueued_jobs do
-          post :comment, :params => { :id => changeset.id, :text => "This is a comment" }
-        end
-      end
-    end
-    assert_response :success
-
-    email = ActionMailer::Base.deliveries.first
-    assert_equal 1, email.to.length
-    assert_equal "[OpenStreetMap] #{user.display_name} has commented on one of your changesets", email.subject
-    assert_equal private_user.email, email.to.first
-
-    ActionMailer::Base.deliveries.clear
-
-    basic_authorization user2.email, "test"
-
-    assert_difference "ChangesetComment.count", 1 do
-      assert_difference "ActionMailer::Base.deliveries.size", 2 do
-        perform_enqueued_jobs do
-          post :comment, :params => { :id => changeset.id, :text => "This is a comment" }
-        end
-      end
-    end
-    assert_response :success
-
-    email = ActionMailer::Base.deliveries.find { |e| e.to.first == private_user.email }
-    assert_not_nil email
-    assert_equal 1, email.to.length
-    assert_equal "[OpenStreetMap] #{user2.display_name} has commented on one of your changesets", email.subject
-
-    email = ActionMailer::Base.deliveries.find { |e| e.to.first == user.email }
-    assert_not_nil email
-    assert_equal 1, email.to.length
-    assert_equal "[OpenStreetMap] #{user2.display_name} has commented on a changeset you are interested in", email.subject
-
-    ActionMailer::Base.deliveries.clear
-  end
-
-  ##
-  # create comment fail
-  def test_create_comment_fail
-    # unauthorized
-    post :comment, :params => { :id => create(:changeset, :closed).id, :text => "This is a comment" }
-    assert_response :unauthorized
-
-    basic_authorization create(:user).email, "test"
-
-    # bad changeset id
-    assert_no_difference "ChangesetComment.count" do
-      post :comment, :params => { :id => 999111, :text => "This is a comment" }
-    end
-    assert_response :not_found
-
-    # not closed changeset
-    assert_no_difference "ChangesetComment.count" do
-      post :comment, :params => { :id => create(:changeset).id, :text => "This is a comment" }
-    end
-    assert_response :conflict
-
-    # no text
-    assert_no_difference "ChangesetComment.count" do
-      post :comment, :params => { :id => create(:changeset, :closed).id }
-    end
-    assert_response :bad_request
-
-    # empty text
-    assert_no_difference "ChangesetComment.count" do
-      post :comment, :params => { :id => create(:changeset, :closed).id, :text => "" }
-    end
-    assert_response :bad_request
-  end
-
   ##
   # test subscribe success
   def test_subscribe_success
@@ -2337,128 +2216,6 @@ CHANGESET
     assert_response :not_found
   end
 
-  ##
-  # test hide comment fail
-  def test_hide_comment_fail
-    # unauthorized
-    comment = create(:changeset_comment)
-    assert_equal true, comment.visible
-
-    post :hide_comment, :params => { :id => comment.id }
-    assert_response :unauthorized
-    assert_equal true, comment.reload.visible
-
-    basic_authorization create(:user).email, "test"
-
-    # not a moderator
-    post :hide_comment, :params => { :id => comment.id }
-    assert_response :forbidden
-    assert_equal true, comment.reload.visible
-
-    basic_authorization create(:moderator_user).email, "test"
-
-    # bad comment id
-    post :hide_comment, :params => { :id => 999111 }
-    assert_response :not_found
-    assert_equal true, comment.reload.visible
-  end
-
-  ##
-  # test hide comment succes
-  def test_hide_comment_success
-    comment = create(:changeset_comment)
-    assert_equal true, comment.visible
-
-    basic_authorization create(:moderator_user).email, "test"
-
-    post :hide_comment, :params => { :id => comment.id }
-    assert_response :success
-    assert_equal false, comment.reload.visible
-  end
-
-  ##
-  # test unhide comment fail
-  def test_unhide_comment_fail
-    # unauthorized
-    comment = create(:changeset_comment, :visible => false)
-    assert_equal false, comment.visible
-
-    post :unhide_comment, :params => { :id => comment.id }
-    assert_response :unauthorized
-    assert_equal false, comment.reload.visible
-
-    basic_authorization create(:user).email, "test"
-
-    # not a moderator
-    post :unhide_comment, :params => { :id => comment.id }
-    assert_response :forbidden
-    assert_equal false, comment.reload.visible
-
-    basic_authorization create(:moderator_user).email, "test"
-
-    # bad comment id
-    post :unhide_comment, :params => { :id => 999111 }
-    assert_response :not_found
-    assert_equal false, comment.reload.visible
-  end
-
-  ##
-  # test unhide comment succes
-  def test_unhide_comment_success
-    comment = create(:changeset_comment, :visible => false)
-    assert_equal false, comment.visible
-
-    basic_authorization create(:moderator_user).email, "test"
-
-    post :unhide_comment, :params => { :id => comment.id }
-    assert_response :success
-    assert_equal true, comment.reload.visible
-  end
-
-  ##
-  # test comments feed
-  def test_comments_feed
-    changeset = create(:changeset, :closed)
-    create_list(:changeset_comment, 3, :changeset => changeset)
-
-    get :comments_feed, :params => { :format => "rss" }
-    assert_response :success
-    assert_equal "application/rss+xml", @response.content_type
-    assert_select "rss", :count => 1 do
-      assert_select "channel", :count => 1 do
-        assert_select "item", :count => 3
-      end
-    end
-
-    get :comments_feed, :params => { :format => "rss", :limit => 2 }
-    assert_response :success
-    assert_equal "application/rss+xml", @response.content_type
-    assert_select "rss", :count => 1 do
-      assert_select "channel", :count => 1 do
-        assert_select "item", :count => 2
-      end
-    end
-
-    get :comments_feed, :params => { :id => changeset.id, :format => "rss" }
-    assert_response :success
-    assert_equal "application/rss+xml", @response.content_type
-    assert_select "rss", :count => 1 do
-      assert_select "channel", :count => 1 do
-        assert_select "item", :count => 3
-      end
-    end
-  end
-
-  ##
-  # test comments feed
-  def test_comments_feed_bad_limit
-    get :comments_feed, :params => { :format => "rss", :limit => 0 }
-    assert_response :bad_request
-
-    get :comments_feed, :params => { :format => "rss", :limit => 100001 }
-    assert_response :bad_request
-  end
-
   private
 
   ##
similarity index 94%
rename from test/controllers/diary_entry_controller_test.rb
rename to test/controllers/diary_entries_controller_test.rb
index cec2250476fe17e8c89668f79f90314544261032..426bc3851619c35d89e8d48b5acd1901aa75438e 100644 (file)
@@ -1,6 +1,6 @@
 require "test_helper"
 
-class DiaryEntryControllerTest < ActionController::TestCase
+class DiaryEntriesControllerTest < ActionController::TestCase
   include ActionView::Helpers::NumberHelper
 
   def setup
@@ -16,86 +16,86 @@ class DiaryEntryControllerTest < ActionController::TestCase
   def test_routes
     assert_routing(
       { :path => "/diary", :method => :get },
-      { :controller => "diary_entry", :action => "index" }
+      { :controller => "diary_entries", :action => "index" }
     )
     assert_routing(
       { :path => "/diary/language", :method => :get },
-      { :controller => "diary_entry", :action => "index", :language => "language" }
+      { :controller => "diary_entries", :action => "index", :language => "language" }
     )
     assert_routing(
       { :path => "/user/username/diary", :method => :get },
-      { :controller => "diary_entry", :action => "index", :display_name => "username" }
+      { :controller => "diary_entries", :action => "index", :display_name => "username" }
     )
     assert_routing(
       { :path => "/diary/friends", :method => :get },
-      { :controller => "diary_entry", :action => "index", :friends => true }
+      { :controller => "diary_entries", :action => "index", :friends => true }
     )
     assert_routing(
       { :path => "/diary/nearby", :method => :get },
-      { :controller => "diary_entry", :action => "index", :nearby => true }
+      { :controller => "diary_entries", :action => "index", :nearby => true }
     )
 
     assert_routing(
       { :path => "/diary/rss", :method => :get },
-      { :controller => "diary_entry", :action => "rss", :format => :rss }
+      { :controller => "diary_entries", :action => "rss", :format => :rss }
     )
     assert_routing(
       { :path => "/diary/language/rss", :method => :get },
-      { :controller => "diary_entry", :action => "rss", :language => "language", :format => :rss }
+      { :controller => "diary_entries", :action => "rss", :language => "language", :format => :rss }
     )
     assert_routing(
       { :path => "/user/username/diary/rss", :method => :get },
-      { :controller => "diary_entry", :action => "rss", :display_name => "username", :format => :rss }
+      { :controller => "diary_entries", :action => "rss", :display_name => "username", :format => :rss }
     )
 
     assert_routing(
       { :path => "/user/username/diary/comments", :method => :get },
-      { :controller => "diary_entry", :action => "comments", :display_name => "username" }
+      { :controller => "diary_entries", :action => "comments", :display_name => "username" }
     )
     assert_routing(
       { :path => "/user/username/diary/comments/1", :method => :get },
-      { :controller => "diary_entry", :action => "comments", :display_name => "username", :page => "1" }
+      { :controller => "diary_entries", :action => "comments", :display_name => "username", :page => "1" }
     )
 
     assert_routing(
       { :path => "/diary/new", :method => :get },
-      { :controller => "diary_entry", :action => "new" }
+      { :controller => "diary_entries", :action => "new" }
     )
     assert_routing(
       { :path => "/diary/new", :method => :post },
-      { :controller => "diary_entry", :action => "new" }
+      { :controller => "diary_entries", :action => "new" }
     )
     assert_routing(
       { :path => "/user/username/diary/1", :method => :get },
-      { :controller => "diary_entry", :action => "show", :display_name => "username", :id => "1" }
+      { :controller => "diary_entries", :action => "show", :display_name => "username", :id => "1" }
     )
     assert_routing(
       { :path => "/user/username/diary/1/edit", :method => :get },
-      { :controller => "diary_entry", :action => "edit", :display_name => "username", :id => "1" }
+      { :controller => "diary_entries", :action => "edit", :display_name => "username", :id => "1" }
     )
     assert_routing(
       { :path => "/user/username/diary/1/edit", :method => :post },
-      { :controller => "diary_entry", :action => "edit", :display_name => "username", :id => "1" }
+      { :controller => "diary_entries", :action => "edit", :display_name => "username", :id => "1" }
     )
     assert_routing(
       { :path => "/user/username/diary/1/newcomment", :method => :post },
-      { :controller => "diary_entry", :action => "comment", :display_name => "username", :id => "1" }
+      { :controller => "diary_entries", :action => "comment", :display_name => "username", :id => "1" }
     )
     assert_routing(
       { :path => "/user/username/diary/1/hide", :method => :post },
-      { :controller => "diary_entry", :action => "hide", :display_name => "username", :id => "1" }
+      { :controller => "diary_entries", :action => "hide", :display_name => "username", :id => "1" }
     )
     assert_routing(
       { :path => "/user/username/diary/1/hidecomment/2", :method => :post },
-      { :controller => "diary_entry", :action => "hidecomment", :display_name => "username", :id => "1", :comment => "2" }
+      { :controller => "diary_entries", :action => "hidecomment", :display_name => "username", :id => "1", :comment => "2" }
     )
     assert_routing(
       { :path => "/user/username/diary/1/subscribe", :method => :post },
-      { :controller => "diary_entry", :action => "subscribe", :display_name => "username", :id => "1" }
+      { :controller => "diary_entries", :action => "subscribe", :display_name => "username", :id => "1" }
     )
     assert_routing(
       { :path => "/user/username/diary/1/unsubscribe", :method => :post },
-      { :controller => "diary_entry", :action => "unsubscribe", :display_name => "username", :id => "1" }
+      { :controller => "diary_entries", :action => "unsubscribe", :display_name => "username", :id => "1" }
     )
   end
 
@@ -316,7 +316,7 @@ class DiaryEntryControllerTest < ActionController::TestCase
         :params => { :display_name => entry.user.display_name, :id => entry.id },
         :session => { :user => entry.user }
     assert_response :success
-    assert_template "diary_entry/show"
+    assert_template "show"
     assert_select "title", :text => /Users' diaries | /, :count => 1
     assert_select "div.content-heading", :count => 1 do
       assert_select "h2", :text => /#{entry.user.display_name}'s diary/, :count => 1
@@ -337,7 +337,7 @@ class DiaryEntryControllerTest < ActionController::TestCase
         :params => { :display_name => entry.user.display_name, :id => entry.id },
         :session => { :user => create(:user) }
     assert_response :success
-    assert_template "diary_entry/show"
+    assert_template "show"
     assert_select "title", :text => /Users' diaries | /, :count => 1
     assert_select "div.content-heading", :count => 1 do
       assert_select "h2", :text => /#{entry.user.display_name}'s diary/, :count => 1
index 3f6e25ea6ae0c16a9e59d70f4e756b85f6b2f56b..1a14351824129c64d56eee1785927d78eca6e813 100644 (file)
@@ -1,5 +1,4 @@
 require "test_helper"
-require "geocoder_controller"
 
 class GeocoderControllerTest < ActionController::TestCase
   ##
similarity index 98%
rename from test/controllers/node_controller_test.rb
rename to test/controllers/nodes_controller_test.rb
index 5f737f798a57c26a0a102739bfe62a013baa2ed7..3cd4244e14e828d6d743712c76f32779b78a401c 100644 (file)
@@ -1,28 +1,28 @@
 require "test_helper"
 
-class NodeControllerTest < ActionController::TestCase
+class NodesControllerTest < ActionController::TestCase
   ##
   # test all routes which lead to this controller
   def test_routes
     assert_routing(
       { :path => "/api/0.6/node/create", :method => :put },
-      { :controller => "node", :action => "create" }
+      { :controller => "nodes", :action => "create" }
     )
     assert_routing(
       { :path => "/api/0.6/node/1", :method => :get },
-      { :controller => "node", :action => "read", :id => "1" }
+      { :controller => "nodes", :action => "read", :id => "1" }
     )
     assert_routing(
       { :path => "/api/0.6/node/1", :method => :put },
-      { :controller => "node", :action => "update", :id => "1" }
+      { :controller => "nodes", :action => "update", :id => "1" }
     )
     assert_routing(
       { :path => "/api/0.6/node/1", :method => :delete },
-      { :controller => "node", :action => "delete", :id => "1" }
+      { :controller => "nodes", :action => "delete", :id => "1" }
     )
     assert_routing(
       { :path => "/api/0.6/nodes", :method => :get },
-      { :controller => "node", :action => "nodes" }
+      { :controller => "nodes", :action => "nodes" }
     )
   end
 
similarity index 96%
rename from test/controllers/old_node_controller_test.rb
rename to test/controllers/old_nodes_controller_test.rb
index 346634f7d42d8b4f458b1f183567d58f9a3ca2ac..2568cbfd831e3e3c02af56f0299dce3ab50e993d 100644 (file)
@@ -1,7 +1,6 @@
 require "test_helper"
-require "old_node_controller"
 
-class OldNodeControllerTest < ActionController::TestCase
+class OldNodesControllerTest < ActionController::TestCase
   #
   # TODO: test history
   #
@@ -11,15 +10,15 @@ class OldNodeControllerTest < ActionController::TestCase
   def test_routes
     assert_routing(
       { :path => "/api/0.6/node/1/history", :method => :get },
-      { :controller => "old_node", :action => "history", :id => "1" }
+      { :controller => "old_nodes", :action => "history", :id => "1" }
     )
     assert_routing(
       { :path => "/api/0.6/node/1/2", :method => :get },
-      { :controller => "old_node", :action => "version", :id => "1", :version => "2" }
+      { :controller => "old_nodes", :action => "version", :id => "1", :version => "2" }
     )
     assert_routing(
       { :path => "/api/0.6/node/1/2/redact", :method => :post },
-      { :controller => "old_node", :action => "redact", :id => "1", :version => "2" }
+      { :controller => "old_nodes", :action => "redact", :id => "1", :version => "2" }
     )
   end
 
@@ -59,7 +58,7 @@ class OldNodeControllerTest < ActionController::TestCase
       # move the node somewhere else
       xml_node["lat"] = precision(rand * 180 - 90).to_s
       xml_node["lon"] = precision(rand * 360 - 180).to_s
-      with_controller(NodeController.new) do
+      with_controller(NodesController.new) do
         content xml_doc
         put :update, :params => { :id => nodeid }
         assert_response :forbidden, "Should have rejected node update"
@@ -75,7 +74,7 @@ class OldNodeControllerTest < ActionController::TestCase
       xml_tag["k"] = random_string
       xml_tag["v"] = random_string
       xml_node << xml_tag
-      with_controller(NodeController.new) do
+      with_controller(NodesController.new) do
         content xml_doc
         put :update, :params => { :id => nodeid }
         assert_response :forbidden,
@@ -109,7 +108,7 @@ class OldNodeControllerTest < ActionController::TestCase
       # move the node somewhere else
       xml_node["lat"] = precision(rand * 180 - 90).to_s
       xml_node["lon"] = precision(rand * 360 - 180).to_s
-      with_controller(NodeController.new) do
+      with_controller(NodesController.new) do
         content xml_doc
         put :update, :params => { :id => nodeid }
         assert_response :success
@@ -125,7 +124,7 @@ class OldNodeControllerTest < ActionController::TestCase
       xml_tag["k"] = random_string
       xml_tag["v"] = random_string
       xml_node << xml_tag
-      with_controller(NodeController.new) do
+      with_controller(NodesController.new) do
         content xml_doc
         put :update, :params => { :id => nodeid }
         assert_response :success,
@@ -390,7 +389,7 @@ class OldNodeControllerTest < ActionController::TestCase
 
   def check_current_version(node_id)
     # get the current version of the node
-    current_node = with_controller(NodeController.new) do
+    current_node = with_controller(NodesController.new) do
       get :read, :params => { :id => node_id }
       assert_response :success, "cant get current node #{node_id}"
       Node.from_xml(@response.body)
similarity index 97%
rename from test/controllers/old_relation_controller_test.rb
rename to test/controllers/old_relations_controller_test.rb
index be91962f8fff776af17f1a1049503eeb9d5bc32d..51e6c565a315d936a50e0684610517cab1d7b834 100644 (file)
@@ -1,21 +1,20 @@
 require "test_helper"
-require "old_relation_controller"
 
-class OldRelationControllerTest < ActionController::TestCase
+class OldRelationsControllerTest < ActionController::TestCase
   ##
   # test all routes which lead to this controller
   def test_routes
     assert_routing(
       { :path => "/api/0.6/relation/1/history", :method => :get },
-      { :controller => "old_relation", :action => "history", :id => "1" }
+      { :controller => "old_relations", :action => "history", :id => "1" }
     )
     assert_routing(
       { :path => "/api/0.6/relation/1/2", :method => :get },
-      { :controller => "old_relation", :action => "version", :id => "1", :version => "2" }
+      { :controller => "old_relations", :action => "version", :id => "1", :version => "2" }
     )
     assert_routing(
       { :path => "/api/0.6/relation/1/2/redact", :method => :post },
-      { :controller => "old_relation", :action => "redact", :id => "1", :version => "2" }
+      { :controller => "old_relations", :action => "redact", :id => "1", :version => "2" }
     )
   end
 
@@ -225,7 +224,7 @@ class OldRelationControllerTest < ActionController::TestCase
   # version which we're getting from the versions call.
   def check_current_version(relation_id)
     # get the current version
-    current_relation = with_controller(RelationController.new) do
+    current_relation = with_controller(RelationsController.new) do
       get :read, :params => { :id => relation_id }
       assert_response :success, "can't get current relation #{relation_id}"
       Relation.from_xml(@response.body)
similarity index 97%
rename from test/controllers/old_way_controller_test.rb
rename to test/controllers/old_ways_controller_test.rb
index 1fff791877764d777990a205d56afb4dccf0f431..0dd2d5e3c743ed20422d4dc771da137917e16671 100644 (file)
@@ -1,21 +1,20 @@
 require "test_helper"
-require "old_way_controller"
 
-class OldWayControllerTest < ActionController::TestCase
+class OldWaysControllerTest < ActionController::TestCase
   ##
   # test all routes which lead to this controller
   def test_routes
     assert_routing(
       { :path => "/api/0.6/way/1/history", :method => :get },
-      { :controller => "old_way", :action => "history", :id => "1" }
+      { :controller => "old_ways", :action => "history", :id => "1" }
     )
     assert_routing(
       { :path => "/api/0.6/way/1/2", :method => :get },
-      { :controller => "old_way", :action => "version", :id => "1", :version => "2" }
+      { :controller => "old_ways", :action => "version", :id => "1", :version => "2" }
     )
     assert_routing(
       { :path => "/api/0.6/way/1/2/redact", :method => :post },
-      { :controller => "old_way", :action => "redact", :id => "1", :version => "2" }
+      { :controller => "old_ways", :action => "redact", :id => "1", :version => "2" }
     )
   end
 
@@ -265,7 +264,7 @@ class OldWayControllerTest < ActionController::TestCase
   # version which we're getting from the versions call.
   def check_current_version(way_id)
     # get the current version
-    current_way = with_controller(WayController.new) do
+    current_way = with_controller(WaysController.new) do
       get :read, :params => { :id => way_id }
       assert_response :success, "can't get current way #{way_id}"
       Way.from_xml(@response.body)
index 08f32d4d0cea97b1ee4f28eb2f6eaef347d478e7..fa56814b27e8403c6d90c9071bbde90de105490d 100644 (file)
@@ -1,5 +1,4 @@
 require "test_helper"
-require "redactions_controller"
 
 class RedactionsControllerTest < ActionController::TestCase
   ##
similarity index 97%
rename from test/controllers/relation_controller_test.rb
rename to test/controllers/relations_controller_test.rb
index 8a7e8b2fe2b6bcf212c804e19ace3df7475e8efd..1613fbf7a8cb924b8241d0c3ee67f065a38af94b 100644 (file)
@@ -1,46 +1,45 @@
 require "test_helper"
-require "relation_controller"
 
-class RelationControllerTest < ActionController::TestCase
+class RelationsControllerTest < ActionController::TestCase
   ##
   # test all routes which lead to this controller
   def test_routes
     assert_routing(
       { :path => "/api/0.6/relation/create", :method => :put },
-      { :controller => "relation", :action => "create" }
+      { :controller => "relations", :action => "create" }
     )
     assert_routing(
       { :path => "/api/0.6/relation/1/full", :method => :get },
-      { :controller => "relation", :action => "full", :id => "1" }
+      { :controller => "relations", :action => "full", :id => "1" }
     )
     assert_routing(
       { :path => "/api/0.6/relation/1", :method => :get },
-      { :controller => "relation", :action => "read", :id => "1" }
+      { :controller => "relations", :action => "read", :id => "1" }
     )
     assert_routing(
       { :path => "/api/0.6/relation/1", :method => :put },
-      { :controller => "relation", :action => "update", :id => "1" }
+      { :controller => "relations", :action => "update", :id => "1" }
     )
     assert_routing(
       { :path => "/api/0.6/relation/1", :method => :delete },
-      { :controller => "relation", :action => "delete", :id => "1" }
+      { :controller => "relations", :action => "delete", :id => "1" }
     )
     assert_routing(
       { :path => "/api/0.6/relations", :method => :get },
-      { :controller => "relation", :action => "relations" }
+      { :controller => "relations", :action => "relations" }
     )
 
     assert_routing(
       { :path => "/api/0.6/node/1/relations", :method => :get },
-      { :controller => "relation", :action => "relations_for_node", :id => "1" }
+      { :controller => "relations", :action => "relations_for_node", :id => "1" }
     )
     assert_routing(
       { :path => "/api/0.6/way/1/relations", :method => :get },
-      { :controller => "relation", :action => "relations_for_way", :id => "1" }
+      { :controller => "relations", :action => "relations_for_way", :id => "1" }
     )
     assert_routing(
       { :path => "/api/0.6/relation/1/relations", :method => :get },
-      { :controller => "relation", :action => "relations_for_relation", :id => "1" }
+      { :controller => "relations", :action => "relations_for_relation", :id => "1" }
     )
   end
 
@@ -785,7 +784,7 @@ OSM
     check_ordering(doc, @response.body)
 
     # check the ordering in the history tables:
-    with_controller(OldRelationController.new) do
+    with_controller(OldRelationsController.new) do
       get :version, :params => { :id => relation_id, :version => 2 }
       assert_response :success, "can't read back version 2 of the relation #{relation_id}"
       check_ordering(doc, @response.body)
@@ -868,7 +867,7 @@ OSM
     check_ordering(doc, @response.body)
 
     # check the ordering in the history tables:
-    with_controller(OldRelationController.new) do
+    with_controller(OldRelationsController.new) do
       get :version, :params => { :id => relation_id, :version => 1 }
       assert_response :success, "can't read back version 1 of the relation: #{@response.body}"
       check_ordering(doc, @response.body)
@@ -982,7 +981,7 @@ OSM
     if ver.nil?
       get :read, :params => { :id => id }
     else
-      with_controller(OldRelationController.new) do
+      with_controller(OldRelationsController.new) do
         get :version, :params => { :id => id, :version => ver }
       end
     end
similarity index 98%
rename from test/controllers/way_controller_test.rb
rename to test/controllers/ways_controller_test.rb
index 3d466de8bbfca3893c9182173b7255c8f1f81e8b..1199e5d941b94ed290a39d985e2157ff93ed9eae 100644 (file)
@@ -1,33 +1,32 @@
 require "test_helper"
-require "way_controller"
 
-class WayControllerTest < ActionController::TestCase
+class WaysControllerTest < ActionController::TestCase
   ##
   # test all routes which lead to this controller
   def test_routes
     assert_routing(
       { :path => "/api/0.6/way/create", :method => :put },
-      { :controller => "way", :action => "create" }
+      { :controller => "ways", :action => "create" }
     )
     assert_routing(
       { :path => "/api/0.6/way/1/full", :method => :get },
-      { :controller => "way", :action => "full", :id => "1" }
+      { :controller => "ways", :action => "full", :id => "1" }
     )
     assert_routing(
       { :path => "/api/0.6/way/1", :method => :get },
-      { :controller => "way", :action => "read", :id => "1" }
+      { :controller => "ways", :action => "read", :id => "1" }
     )
     assert_routing(
       { :path => "/api/0.6/way/1", :method => :put },
-      { :controller => "way", :action => "update", :id => "1" }
+      { :controller => "ways", :action => "update", :id => "1" }
     )
     assert_routing(
       { :path => "/api/0.6/way/1", :method => :delete },
-      { :controller => "way", :action => "delete", :id => "1" }
+      { :controller => "ways", :action => "delete", :id => "1" }
     )
     assert_routing(
       { :path => "/api/0.6/ways", :method => :get },
-      { :controller => "way", :action => "ways" }
+      { :controller => "ways", :action => "ways" }
     )
   end
 
index 89e5a38937c221bc32db5d2710b18bfe65d6185e..050fa0e9f169597b5a73581b17b35cc957d12f1e 100644 (file)
@@ -38,7 +38,7 @@ class ApplicationHelperTest < ActionView::TestCase
   end
 
   def test_rss_link_to
-    link = rss_link_to(:controller => :diary_entry, :action => :rss)
+    link = rss_link_to(:controller => :diary_entries, :action => :rss)
     assert_dom_equal "<a class=\"rsssmall\" href=\"/diary/rss\"><img border=\"0\" height=\"16\" src=\"/images/RSS.png\" width=\"16\" /></a>", link
   end
 
index 57b4a8b0c97d3bb68604ef3d498cc4355f459713..026028d5f23d83e44073a2a814966c4160ef9ec7 100644 (file)
@@ -29,7 +29,7 @@ class UserDiariesTest < ActionDispatch::IntegrationTest
     follow_redirect!
 
     assert_response :success
-    assert_template "diary_entry/edit"
+    assert_template "diary_entries/edit"
     # print @response.body
     # print @html_document.to_yaml
 
index 4196dea154d242cd675150748907f0f3c9786c30..fb232b81b4396ef4bc3f6ae0aef27f10980d34f9 100644 (file)
@@ -1,5 +1,4 @@
 require "test_helper"
-require "osm"
 
 class RedactionTest < ActiveSupport::TestCase
   def test_cannot_redact_current
index 18be7e649103743a2ffa540b3e72d6db6e573455..61879a32f0b3961ecd1ad7d69df9614e6d311539 100644 (file)
@@ -11,7 +11,7 @@ class ReportDiaryCommentTest < ApplicationSystemTestCase
     visit diary_entry_path(@diary_entry.user.display_name, @diary_entry)
     assert page.has_content?(@comment.body)
 
-    assert_not page.has_content?(I18n.t("diary_entry.diary_comment.report"))
+    assert_not page.has_content?(I18n.t("diary_entries.diary_comment.report"))
   end
 
   def test_it_works
@@ -19,7 +19,7 @@ class ReportDiaryCommentTest < ApplicationSystemTestCase
     visit diary_entry_path(@diary_entry.user.display_name, @diary_entry)
     assert page.has_content? @diary_entry.title
 
-    click_on I18n.t("diary_entry.diary_comment.report")
+    click_on I18n.t("diary_entries.diary_comment.report")
     assert page.has_content? "Report"
     assert page.has_content? I18n.t("reports.new.disclaimer.intro")
 
index 1db733ab7ca510e0bc38a63ed86efcca5349696a..9d232f8d465f2797a8a5917c603ec7248dc22251 100644 (file)
@@ -10,7 +10,7 @@ class ReportDiaryEntryTest < ApplicationSystemTestCase
     visit diary_entry_path(@diary_entry.user.display_name, @diary_entry)
     assert page.has_content?(@diary_entry.title)
 
-    assert_not page.has_content?(I18n.t("diary_entry.diary_entry.report"))
+    assert_not page.has_content?(I18n.t("diary_entries.diary_entry.report"))
   end
 
   def test_it_works
@@ -18,7 +18,7 @@ class ReportDiaryEntryTest < ApplicationSystemTestCase
     visit diary_entry_path(@diary_entry.user.display_name, @diary_entry)
     assert page.has_content? @diary_entry.title
 
-    click_on I18n.t("diary_entry.diary_entry.report")
+    click_on I18n.t("diary_entries.diary_entry.report")
     assert page.has_content? "Report"
     assert page.has_content? I18n.t("reports.new.disclaimer.intro")
 
@@ -42,7 +42,7 @@ class ReportDiaryEntryTest < ApplicationSystemTestCase
     visit diary_entry_path(@diary_entry.user.display_name, @diary_entry)
     assert page.has_content? @diary_entry.title
 
-    click_on I18n.t("diary_entry.diary_entry.report")
+    click_on I18n.t("diary_entries.diary_entry.report")
     assert page.has_content? "Report"
     assert page.has_content? I18n.t("reports.new.disclaimer.intro")
 
index 8544e17a04cd5867f3cbe046679648483bdb0a56..a7e4730b5ab58747c464e22d00973f72346941b2 100644 (file)
@@ -36,6 +36,112 @@ You can find the project at: https://github.com/domoritz/leaflet-locatecontrol
     var addClasses = function(el, names) { LDomUtilApplyClassesMethod('addClass', el, names); };
     var removeClasses = function(el, names) { LDomUtilApplyClassesMethod('removeClass', el, names); };
 
+    /**
+     * Compatible with L.Circle but a true marker instead of a path
+     */
+    var LocationMarker = L.Marker.extend({
+        initialize: function (latlng, options) {
+            L.Util.setOptions(this, options);
+            this._latlng = latlng;
+            this.createIcon();
+        },
+
+        /**
+         * Create a styled circle location marker
+         */
+        createIcon: function() {
+            var opt = this.options;
+
+            var style = '';
+
+            if (opt.color !== undefined) {
+                style += 'stroke:'+opt.color+';';
+            }
+            if (opt.weight !== undefined) {
+                style += 'stroke-width:'+opt.weight+';';
+            }
+            if (opt.fillColor !== undefined) {
+                style += 'fill:'+opt.fillColor+';';
+            }
+            if (opt.fillOpacity !== undefined) {
+                style += 'fill-opacity:'+opt.fillOpacity+';';
+            }
+            if (opt.opacity !== undefined) {
+                style += 'opacity:'+opt.opacity+';';
+            }
+
+            var icon = this._getIconSVG(opt, style);
+
+            this._locationIcon = L.divIcon({
+                className: icon.className,
+                html: icon.svg,
+                iconSize: [icon.w,icon.h],
+            });
+
+            this.setIcon(this._locationIcon);
+        },
+
+        /**
+         * Return the raw svg for the shape
+         *
+         * Split so can be easily overridden
+         */
+        _getIconSVG: function(options, style) {
+            var r = options.radius;
+            var w = options.weight;
+            var s = r + w;
+            var s2 = s * 2;
+            var svg = '<svg xmlns="http://www.w3.org/2000/svg" width="'+s2+'" height="'+s2+'" version="1.1" viewBox="-'+s+' -'+s+' '+s2+' '+s2+'">' +
+            '<circle r="'+r+'" style="'+style+'" />' +
+            '</svg>';
+            return {
+                className: 'leafet-control-locate-location',
+                svg: svg,
+                w: s2,
+                h: s2
+            };
+        },
+
+        setStyle: function(style) {
+            L.Util.setOptions(this, style);
+            this.createIcon();
+        }
+    });
+
+    var CompassMarker = LocationMarker.extend({
+        initialize: function (latlng, heading, options) {
+            L.Util.setOptions(this, options);
+            this._latlng = latlng;
+            this._heading = heading;
+            this.createIcon();
+        },
+
+        setHeading: function(heading) {
+            this._heading = heading;
+        },
+
+        /**
+         * Create a styled arrow compass marker
+         */
+        _getIconSVG: function(options, style) {
+            var r = options.radius;
+            var w = (options.width + options.weight);
+            var h = (r+options.depth + options.weight)*2;
+            var path = 'M0,0 l'+(options.width/2)+','+options.depth+' l-'+(w)+',0 z';
+            var svgstyle = 'transform: rotate('+this._heading+'deg)';
+            var svg = '<svg xmlns="http://www.w3.org/2000/svg" width="'+(w)+'" height="'+h+'" version="1.1" viewBox="-'+(w/2)+' 0 '+w+' '+h+'" style="'+svgstyle+'">'+
+            '<path d="'+path+'" style="'+style+'" />'+
+            '</svg>';
+            return {
+                className: 'leafet-control-locate-heading',
+                svg: svg,
+                w: w,
+                h: h
+            };
+        },
+    });
+
+
     var LocateControl = L.Control.extend({
         options: {
             /** Position of the control */
@@ -51,12 +157,15 @@ You can find the project at: https://github.com/domoritz/leaflet-locatecontrol
              *  - false: never updates the map view when location changes.
              *  - 'once': set the view when the location is first determined
              *  - 'always': always updates the map view when location changes.
-             *              The map view follows the users location.
-             *  - 'untilPan': (default) like 'always', except stops updating the
+             *              The map view follows the user's location.
+             *  - 'untilPan': like 'always', except stops updating the
+             *                view if the user has manually panned the map.
+             *                The map view follows the user's location until she pans.
+             *  - 'untilPanOrZoom': (default) like 'always', except stops updating the
              *                view if the user has manually panned the map.
-             *                The map view follows the users location until she pans.
+             *                The map view follows the user's location until she pans.
              */
-            setView: 'untilPan',
+            setView: 'untilPanOrZoom',
             /** Keep the current map zoom level when setting the view and only pan. */
             keepCurrentZoomLevel: false,
             /** Smooth pan and zoom to the location of the marker. Only works in Leaflet 1.0+. */
@@ -89,24 +198,40 @@ You can find the project at: https://github.com/domoritz/leaflet-locatecontrol
             drawCircle: true,
             /** If set, the marker at the users' location is drawn. */
             drawMarker: true,
+            /** If set and supported then show the compass heading */
+            showCompass: true,
             /** The class to be used to create the marker. For example L.CircleMarker or L.Marker */
-            markerClass: L.CircleMarker,
-            /** Accuracy circle style properties. */
+            markerClass: LocationMarker,
+            /** The class us be used to create the compass bearing arrow */
+            compassClass: CompassMarker,
+            /** Accuracy circle style properties. NOTE these styles should match the css animations styles */
             circleStyle: {
-                color: '#136AEC',
-                fillColor: '#136AEC',
+                className:   'leaflet-control-locate-circle',
+                color:       '#136AEC',
+                fillColor:   '#136AEC',
                 fillOpacity: 0.15,
-                weight: 2,
-                opacity: 0.5
+                weight:      0
             },
             /** Inner marker style properties. Only works if your marker class supports `setStyle`. */
             markerStyle: {
-                color: '#136AEC',
-                fillColor: '#2A93EE',
-                fillOpacity: 0.7,
-                weight: 2,
-                opacity: 0.9,
-                radius: 5
+                className:   'leaflet-control-locate-marker',
+                color:       '#fff',
+                fillColor:   '#2A93EE',
+                fillOpacity: 1,
+                weight:      3,
+                opacity:     1,
+                radius:      9
+            },
+            /** Compass */
+            compassStyle: {
+                fillColor:   '#2A93EE',
+                fillOpacity: 1,
+                weight:      0,
+                color:       '#fff',
+                opacity:     1,
+                radius:      9, // How far is the arrow is from the center of of the marker
+                width:       9, // Width of the arrow
+                depth:       6  // Length of the arrow
             },
             /**
              * Changes to accuracy circle and inner marker while following.
@@ -117,6 +242,7 @@ You can find the project at: https://github.com/domoritz/leaflet-locatecontrol
                 // color: '#FFA500',
                 // fillColor: '#FFB000'
             },
+            followCompassStyle: {},
             /** The CSS class for the icon. For example fa-location-arrow or fa-map-marker */
             icon: 'fa fa-map-marker',
             iconLoading: 'fa fa-spinner fa-spin',
@@ -142,7 +268,7 @@ You can find the project at: https://github.com/domoritz/leaflet-locatecontrol
                 alert(err.message);
             },
             /**
-             * This even is called when the user's location is outside the bounds set on the map.
+             * This event is called when the user's location is outside the bounds set on the map.
              * The event is called repeatedly when the location changes.
              */
             onLocationOutsideMapBounds: function(control) {
@@ -180,6 +306,7 @@ You can find the project at: https://github.com/domoritz/leaflet-locatecontrol
             // extend the follow marker style and circle from the normal style
             this.options.followMarkerStyle = L.extend({}, this.options.markerStyle, this.options.followMarkerStyle);
             this.options.followCircleStyle = L.extend({}, this.options.circleStyle, this.options.followCircleStyle);
+            this.options.followCompassStyle = L.extend({}, this.options.compassStyle, this.options.followCompassStyle);
         },
 
         /**
@@ -192,6 +319,7 @@ You can find the project at: https://github.com/domoritz/leaflet-locatecontrol
             this._layer = this.options.layer || new L.LayerGroup();
             this._layer.addTo(map);
             this._event = undefined;
+            this._compassHeading = null;
             this._prevBounds = null;
 
             var linkAndIcon = this.options.createButtonCallback(container, this.options);
@@ -217,6 +345,7 @@ You can find the project at: https://github.com/domoritz/leaflet-locatecontrol
         _onClick: function() {
             this._justClicked = true;
             this._userPanned = false;
+            this._userZoomed = false;
 
             if (this._active && !this._event) {
                 // click while requesting
@@ -298,6 +427,15 @@ You can find the project at: https://github.com/domoritz/leaflet-locatecontrol
                 this._map.on('locationfound', this._onLocationFound, this);
                 this._map.on('locationerror', this._onLocationError, this);
                 this._map.on('dragstart', this._onDrag, this);
+                this._map.on('zoomstart', this._onZoom, this);
+                this._map.on('zoomend', this._onZoomEnd, this);
+                if (this.options.showCompass) {
+                    if ('ondeviceorientationabsolute' in window) {
+                        L.DomEvent.on(window, 'deviceorientationabsolute', this._onDeviceOrientation, this);
+                    } else if ('ondeviceorientation' in window) {
+                        L.DomEvent.on(window, 'deviceorientation', this._onDeviceOrientation, this);
+                    }
+                }
             }
         },
 
@@ -318,6 +456,16 @@ You can find the project at: https://github.com/domoritz/leaflet-locatecontrol
             this._map.off('locationfound', this._onLocationFound, this);
             this._map.off('locationerror', this._onLocationError, this);
             this._map.off('dragstart', this._onDrag, this);
+            this._map.off('zoomstart', this._onZoom, this);
+            this._map.off('zoomend', this._onZoomEnd, this);
+            if (this.options.showCompass) {
+                this._compassHeading = null;
+                if ('ondeviceorientationabsolute' in window) {
+                    L.DomEvent.off(window, 'deviceorientationabsolute', this._onDeviceOrientation, this);
+                } else if ('ondeviceorientation' in window) {
+                    L.DomEvent.off(window, 'deviceorientation', this._onDeviceOrientation, this);
+                }
+            }
         },
 
         /**
@@ -342,6 +490,32 @@ You can find the project at: https://github.com/domoritz/leaflet-locatecontrol
             }
         },
 
+        /**
+         *
+         */
+        _drawCompass: function() {
+            var latlng = this._event.latlng;
+
+            if (this.options.showCompass && latlng && this._compassHeading !== null) {
+                var cStyle = this._isFollowing() ? this.options.followCompassStyle : this.options.compassStyle;
+                if (!this._compass) {
+                    this._compass = new this.options.compassClass(latlng, this._compassHeading, cStyle).addTo(this._layer);
+                } else {
+                    this._compass.setLatLng(latlng);
+                    this._compass.setHeading(this._compassHeading);
+                    // If the compassClass can be updated with setStyle, update it.
+                    if (this._compass.setStyle) {
+                        this._compass.setStyle(cStyle);
+                    }
+                }
+                // 
+            }
+            if (this._compass && (!this.options.showCompass || this._compassHeading === null)) {
+                this._compass.removeFrom(this._layer);
+                this._compass = null;
+            }
+        },
+
         /**
          * Draw the marker and accuracy circle on the map.
          *
@@ -389,12 +563,19 @@ You can find the project at: https://github.com/domoritz/leaflet-locatecontrol
                 }
             }
 
+            this._drawCompass();
+
             var t = this.options.strings.popup;
             if (this.options.showPopup && t && this._marker) {
                 this._marker
                     .bindPopup(L.Util.template(t, {distance: distance, unit: unit}))
                     ._popup.setLatLng(latlng);
             }
+            if (this.options.showPopup && t && this._compass) {
+                this._compass
+                    .bindPopup(L.Util.template(t, {distance: distance, unit: unit}))
+                    ._popup.setLatLng(latlng);
+            }
         },
 
         /**
@@ -415,6 +596,44 @@ You can find the project at: https://github.com/domoritz/leaflet-locatecontrol
             this._map.off('unload', this._unload, this);
         },
 
+        /**
+         * Sets the compass heading
+         */
+        _setCompassHeading: function(angle) {
+            if (!isNaN(parseFloat(angle)) && isFinite(angle)) {
+                angle = Math.round(angle);
+
+                this._compassHeading = angle;
+                L.Util.requestAnimFrame(this._drawCompass, this);
+            } else {
+                this._compassHeading = null;
+            }
+        },
+
+        /**
+         * If the compass fails calibration just fail safely and remove the compass
+         */
+        _onCompassNeedsCalibration: function() {
+            this._setCompassHeading();
+        },
+
+        /**
+         * Process and normalise compass events
+         */
+        _onDeviceOrientation: function(e) {
+            if (!this._active) {
+                return;
+            }
+
+            if (e.webkitCompassHeading) {
+                // iOS
+                this._setCompassHeading(e.webkitCompassHeading);
+            } else if (e.absolute && e.alpha) {
+                // Android
+                this._setCompassHeading(360 - e.alpha)
+            }
+        },
+
         /**
          * Calls deactivate and dispatches an error.
          */
@@ -461,6 +680,11 @@ You can find the project at: https://github.com/domoritz/leaflet-locatecontrol
                         this.setView();
                     }
                     break;
+                case 'untilPanOrZoom':
+                    if (!this._userPanned && !this._userZoomed) {
+                        this.setView();
+                    }
+                    break;
                 case 'always':
                     this.setView();
                     break;
@@ -473,7 +697,7 @@ You can find the project at: https://github.com/domoritz/leaflet-locatecontrol
         },
 
         /**
-         * When the user drags. Need a separate even so we can bind and unbind even listeners.
+         * When the user drags. Need a separate event so we can bind and unbind event listeners.
          */
         _onDrag: function() {
             // only react to drags once we have a location
@@ -484,6 +708,27 @@ You can find the project at: https://github.com/domoritz/leaflet-locatecontrol
             }
         },
 
+        /**
+         * When the user zooms. Need a separate event so we can bind and unbind event listeners.
+         */
+        _onZoom: function() {
+            // only react to drags once we have a location
+            if (this._event) {
+                this._userZoomed = true;
+                this._updateContainerStyle();
+                this._drawMarker();
+            }
+        },
+
+        /**
+         * After a zoom ends update the compass
+         */
+        _onZoomEnd: function() {
+            if (this._event) {
+                this._drawCompass();
+            }
+        },
+
         /**
          * Compute whether the map is following the user location with pan and zoom.
          */
@@ -496,6 +741,8 @@ You can find the project at: https://github.com/domoritz/leaflet-locatecontrol
                 return true;
             } else if (this.options.setView === 'untilPan') {
                 return !this._userPanned;
+            } else if (this.options.setView === 'untilPanOrZoom') {
+                return !this._userPanned && !this._userZoomed;
             }
         },
 
@@ -580,6 +827,9 @@ You can find the project at: https://github.com/domoritz/leaflet-locatecontrol
 
             // true if the user has panned the map after clicking the control
             this._userPanned = false;
+
+            // true if the user has zoomed the map after clicking the control
+            this._userZoomed = false;
         }
     });