]> git.openstreetmap.org Git - rails.git/commitdiff
Merge remote-tracking branch 'upstream/pull/5461'
authorTom Hughes <tom@compton.nu>
Fri, 3 Jan 2025 19:32:42 +0000 (19:32 +0000)
committerTom Hughes <tom@compton.nu>
Fri, 3 Jan 2025 19:32:42 +0000 (19:32 +0000)
14 files changed:
app/abilities/ability.rb
app/controllers/messages/replies_controller.rb [new file with mode: 0644]
app/controllers/messages_controller.rb
app/helpers/user_blocks_helper.rb
app/mailers/user_mailer.rb
app/views/accounts/edit.html.erb
app/views/application/_auth_providers.html.erb
app/views/messages/show.html.erb
config/locales/en.yml
config/routes.rb
lib/auth.rb
test/controllers/messages/replies_controller_test.rb [new file with mode: 0644]
test/controllers/messages_controller_test.rb
test/helpers/user_blocks_helper_test.rb

index 6638016d72ea55b1cad4fbd908228562d1db00fc..7ed6470b84e5830c37e4184e50743b9d8a96ee8b 100644 (file)
@@ -42,7 +42,7 @@ class Ability
         can :update, DiaryEntry, :user => user
         can [:create], DiaryComment
         can [:make_friend, :remove_friend], Friendship
-        can [:read, :create, :reply, :inbox, :outbox, :muted, :mark, :unmute, :destroy], Message
+        can [:read, :create, :mark, :unmute, :destroy], Message
         can [:close, :reopen], Note
         can [:read, :update], :preference
         can :update, :profile
diff --git a/app/controllers/messages/replies_controller.rb b/app/controllers/messages/replies_controller.rb
new file mode 100644 (file)
index 0000000..b1e7b8d
--- /dev/null
@@ -0,0 +1,50 @@
+module Messages
+  class RepliesController < ApplicationController
+    layout "site"
+
+    before_action :authorize_web
+    before_action :set_locale
+
+    authorize_resource :class => Message
+
+    before_action :check_database_readable
+    before_action :check_database_writable
+
+    allow_thirdparty_images
+
+    # Allow the user to reply to another message.
+    def new
+      message = Message.find(params[:message_id])
+
+      if message.recipient == current_user
+        message.update(:message_read => true)
+
+        @message = Message.new(
+          :recipient => message.sender,
+          :title => "Re: #{message.title.sub(/^Re:\s*/, '')}",
+          :body => "On #{message.sent_on} #{message.sender.display_name} wrote:\n\n#{message.body.gsub(/^/, '> ')}"
+        )
+
+        @title = @message.title
+
+        render "messages/new"
+      elsif message.sender == current_user
+        @message = Message.new(
+          :recipient => message.recipient,
+          :title => "Re: #{message.title.sub(/^Re:\s*/, '')}",
+          :body => "On #{message.sent_on} #{message.sender.display_name} wrote:\n\n#{message.body.gsub(/^/, '> ')}"
+        )
+
+        @title = @message.title
+
+        render "messages/new"
+      else
+        flash[:notice] = t ".wrong_user", :user => current_user.display_name
+        redirect_to login_path(:referer => request.fullpath)
+      end
+    rescue ActiveRecord::RecordNotFound
+      @title = t "messages.no_such_message.title"
+      render "messages/no_such_message", :status => :not_found
+    end
+  end
+end
index 7162b900a011c4719c18a212f96691d3e68e26b8..26e8a5e09e6602d3a27508b8fb42a3d70b3acd5c 100644 (file)
@@ -10,7 +10,7 @@ class MessagesController < ApplicationController
 
   before_action :lookup_user, :only => [:new, :create]
   before_action :check_database_readable
-  before_action :check_database_writable, :only => [:new, :create, :reply, :mark, :destroy]
+  before_action :check_database_writable, :only => [:new, :create, :mark, :destroy]
 
   allow_thirdparty_images :only => [:new, :create, :show]
 
@@ -73,41 +73,6 @@ class MessagesController < ApplicationController
     render :action => "no_such_message", :status => :not_found
   end
 
-  # Allow the user to reply to another message.
-  def reply
-    message = Message.find(params[:message_id])
-
-    if message.recipient == current_user
-      message.update(:message_read => true)
-
-      @message = Message.new(
-        :recipient => message.sender,
-        :title => "Re: #{message.title.sub(/^Re:\s*/, '')}",
-        :body => "On #{message.sent_on} #{message.sender.display_name} wrote:\n\n#{message.body.gsub(/^/, '> ')}"
-      )
-
-      @title = @message.title
-
-      render :action => "new"
-    elsif message.sender == current_user
-      @message = Message.new(
-        :recipient => message.recipient,
-        :title => "Re: #{message.title.sub(/^Re:\s*/, '')}",
-        :body => "On #{message.sent_on} #{message.sender.display_name} wrote:\n\n#{message.body.gsub(/^/, '> ')}"
-      )
-
-      @title = @message.title
-
-      render :action => "new"
-    else
-      flash[:notice] = t ".wrong_user", :user => current_user.display_name
-      redirect_to login_path(:referer => request.fullpath)
-    end
-  rescue ActiveRecord::RecordNotFound
-    @title = t "messages.no_such_message.title"
-    render :action => "no_such_message", :status => :not_found
-  end
-
   # Set the message as being read or unread.
   def mark
     @message = current_user.messages.unscope(:where => :muted).find(params[:message_id])
index 8a3a8a3eb460f2b8c550d7daeba3c99e724e48f2..c7c12f6d1f17901f54e05367c35b9d4fdc69bd2e 100644 (file)
@@ -27,14 +27,10 @@ module UserBlocksHelper
 
   def block_short_status(block)
     if block.active?
-      if block.needs_view?
-        if block.ends_at > Time.now.utc
-          t("user_blocks.helper.short.active_unread")
-        else
-          t("user_blocks.helper.short.expired_unread")
-        end
-      else
+      if block.ends_at > Time.now.utc
         t("user_blocks.helper.short.active")
+      else
+        t("user_blocks.helper.short.active_until_read")
       end
     else
       if block.revoker_id.nil?
index dee3dafbed35562ab865f11c64fcad4d61e8a067..1dd13fb2d220787af6562f11281abb6bd0da07cc 100644 (file)
@@ -78,7 +78,7 @@ class UserMailer < ApplicationMailer
       @text = message.body
       @title = message.title
       @readurl = message_url(message)
-      @replyurl = message_reply_url(message)
+      @replyurl = new_message_reply_url(message)
       @author = @from_user
 
       attach_user_avatar(message.sender)
index a3e6f943bb9ef714979811c8c1c2e56015990a07..e31c5e90d2a7508e770a0870bde1a92e82712f5c 100644 (file)
   <fieldset class="mb-3">
     <label for="user_auth_provider" class="form-label"><%= t(".external auth") %></label>
     <div class="row">
-      <%= f.select(:auth_provider, { t("auth.providers.none") => "" }.merge(Auth.providers), :hide_label => true, :wrapper => { :class => "col-auto mb-0" }) %>
+      <%= f.select :auth_provider,
+                   Auth.providers.map { |provider| [I18n.t("auth.providers.#{provider}"), provider] },
+                   :include_blank => t("auth.providers.none"),
+                   :hide_label => true,
+                   :wrapper => { :class => "col-auto mb-0" } %>
       <%= f.text_field(:auth_uid, :hide_label => true, :wrapper => { :class => "col mb-0" }) %>
     </div>
     <small class="form-text text-body-secondary">(<a href="<%= t ".openid.link" %>" target="_new"><%= t ".openid.link text" %></a>)</small>
index 3feda6139a4473b637ae4d678fd90da8f6879be6..3edc6edd2476d9a8fd195867f7d01b832c7f29eb 100644 (file)
@@ -1,4 +1,4 @@
-<% prefered_auth_button_available = @preferred_auth_provider != "openid" && Auth.providers.value?(@preferred_auth_provider) %>
+<% prefered_auth_button_available = @preferred_auth_provider != "openid" && Auth.providers.include?(@preferred_auth_provider) %>
 
 <div>
   <%= tag.div :id => "login_auth_buttons",
@@ -11,7 +11,7 @@
     <% end %>
 
     <div class="col justify-content-center d-flex align-items-center flex-wrap gap-2">
-      <% Auth.providers.each_value do |provider| %>
+      <% Auth.providers.each do |provider| %>
         <% if provider == "openid" %>
           <%= button_tag image_tag("auth_providers/openid.svg",
                                    :alt => t(".openid.alt"),
index 99d6d0435512d0f8e33ef8ccc3112dec762ad20f..d3147c9699c3c24c95b1a12aa2c7d74acf24be0c 100644 (file)
@@ -18,7 +18,7 @@
 <div class="richtext text-break"><%= @message.body.to_html %></div>
 
 <div>
-  <%= link_to t(".reply_button"), message_reply_path(@message), :class => "btn btn-primary" %>
+  <%= link_to t(".reply_button"), new_message_reply_path(@message), :class => "btn btn-primary" %>
   <% if current_user == @message.recipient %>
     <%= link_to t(".unread_button"), message_mark_path(@message, :mark => "unread"), :method => "post", :class => "btn btn-primary" %>
     <%= link_to t(".destroy_button"), message_path(@message), :method => "delete", :class => "btn btn-danger" %>
index ea11ab03d87d1eea57406c51ab548820cd0ad584..3fabe13c1ff39502935a9dbe39e7898bd40ded3d 100644 (file)
@@ -1751,8 +1751,6 @@ en:
       title: "No such message"
       heading: "No such message"
       body: "Sorry there is no message with that id."
-    reply:
-      wrong_user: "You are logged in as '%{user}' but the message you have asked to reply to was not sent to that user. Please log in as the correct user in order to reply."
     show:
       title: "Read message"
       reply_button: "Reply"
@@ -1812,6 +1810,9 @@ en:
         people_mapping_nearby: "people mapping nearby"
       message:
         destroy_button: "Delete"
+    replies:
+      new:
+        wrong_user: "You are logged in as '%{user}' but the message you have asked to reply to was not sent to that user. Please log in as the correct user in order to reply."
   passwords:
     new:
       title: "Lost password"
@@ -2971,8 +2972,7 @@ en:
         ended: "ended"
         revoked_html: "revoked by %{name}"
         active: "active"
-        active_unread: "active unread"
-        expired_unread: "expired unread"
+        active_until_read: "active until read"
         read_html: "read at %{time}"
         time_in_future_title: "%{time_absolute}; in %{time_relative}"
         time_in_past_title: "%{time_absolute}; %{time_relative}"
index b068d997028d819b5bd55893042f0629f8d2a04c..6d6acc7db34654bfe024a1f1acb556476b8208f2 100644 (file)
@@ -314,7 +314,7 @@ OpenStreetMap::Application.routes.draw do
     post :mark
     patch :unmute
 
-    match :reply, :via => [:get, :post]
+    resource :reply, :module => :messages, :path_names => { :new => "new" }, :only => :new
   end
   namespace :messages, :path => "/messages" do
     resource :inbox, :only => :show
@@ -325,6 +325,7 @@ OpenStreetMap::Application.routes.draw do
   get "/user/:display_name/outbox", :to => redirect(:path => "/messages/outbox")
   get "/message/new/:display_name", :to => redirect(:path => "/messages/new/%{display_name}")
   get "/message/read/:message_id", :to => redirect(:path => "/messages/%{message_id}")
+  get "/messages/:message_id/reply", :to => redirect(:path => "/messages/%{message_id}/reply/new")
 
   # muting users
   scope "/user/:display_name" do
index 729772477757ac810113e6abf77a92fead58e904..2c6d0c1d7036ad5f4f2d4f1e6a53593f3048b65d 100644 (file)
@@ -1,15 +1,13 @@
 module Auth
-  @providers = {}
+  @providers = ["openid"]
+  @providers << "google" if Settings.key?(:google_auth_id)
+  @providers << "facebook" if Settings.key?(:facebook_auth_id)
+  @providers << "microsoft" if Settings.key?(:microsoft_auth_id)
+  @providers << "github" if Settings.key?(:github_auth_id)
+  @providers << "wikipedia" if Settings.key?(:wikipedia_auth_id)
+  @providers.freeze
 
   def self.providers
-    @providers[I18n.locale] ||= {
-      I18n.t("auth.providers.openid") => "openid"
-    }.tap do |providers|
-      providers[I18n.t("auth.providers.google")] = "google" if Settings.key?(:google_auth_id)
-      providers[I18n.t("auth.providers.facebook")] = "facebook" if Settings.key?(:facebook_auth_id)
-      providers[I18n.t("auth.providers.microsoft")] = "microsoft" if Settings.key?(:microsoft_auth_id)
-      providers[I18n.t("auth.providers.github")] = "github" if Settings.key?(:github_auth_id)
-      providers[I18n.t("auth.providers.wikipedia")] = "wikipedia" if Settings.key?(:wikipedia_auth_id)
-    end.freeze
+    @providers
   end
 end
diff --git a/test/controllers/messages/replies_controller_test.rb b/test/controllers/messages/replies_controller_test.rb
new file mode 100644 (file)
index 0000000..a839a44
--- /dev/null
@@ -0,0 +1,69 @@
+require "test_helper"
+
+module Messages
+  class RepliesControllerTest < ActionDispatch::IntegrationTest
+    ##
+    # test all routes which lead to this controller
+    def test_routes
+      assert_routing(
+        { :path => "/messages/1/reply/new", :method => :get },
+        { :controller => "messages/replies", :action => "new", :message_id => "1" }
+      )
+    end
+
+    def test_new
+      user = create(:user)
+      recipient_user = create(:user)
+      other_user = create(:user)
+      message = create(:message, :unread, :sender => user, :recipient => recipient_user)
+
+      # Check that the message reply page requires us to login
+      get new_message_reply_path(message)
+      assert_redirected_to login_path(:referer => new_message_reply_path(message))
+
+      # Login as the wrong user
+      session_for(other_user)
+
+      # Check that we can't reply to somebody else's message
+      get new_message_reply_path(message)
+      assert_redirected_to login_path(:referer => new_message_reply_path(message))
+      assert_equal "You are logged in as '#{other_user.display_name}' but the message you have asked to reply to was not sent to that user. Please log in as the correct user in order to reply.", flash[:notice]
+
+      # Login as the right user
+      session_for(recipient_user)
+
+      # Check that the message reply page loads
+      get new_message_reply_path(message)
+      assert_response :success
+      assert_template "new"
+      assert_select "title", "Re: #{message.title} | OpenStreetMap"
+      assert_select "form[action='/messages']", :count => 1 do
+        assert_select "input[type='hidden'][name='display_name'][value='#{user.display_name}']"
+        assert_select "input#message_title[value='Re: #{message.title}']", :count => 1
+        assert_select "textarea#message_body", :count => 1
+        assert_select "input[type='submit'][value='Send']", :count => 1
+      end
+      assert Message.find(message.id).message_read
+
+      # Login as the sending user
+      session_for(user)
+
+      # Check that the message reply page loads
+      get new_message_reply_path(message)
+      assert_response :success
+      assert_template "new"
+      assert_select "title", "Re: #{message.title} | OpenStreetMap"
+      assert_select "form[action='/messages']", :count => 1 do
+        assert_select "input[type='hidden'][name='display_name'][value='#{recipient_user.display_name}']"
+        assert_select "input#message_title[value='Re: #{message.title}']", :count => 1
+        assert_select "textarea#message_body", :count => 1
+        assert_select "input[type='submit'][value='Send']", :count => 1
+      end
+
+      # Asking to reply to a message with a bogus ID should fail
+      get new_message_reply_path(99999)
+      assert_response :not_found
+      assert_template "no_such_message"
+    end
+  end
+end
index f72e695936813142a723b4aaef28cf6bb8c4f0ec..9249908929426d32086ee4297f41d1cacf6198e1 100644 (file)
@@ -20,14 +20,6 @@ class MessagesControllerTest < ActionDispatch::IntegrationTest
       { :path => "/messages/1/mark", :method => :post },
       { :controller => "messages", :action => "mark", :message_id => "1" }
     )
-    assert_routing(
-      { :path => "/messages/1/reply", :method => :get },
-      { :controller => "messages", :action => "reply", :message_id => "1" }
-    )
-    assert_routing(
-      { :path => "/messages/1/reply", :method => :post },
-      { :controller => "messages", :action => "reply", :message_id => "1" }
-    )
     assert_routing(
       { :path => "/messages/1", :method => :delete },
       { :controller => "messages", :action => "destroy", :id => "1" }
@@ -219,63 +211,6 @@ class MessagesControllerTest < ActionDispatch::IntegrationTest
     end
   end
 
-  ##
-  # test the reply action
-  def test_reply
-    user = create(:user)
-    recipient_user = create(:user)
-    other_user = create(:user)
-    message = create(:message, :unread, :sender => user, :recipient => recipient_user)
-
-    # Check that the message reply page requires us to login
-    get message_reply_path(message)
-    assert_redirected_to login_path(:referer => message_reply_path(message))
-
-    # Login as the wrong user
-    session_for(other_user)
-
-    # Check that we can't reply to somebody else's message
-    get message_reply_path(message)
-    assert_redirected_to login_path(:referer => message_reply_path(message))
-    assert_equal "You are logged in as '#{other_user.display_name}' but the message you have asked to reply to was not sent to that user. Please log in as the correct user in order to reply.", flash[:notice]
-
-    # Login as the right user
-    session_for(recipient_user)
-
-    # Check that the message reply page loads
-    get message_reply_path(message)
-    assert_response :success
-    assert_template "new"
-    assert_select "title", "Re: #{message.title} | OpenStreetMap"
-    assert_select "form[action='/messages']", :count => 1 do
-      assert_select "input[type='hidden'][name='display_name'][value='#{user.display_name}']"
-      assert_select "input#message_title[value='Re: #{message.title}']", :count => 1
-      assert_select "textarea#message_body", :count => 1
-      assert_select "input[type='submit'][value='Send']", :count => 1
-    end
-    assert Message.find(message.id).message_read
-
-    # Login as the sending user
-    session_for(user)
-
-    # Check that the message reply page loads
-    get message_reply_path(message)
-    assert_response :success
-    assert_template "new"
-    assert_select "title", "Re: #{message.title} | OpenStreetMap"
-    assert_select "form[action='/messages']", :count => 1 do
-      assert_select "input[type='hidden'][name='display_name'][value='#{recipient_user.display_name}']"
-      assert_select "input#message_title[value='Re: #{message.title}']", :count => 1
-      assert_select "textarea#message_body", :count => 1
-      assert_select "input[type='submit'][value='Send']", :count => 1
-    end
-
-    # Asking to reply to a message with a bogus ID should fail
-    get message_reply_path(99999)
-    assert_response :not_found
-    assert_template "no_such_message"
-  end
-
   ##
   # test the show action
   def test_show
index db4fd87a49a8d9672bd0785437f64f0cc5b1ca28..99f59af4795437b488e576fdecca530de7cbc4cb 100644 (file)
@@ -14,6 +14,22 @@ class UserBlocksHelperTest < ActionView::TestCase
     assert_match %r{^Ends in <time title=".* datetime=".*">about 1 hour</time>\.$}, block_status(block)
   end
 
+  def test_block_short_status
+    freeze_time do
+      future_end_block = create(:user_block, :ends_at => Time.now.utc + 48.hours)
+      unread_future_end_block = create(:user_block, :needs_view, :ends_at => Time.now.utc + 48.hours)
+      past_end_block = create(:user_block, :ends_at => Time.now.utc + 1.hour)
+      unread_past_end_block = create(:user_block, :needs_view, :ends_at => Time.now.utc + 1.hour)
+
+      travel 24.hours
+
+      assert_equal "active", block_short_status(future_end_block)
+      assert_equal "active", block_short_status(unread_future_end_block)
+      assert_equal "ended", block_short_status(past_end_block)
+      assert_equal "active until read", block_short_status(unread_past_end_block)
+    end
+  end
+
   def test_block_duration_in_words
     words = block_duration_in_words(364.days)
     assert_equal "11 months", words