From 6d9e4a9330c930172112030bc2b7125ccaf26e6b Mon Sep 17 00:00:00 2001 From: taitus Date: Tue, 29 Dec 2020 12:08:57 +0100 Subject: [PATCH] Allow users to manage their notifications The user can access this page without being logged in. We identify the user through the "subscriptions_token" parameter and show a list of the notifications that can be enable/disable. We will return a 404 error in case someone accesses the page with a non-existent token. We also control the case that some anonymous user tries to access the page without any token, by returning the CanCan::AccessDenied exception. --- app/assets/stylesheets/application.scss | 1 + app/assets/stylesheets/layout.scss | 3 ++- app/assets/stylesheets/subscriptions.scss | 5 +++++ .../subscriptions/edit_component.html.erb | 13 +++++++++++++ .../subscriptions/edit_component.rb | 7 +++++++ app/controllers/subscriptions_controller.rb | 17 +++++++++++++++++ app/views/subscriptions/edit.html.erb | 1 + config/routes/account.rb | 2 ++ .../subscriptions/edit_component_spec.rb | 19 +++++++++++++++++++ .../subscriptions_controller_spec.rb | 16 ++++++++++++++++ 10 files changed, 83 insertions(+), 1 deletion(-) create mode 100644 app/assets/stylesheets/subscriptions.scss create mode 100644 app/components/subscriptions/edit_component.html.erb create mode 100644 app/components/subscriptions/edit_component.rb create mode 100644 app/controllers/subscriptions_controller.rb create mode 100644 app/views/subscriptions/edit.html.erb create mode 100644 spec/components/subscriptions/edit_component_spec.rb create mode 100644 spec/controllers/subscriptions_controller_spec.rb diff --git a/app/assets/stylesheets/application.scss b/app/assets/stylesheets/application.scss index 08bb60faa..0aa0834a7 100644 --- a/app/assets/stylesheets/application.scss +++ b/app/assets/stylesheets/application.scss @@ -47,6 +47,7 @@ @import "sdg/**/*"; @import "sdg_management/*"; @import "sdg_management/**/*"; +@import "subscriptions"; @import "widgets/**/*"; @import "custom"; diff --git a/app/assets/stylesheets/layout.scss b/app/assets/stylesheets/layout.scss index 4c38b27d7..d3c5ca090 100644 --- a/app/assets/stylesheets/layout.scss +++ b/app/assets/stylesheets/layout.scss @@ -74,7 +74,8 @@ main { &.sdg-goals-index, &.sdg-goal-show, &.topic-edit, - &.topic-new { + &.topic-new, + &.subscriptions-edit { @include grid-column-gutter; } } diff --git a/app/assets/stylesheets/subscriptions.scss b/app/assets/stylesheets/subscriptions.scss new file mode 100644 index 000000000..6affddaaf --- /dev/null +++ b/app/assets/stylesheets/subscriptions.scss @@ -0,0 +1,5 @@ +.subscriptions-edit { + form { + max-width: $global-width * 7 / 12; + } +} diff --git a/app/components/subscriptions/edit_component.html.erb b/app/components/subscriptions/edit_component.html.erb new file mode 100644 index 000000000..09e65926b --- /dev/null +++ b/app/components/subscriptions/edit_component.html.erb @@ -0,0 +1,13 @@ +
+ <%= form_for user, url: subscriptions_path(token: user.subscriptions_token) do |f| %> +

<%= t("account.show.notifications") %>

+ +
<%= f.check_box :email_on_comment %>
+
<%= f.check_box :email_on_comment_reply %>
+
<%= f.check_box :newsletter %>
+
<%= f.check_box :email_digest %>
+
<%= f.check_box :email_on_direct_message %>
+ + <%= f.submit t("account.show.save_changes_submit"), class: "button margin-top" %> + <% end %> +
diff --git a/app/components/subscriptions/edit_component.rb b/app/components/subscriptions/edit_component.rb new file mode 100644 index 000000000..bd5771102 --- /dev/null +++ b/app/components/subscriptions/edit_component.rb @@ -0,0 +1,7 @@ +class Subscriptions::EditComponent < ApplicationComponent + attr_reader :user + + def initialize(user) + @user = user + end +end diff --git a/app/controllers/subscriptions_controller.rb b/app/controllers/subscriptions_controller.rb new file mode 100644 index 000000000..e5c4fa34a --- /dev/null +++ b/app/controllers/subscriptions_controller.rb @@ -0,0 +1,17 @@ +class SubscriptionsController < ApplicationController + before_action :set_user + skip_authorization_check + + def edit + end + + private + + def set_user + @user = if params[:token].present? + User.find_by!(subscriptions_token: params[:token]) + else + current_user || raise(CanCan::AccessDenied) + end + end +end diff --git a/app/views/subscriptions/edit.html.erb b/app/views/subscriptions/edit.html.erb new file mode 100644 index 000000000..cc3b8a685 --- /dev/null +++ b/app/views/subscriptions/edit.html.erb @@ -0,0 +1 @@ +<%= render Subscriptions::EditComponent.new(@user) %> diff --git a/config/routes/account.rb b/config/routes/account.rb index 2b377bc36..128107207 100644 --- a/config/routes/account.rb +++ b/config/routes/account.rb @@ -1,3 +1,5 @@ resource :account, controller: "account", only: [:show, :update, :delete] do get :erase, on: :collection end + +resource :subscriptions, only: [:edit] diff --git a/spec/components/subscriptions/edit_component_spec.rb b/spec/components/subscriptions/edit_component_spec.rb new file mode 100644 index 000000000..060407d16 --- /dev/null +++ b/spec/components/subscriptions/edit_component_spec.rb @@ -0,0 +1,19 @@ +require "rails_helper" + +describe Subscriptions::EditComponent do + let(:user) { create(:user, subscriptions_token: SecureRandom.base58(32)) } + let(:component) { Subscriptions::EditComponent.new(user) } + + it "renders checkboxes to change the subscriptions preferences" do + render_inline component + + expect(page).to have_content "Notifications" + expect(page).to have_field "Notify me by email when someone comments on my proposals or debates", + type: :checkbox + expect(page).to have_field "Notify me by email when someone replies to my comments", type: :checkbox + expect(page).to have_field "Receive by email website relevant information", type: :checkbox + expect(page).to have_field "Receive a summary of proposal notifications", type: :checkbox + expect(page).to have_field "Receive emails about direct messages", type: :checkbox + expect(page).to have_button "Save changes" + end +end diff --git a/spec/controllers/subscriptions_controller_spec.rb b/spec/controllers/subscriptions_controller_spec.rb new file mode 100644 index 000000000..ef1309c46 --- /dev/null +++ b/spec/controllers/subscriptions_controller_spec.rb @@ -0,0 +1,16 @@ +require "rails_helper" + +describe SubscriptionsController do + describe "GET edit" do + it "returns a 404 code with a wrong token" do + expect { get :edit, params: { token: "non_existent" } }.to raise_error ActiveRecord::RecordNotFound + end + + it "doesn't allow access to anonymous users without a token" do + get :edit, params: { token: "" } + + expect(response).to redirect_to "/" + expect(flash[:alert]).to eq "You do not have permission to access this page." + end + end +end