From: Tom Hughes Date: Wed, 22 Jan 2025 18:11:48 +0000 (+0000) Subject: Merge remote-tracking branch 'upstream/pull/5533' X-Git-Tag: live~184 X-Git-Url: https://git.openstreetmap.org./rails.git/commitdiff_plain/e310767dcde76839c9c4fe452d5479ba531f3a65?hp=0edac40638b82a87ae1528bd89d3b81388dcbaca Merge remote-tracking branch 'upstream/pull/5533' --- diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index fa15ea90a..3d7cea500 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -106,19 +106,6 @@ Minitest/EmptyLineBeforeAssertionMethods: Minitest/MultipleAssertions: Max: 60 -# Offense count: 10 -# This cop supports unsafe autocorrection (--autocorrect-all). -Rails/ActionControllerFlashBeforeRender: - Exclude: - - 'app/controllers/application_controller.rb' - - 'app/controllers/confirmations_controller.rb' - - 'app/controllers/issue_comments_controller.rb' - - 'app/controllers/messages_controller.rb' - - 'app/controllers/passwords_controller.rb' - - 'app/controllers/traces_controller.rb' - - 'app/controllers/user_blocks_controller.rb' - - 'app/controllers/users_controller.rb' - # Offense count: 2 # Configuration parameters: Include. # Include: app/models/**/*.rb diff --git a/app/abilities/ability.rb b/app/abilities/ability.rb index 3ba2ab707..d4172bfd1 100644 --- a/app/abilities/ability.rb +++ b/app/abilities/ability.rb @@ -32,7 +32,7 @@ class Ability can :read, [:deletion, :account_terms] if Settings.status != "database_offline" - can [:subscribe, :unsubscribe], Changeset + can [:read, :create, :destroy], :changeset_subscription can [:read, :create, :update, :destroy], :oauth2_application can [:read, :destroy], :oauth2_authorized_application can [:read, :create, :destroy], :oauth2_authorization diff --git a/app/assets/javascripts/osm.js.erb b/app/assets/javascripts/osm.js.erb index e9c09c79f..3edd9b451 100644 --- a/app/assets/javascripts/osm.js.erb +++ b/app/assets/javascripts/osm.js.erb @@ -80,7 +80,7 @@ OSM = { }, mapParams: function (search) { - var params = OSM.params(search), mapParams = {}, loc, match; + var params = OSM.params(search), mapParams = {}, match; if (params.mlon && params.mlat) { mapParams.marker = true; @@ -101,6 +101,8 @@ OSM = { var hash = OSM.parseHash(location.hash); + const loc = Cookies.get('_osm_location')?.split("|"); + // Decide on a map starting position. Various ways of doing this. if (hash.center) { mapParams.lon = hash.center.lng; @@ -119,8 +121,7 @@ OSM = { mapParams.lon = parseFloat(params.mlon); mapParams.lat = parseFloat(params.mlat); mapParams.zoom = parseInt(params.zoom || 12); - } else if (loc = Cookies.get('_osm_location')) { - loc = loc.split("|"); + } else if (loc) { mapParams.lon = parseFloat(loc[0]); mapParams.lat = parseFloat(loc[1]); mapParams.zoom = parseInt(loc[2]); diff --git a/app/controllers/changeset_subscriptions_controller.rb b/app/controllers/changeset_subscriptions_controller.rb new file mode 100644 index 000000000..6e0ad5257 --- /dev/null +++ b/app/controllers/changeset_subscriptions_controller.rb @@ -0,0 +1,38 @@ +class ChangesetSubscriptionsController < ApplicationController + layout "site" + + before_action :authorize_web + before_action :set_locale + before_action :check_database_writable + + authorize_resource :class => :changeset_subscription + + around_action :web_timeout + + def show + @changeset = Changeset.find(params[:changeset_id]) + @subscribed = @changeset.subscribed?(current_user) + rescue ActiveRecord::RecordNotFound + render :action => "no_such_entry", :status => :not_found + end + + def create + @changeset = Changeset.find(params[:changeset_id]) + + @changeset.subscribe(current_user) unless @changeset.subscribed?(current_user) + + redirect_to changeset_path(@changeset) + rescue ActiveRecord::RecordNotFound + render :action => "no_such_entry", :status => :not_found + end + + def destroy + @changeset = Changeset.find(params[:changeset_id]) + + @changeset.unsubscribe(current_user) + + redirect_to changeset_path(@changeset) + rescue ActiveRecord::RecordNotFound + render :action => "no_such_entry", :status => :not_found + end +end diff --git a/app/controllers/changesets_controller.rb b/app/controllers/changesets_controller.rb index aa9d81343..d5ac49d4c 100644 --- a/app/controllers/changesets_controller.rb +++ b/app/controllers/changesets_controller.rb @@ -7,9 +7,8 @@ class ChangesetsController < ApplicationController before_action :authorize_web before_action :set_locale - before_action -> { check_database_readable(:need_api => true) }, :only => [:index, :feed, :show] + before_action -> { check_database_readable(:need_api => true) } before_action :require_oauth, :only => :show - before_action :check_database_writable, :only => [:subscribe, :unsubscribe] authorize_resource @@ -107,34 +106,6 @@ class ChangesetsController < ApplicationController render :template => "browse/not_found", :status => :not_found, :layout => map_layout end - ## - # subscribe to a changeset - def subscribe - @changeset = Changeset.find(params[:id]) - - if request.post? - @changeset.subscribe(current_user) unless @changeset.subscribed?(current_user) - - redirect_to changeset_path(@changeset) - end - rescue ActiveRecord::RecordNotFound - render :action => "no_such_entry", :status => :not_found - end - - ## - # unsubscribe from a changeset - def unsubscribe - @changeset = Changeset.find(params[:id]) - - if request.post? - @changeset.unsubscribe(current_user) - - redirect_to changeset_path(@changeset) - end - rescue ActiveRecord::RecordNotFound - render :action => "no_such_entry", :status => :not_found - end - private #------------------------------------------------------------ diff --git a/app/controllers/traces_controller.rb b/app/controllers/traces_controller.rb index 14648dc9c..075b5a864 100644 --- a/app/controllers/traces_controller.rb +++ b/app/controllers/traces_controller.rb @@ -116,7 +116,7 @@ class TracesController < ApplicationController @trace.schedule_import redirect_to :action => :index, :display_name => current_user.display_name else - flash[:error] = t(".upload_failed") if @trace.valid? + flash.now[:error] = t(".upload_failed") if @trace.valid? render :action => "new" end diff --git a/app/controllers/user_blocks_controller.rb b/app/controllers/user_blocks_controller.rb index a526f529e..ec85aef38 100644 --- a/app/controllers/user_blocks_controller.rb +++ b/app/controllers/user_blocks_controller.rb @@ -37,7 +37,7 @@ class UserBlocksController < ApplicationController end def new - @user_block = UserBlock.new + @user_block = UserBlock.new(:needs_view => true) end def edit diff --git a/app/mailers/user_mailer.rb b/app/mailers/user_mailer.rb index 609816285..e466b694a 100644 --- a/app/mailers/user_mailer.rb +++ b/app/mailers/user_mailer.rb @@ -177,7 +177,7 @@ class UserMailer < ApplicationMailer @changeset_comment = comment.changeset.tags["comment"].presence @time = comment.created_at @changeset_author = comment.changeset.user.display_name - @unsubscribe_url = unsubscribe_changeset_url(comment.changeset) + @changeset_subscription_url = changeset_subscription_url(comment.changeset) @author = @commenter subject = if @owner @@ -193,8 +193,8 @@ class UserMailer < ApplicationMailer set_list_headers( "#{comment.changeset.id}.changeset.www.openstreetmap.org", t(".description", :id => comment.changeset.id), - :subscribe => subscribe_changeset_url(comment.changeset), - :unsubscribe => @unsubscribe_url, + :subscribe => @changeset_subscription_url, + :unsubscribe => @changeset_subscription_url, :archive => @changeset_url ) diff --git a/app/views/changesets/_heading.html.erb b/app/views/changeset_subscriptions/_heading.html.erb similarity index 100% rename from app/views/changesets/_heading.html.erb rename to app/views/changeset_subscriptions/_heading.html.erb diff --git a/app/views/changeset_subscriptions/no_such_entry.html.erb b/app/views/changeset_subscriptions/no_such_entry.html.erb new file mode 100644 index 000000000..ff7d98f1a --- /dev/null +++ b/app/views/changeset_subscriptions/no_such_entry.html.erb @@ -0,0 +1,5 @@ +<% content_for :heading do %> +

<%= t ".heading", :id => h(params[:changeset_id]) %>

+<% end %> + +

<%= t ".body", :id => h(params[:changeset_id]) %>

diff --git a/app/views/changeset_subscriptions/show.html.erb b/app/views/changeset_subscriptions/show.html.erb new file mode 100644 index 000000000..e3ddb7337 --- /dev/null +++ b/app/views/changeset_subscriptions/show.html.erb @@ -0,0 +1,12 @@ +<% content_for :heading do %> +

<%= @subscribed ? t(".unsubscribe.heading") : t(".subscribe.heading") %>

+<% end %> + +<%= render :partial => "heading", :object => @changeset, :as => "changeset" %> + +<%= bootstrap_form_tag :method => (@subscribed ? :delete : :post) do |f| %> + <% if params[:referer] -%> + <%= f.hidden_field :referer, :value => params[:referer] %> + <% end -%> + <%= f.primary @subscribed ? t(".unsubscribe.button") : t(".subscribe.button") %> +<% end %> diff --git a/app/views/changesets/no_such_entry.html.erb b/app/views/changesets/no_such_entry.html.erb deleted file mode 100644 index da7d18524..000000000 --- a/app/views/changesets/no_such_entry.html.erb +++ /dev/null @@ -1,5 +0,0 @@ -<% content_for :heading do %> -

<%= t ".heading", :id => h(params[:id]) %>

-<% end %> - -

<%= t ".body", :id => h(params[:id]) %>

diff --git a/app/views/changesets/subscribe.html.erb b/app/views/changesets/subscribe.html.erb deleted file mode 100644 index 6a65e5fec..000000000 --- a/app/views/changesets/subscribe.html.erb +++ /dev/null @@ -1,12 +0,0 @@ -<% content_for :heading do %> -

<%= t ".heading" %>

-<% end %> - -<%= render :partial => "heading", :object => @changeset, :as => "changeset" %> - -<%= bootstrap_form_tag do |f| %> - <% if params[:referer] -%> - <%= f.hidden_field :referer, :value => params[:referer] %> - <% end -%> - <%= f.primary t(".button") %> -<% end %> diff --git a/app/views/changesets/unsubscribe.html.erb b/app/views/changesets/unsubscribe.html.erb deleted file mode 100644 index 6a65e5fec..000000000 --- a/app/views/changesets/unsubscribe.html.erb +++ /dev/null @@ -1,12 +0,0 @@ -<% content_for :heading do %> -

<%= t ".heading" %>

-<% end %> - -<%= render :partial => "heading", :object => @changeset, :as => "changeset" %> - -<%= bootstrap_form_tag do |f| %> - <% if params[:referer] -%> - <%= f.hidden_field :referer, :value => params[:referer] %> - <% end -%> - <%= f.primary t(".button") %> -<% end %> diff --git a/app/views/user_mailer/changeset_comment_notification.html.erb b/app/views/user_mailer/changeset_comment_notification.html.erb index efba71eb6..d0f27a143 100644 --- a/app/views/user_mailer/changeset_comment_notification.html.erb +++ b/app/views/user_mailer/changeset_comment_notification.html.erb @@ -24,6 +24,6 @@ <% content_for :footer do %>

- <%= t ".unsubscribe_html", :url => link_to(@unsubscribe_url, @unsubscribe_url) %> + <%= t ".unsubscribe_html", :url => link_to(@changeset_subscription_url, @changeset_subscription_url) %>

<% end %> diff --git a/app/views/user_mailer/changeset_comment_notification.text.erb b/app/views/user_mailer/changeset_comment_notification.text.erb index 8c0727583..91278a3c1 100644 --- a/app/views/user_mailer/changeset_comment_notification.text.erb +++ b/app/views/user_mailer/changeset_comment_notification.text.erb @@ -17,4 +17,4 @@ <%= t '.details', :url => @changeset_url %> -<%= t '.unsubscribe', :url => @unsubscribe_url %> +<%= t '.unsubscribe', :url => @changeset_subscription_url %> diff --git a/config/locales/en.yml b/config/locales/en.yml index 50c9cc754..a7125a3a7 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -484,18 +484,6 @@ en: created: "Created" closed: "Closed" belongs_to: "Author" - subscribe: - heading: Subscribe to the following changeset discussion? - button: Subscribe to discussion - unsubscribe: - heading: Unsubscribe from the following changeset discussion? - button: Unsubscribe from discussion - heading: - title: "Changeset %{id}" - created_by_html: "Created by %{link_user} on %{created}." - no_such_entry: - heading: "No entry with the id: %{id}" - body: "Sorry, there is no changeset with the id %{id}. Please check your spelling, or maybe the link you clicked is wrong." show: title: "Changeset: %{id}" created: "Created: %{when}" @@ -527,6 +515,20 @@ en: sorry: "Sorry, changeset #%{id} could not be found." timeout: sorry: "Sorry, the list of changesets you requested took too long to retrieve." + changeset_subscriptions: + show: + subscribe: + heading: Subscribe to the following changeset discussion? + button: Subscribe to discussion + unsubscribe: + heading: Unsubscribe from the following changeset discussion? + button: Unsubscribe from discussion + heading: + title: "Changeset %{id}" + created_by_html: "Created by %{link_user} on %{created}." + no_such_entry: + heading: "No entry with the id: %{id}" + body: "Sorry, there is no changeset with the id %{id}. Please check your spelling, or maybe the link you clicked is wrong." dashboards: contact: km away: "%{count}km away" diff --git a/config/routes.rb b/config/routes.rb index 242423996..dae870a07 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -124,14 +124,16 @@ OpenStreetMap::Application.routes.draw do get "/relation/:id" => "relations#show", :id => /\d+/, :as => :relation get "/relation/:id/history" => "old_relations#index", :id => /\d+/, :as => :relation_history resources :old_relations, :path => "/relation/:id/history", :id => /\d+/, :version => /\d+/, :param => :version, :only => :show - resources :changesets, :path => "changeset", :id => /\d+/, :only => :show do - match :subscribe, :on => :member, :via => [:get, :post] - match :unsubscribe, :on => :member, :via => [:get, :post] + resources :changesets, :path => "changeset", :id => /\d+/, :only => :show do + resource :subscription, :controller => :changeset_subscriptions, :only => [:show, :create, :destroy] namespace :changeset_comments, :as => :comments, :path => :comments do resource :feed, :only => :show, :defaults => { :format => "rss" } end end + get "/changeset/:id/subscribe", :id => /\d+/, :to => redirect(:path => "/changeset/%{id}/subscription") + get "/changeset/:id/unsubscribe", :id => /\d+/, :to => redirect(:path => "/changeset/%{id}/subscription") + resources :notes, :path => "note", :id => /\d+/, :only => [:show, :new] get "/user/:display_name/history" => "changesets#index" diff --git a/test/controllers/changeset_subscriptions_controller_test.rb b/test/controllers/changeset_subscriptions_controller_test.rb new file mode 100644 index 000000000..7d899ac87 --- /dev/null +++ b/test/controllers/changeset_subscriptions_controller_test.rb @@ -0,0 +1,150 @@ +require "test_helper" + +class ChangesetSubscriptionsControllerTest < ActionDispatch::IntegrationTest + ## + # test all routes which lead to this controller + def test_routes + assert_routing( + { :path => "/changeset/1/subscription", :method => :get }, + { :controller => "changeset_subscriptions", :action => "show", :changeset_id => "1" } + ) + assert_routing( + { :path => "/changeset/1/subscription", :method => :post }, + { :controller => "changeset_subscriptions", :action => "create", :changeset_id => "1" } + ) + assert_routing( + { :path => "/changeset/1/subscription", :method => :delete }, + { :controller => "changeset_subscriptions", :action => "destroy", :changeset_id => "1" } + ) + + get "/changeset/1/subscribe" + assert_redirected_to "/changeset/1/subscription" + + get "/changeset/1/unsubscribe" + assert_redirected_to "/changeset/1/subscription" + end + + def test_show_as_anonymous + changeset = create(:changeset) + + get changeset_subscription_path(changeset) + assert_redirected_to login_path(:referer => changeset_subscription_path(changeset)) + end + + def test_show_when_not_subscribed + user = create(:user) + other_user = create(:user) + changeset = create(:changeset, :user => user) + + session_for(other_user) + get changeset_subscription_path(changeset) + + assert_response :success + assert_dom ".content-body" do + assert_dom "a[href='#{changeset_path(changeset)}']", :text => "Changeset #{changeset.id}" + assert_dom "a[href='#{user_path(user)}']", :text => user.display_name + assert_dom "form" do + assert_dom "> @action", changeset_subscription_path(changeset) + assert_dom "input[type=submit]" do + assert_dom "> @value", "Subscribe to discussion" + end + end + end + end + + def test_show_when_subscribed + user = create(:user) + other_user = create(:user) + changeset = create(:changeset, :user => user) + changeset.subscribers << other_user + + session_for(other_user) + get changeset_subscription_path(changeset) + + assert_response :success + assert_dom ".content-body" do + assert_dom "a[href='#{changeset_path(changeset)}']", :text => "Changeset #{changeset.id}" + assert_dom "a[href='#{user_path(user)}']", :text => user.display_name + assert_dom "form" do + assert_dom "> @action", changeset_subscription_path(changeset) + assert_dom "input[type=submit]" do + assert_dom "> @value", "Unsubscribe from discussion" + end + end + end + end + + def test_create_success + user = create(:user) + other_user = create(:user) + changeset = create(:changeset, :user => user) + + session_for(other_user) + assert_difference "changeset.subscribers.count", 1 do + post changeset_subscription_path(changeset) + end + assert_redirected_to changeset_path(changeset) + assert changeset.reload.subscribed?(other_user) + end + + def test_create_fail + user = create(:user) + other_user = create(:user) + changeset = create(:changeset, :user => user) + changeset.subscribers << other_user + + # not signed in + assert_no_difference "changeset.subscribers.count" do + post changeset_subscription_path(changeset) + end + assert_response :forbidden + + session_for(other_user) + + # bad diary id + post changeset_subscription_path(999111) + assert_response :not_found + + # trying to subscribe when already subscribed + assert_no_difference "changeset.subscribers.count" do + post changeset_subscription_path(changeset) + end + end + + def test_destroy_success + user = create(:user) + other_user = create(:user) + changeset = create(:changeset, :user => user) + changeset.subscribers << other_user + + session_for(other_user) + assert_difference "changeset.subscribers.count", -1 do + delete changeset_subscription_path(changeset) + end + assert_redirected_to changeset_path(changeset) + assert_not changeset.reload.subscribed?(other_user) + end + + def test_unsubscribe_fail + user = create(:user) + other_user = create(:user) + changeset = create(:changeset, :user => user) + + # not signed in + assert_no_difference "changeset.subscribers.count" do + delete changeset_subscription_path(changeset) + end + assert_response :forbidden + + session_for(other_user) + + # bad diary id + delete changeset_subscription_path(999111) + assert_response :not_found + + # trying to unsubscribe when not subscribed + assert_no_difference "changeset.subscribers.count" do + delete changeset_subscription_path(changeset) + end + end +end diff --git a/test/controllers/changesets_controller_test.rb b/test/controllers/changesets_controller_test.rb index 9bbca2ab1..2e701f248 100644 --- a/test/controllers/changesets_controller_test.rb +++ b/test/controllers/changesets_controller_test.rb @@ -32,22 +32,6 @@ class ChangesetsControllerTest < ActionDispatch::IntegrationTest { :path => "/history/feed", :method => :get }, { :controller => "changesets", :action => "feed", :format => :atom } ) - assert_routing( - { :path => "/changeset/1/subscribe", :method => :get }, - { :controller => "changesets", :action => "subscribe", :id => "1" } - ) - assert_routing( - { :path => "/changeset/1/subscribe", :method => :post }, - { :controller => "changesets", :action => "subscribe", :id => "1" } - ) - assert_routing( - { :path => "/changeset/1/unsubscribe", :method => :get }, - { :controller => "changesets", :action => "unsubscribe", :id => "1" } - ) - assert_routing( - { :path => "/changeset/1/unsubscribe", :method => :post }, - { :controller => "changesets", :action => "unsubscribe", :id => "1" } - ) end ## @@ -432,119 +416,6 @@ class ChangesetsControllerTest < ActionDispatch::IntegrationTest assert_redirected_to :action => :feed end - def test_subscribe_page - user = create(:user) - other_user = create(:user) - changeset = create(:changeset, :user => user) - path = subscribe_changeset_path(changeset) - - get path - assert_redirected_to login_path(:referer => path) - - session_for(other_user) - get path - assert_response :success - assert_dom ".content-body" do - assert_dom "a[href='#{changeset_path(changeset)}']", :text => "Changeset #{changeset.id}" - assert_dom "a[href='#{user_path(user)}']", :text => user.display_name - end - end - - def test_subscribe_success - user = create(:user) - other_user = create(:user) - changeset = create(:changeset, :user => user) - - session_for(other_user) - assert_difference "changeset.subscribers.count", 1 do - post subscribe_changeset_path(changeset) - end - assert_redirected_to changeset_path(changeset) - assert changeset.reload.subscribed?(other_user) - end - - def test_subscribe_fail - user = create(:user) - other_user = create(:user) - - changeset = create(:changeset, :user => user) - - # not signed in - assert_no_difference "changeset.subscribers.count" do - post subscribe_changeset_path(changeset) - end - assert_response :forbidden - - session_for(other_user) - - # bad diary id - post subscribe_changeset_path(999111) - assert_response :not_found - - # trying to subscribe when already subscribed - post subscribe_changeset_path(changeset) - assert_no_difference "changeset.subscribers.count" do - post subscribe_changeset_path(changeset) - end - end - - def test_unsubscribe_page - user = create(:user) - other_user = create(:user) - changeset = create(:changeset, :user => user) - path = unsubscribe_changeset_path(changeset) - - get path - assert_redirected_to login_path(:referer => path) - - session_for(other_user) - get path - assert_response :success - assert_dom ".content-body" do - assert_dom "a[href='#{changeset_path(changeset)}']", :text => "Changeset #{changeset.id}" - assert_dom "a[href='#{user_path(user)}']", :text => user.display_name - end - end - - def test_unsubscribe_success - user = create(:user) - other_user = create(:user) - - changeset = create(:changeset, :user => user) - changeset.subscribers.push(other_user) - - session_for(other_user) - assert_difference "changeset.subscribers.count", -1 do - post unsubscribe_changeset_path(changeset) - end - assert_redirected_to changeset_path(changeset) - assert_not changeset.reload.subscribed?(other_user) - end - - def test_unsubscribe_fail - user = create(:user) - other_user = create(:user) - - changeset = create(:changeset, :user => user) - - # not signed in - assert_no_difference "changeset.subscribers.count" do - post unsubscribe_changeset_path(changeset) - end - assert_response :forbidden - - session_for(other_user) - - # bad diary id - post unsubscribe_changeset_path(999111) - assert_response :not_found - - # trying to unsubscribe when not subscribed - assert_no_difference "changeset.subscribers.count" do - post unsubscribe_changeset_path(changeset) - end - end - private ## diff --git a/test/mailers/user_mailer_test.rb b/test/mailers/user_mailer_test.rb index 3b7119ff6..9b895c475 100644 --- a/test/mailers/user_mailer_test.rb +++ b/test/mailers/user_mailer_test.rb @@ -83,7 +83,7 @@ class UserMailerTest < ActionMailer::TestCase body = Rails::Dom::Testing.html_document_fragment.parse(email.html_part.body) url = Rails.application.routes.url_helpers.changeset_url(changeset, :host => Settings.server_url, :protocol => Settings.server_protocol) - unsubscribe_url = Rails.application.routes.url_helpers.unsubscribe_changeset_url(changeset, :host => Settings.server_url, :protocol => Settings.server_protocol) + unsubscribe_url = Rails.application.routes.url_helpers.changeset_subscription_url(changeset, :host => Settings.server_url, :protocol => Settings.server_protocol) assert_select body, "a[href^='#{url}']" assert_select body, "a[href='#{unsubscribe_url}']", :count => 1 end