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.
This commit is contained in:
taitus
2020-12-29 12:08:57 +01:00
parent 2bef215fc6
commit 6d9e4a9330
10 changed files with 83 additions and 1 deletions

View File

@@ -47,6 +47,7 @@
@import "sdg/**/*"; @import "sdg/**/*";
@import "sdg_management/*"; @import "sdg_management/*";
@import "sdg_management/**/*"; @import "sdg_management/**/*";
@import "subscriptions";
@import "widgets/**/*"; @import "widgets/**/*";
@import "custom"; @import "custom";

View File

@@ -74,7 +74,8 @@ main {
&.sdg-goals-index, &.sdg-goals-index,
&.sdg-goal-show, &.sdg-goal-show,
&.topic-edit, &.topic-edit,
&.topic-new { &.topic-new,
&.subscriptions-edit {
@include grid-column-gutter; @include grid-column-gutter;
} }
} }

View File

@@ -0,0 +1,5 @@
.subscriptions-edit {
form {
max-width: $global-width * 7 / 12;
}
}

View File

@@ -0,0 +1,13 @@
<main class="subscriptions-edit">
<%= form_for user, url: subscriptions_path(token: user.subscriptions_token) do |f| %>
<h2><%= t("account.show.notifications") %></h2>
<div><%= f.check_box :email_on_comment %></div>
<div><%= f.check_box :email_on_comment_reply %></div>
<div><%= f.check_box :newsletter %></div>
<div><%= f.check_box :email_digest %></div>
<div><%= f.check_box :email_on_direct_message %></div>
<%= f.submit t("account.show.save_changes_submit"), class: "button margin-top" %>
<% end %>
</main>

View File

@@ -0,0 +1,7 @@
class Subscriptions::EditComponent < ApplicationComponent
attr_reader :user
def initialize(user)
@user = user
end
end

View File

@@ -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

View File

@@ -0,0 +1 @@
<%= render Subscriptions::EditComponent.new(@user) %>

View File

@@ -1,3 +1,5 @@
resource :account, controller: "account", only: [:show, :update, :delete] do resource :account, controller: "account", only: [:show, :update, :delete] do
get :erase, on: :collection get :erase, on: :collection
end end
resource :subscriptions, only: [:edit]

View File

@@ -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

View File

@@ -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