Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Move subscription functionality to Turbo Streams #1417

Merged
merged 8 commits into from
Oct 28, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 0 additions & 17 deletions app/controllers/ajax/subscription_controller.rb

This file was deleted.

41 changes: 41 additions & 0 deletions app/controllers/subscriptions_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# frozen_string_literal: true

class SubscriptionsController < ApplicationController
include TurboStreamable

before_action :authenticate_user!

turbo_stream_actions :create, :destroy

def create
answer = Answer.find(params[:answer])
result = Subscription.subscribe(current_user, answer)

respond_to do |format|
format.turbo_stream do
render turbo_stream: [
turbo_stream.replace("subscription-#{answer.id}", partial: "subscriptions/destroy", locals: { answer: }),
render_toast(t(result.present? ? ".success" : ".error"), result.present?)
]
end

format.html { redirect_to answer_path(username: answer.user.screen_name, id: answer.id) }
end
end

def destroy
answer = Answer.find(params[:answer])
result = Subscription.unsubscribe(current_user, answer)

respond_to do |format|
format.turbo_stream do
render turbo_stream: [
turbo_stream.replace("subscription-#{answer.id}", partial: "subscriptions/create", locals: { answer: }),
render_toast(t(result.present? ? ".success" : ".error"), result.present?)
]
end

format.html { redirect_to answer_path(username: answer.user.screen_name, id: answer.id) }
end
end
end
2 changes: 0 additions & 2 deletions app/javascript/retrospring/features/answerbox/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,9 @@ import registerAnswerboxCommentEvents from './comment';
import { answerboxDestroyHandler } from './destroy';
import { answerboxReportHandler } from './report';
import { answerboxSmileHandler } from './smile';
import { answerboxSubscribeHandler } from './subscribe';

export default (): void => {
registerEvents([
{ type: 'click', target: '[data-action=ab-submarine]', handler: answerboxSubscribeHandler, global: true },
{ type: 'click', target: '[data-action=ab-report]', handler: answerboxReportHandler, global: true },
{ type: 'click', target: '[data-action=ab-destroy]', handler: answerboxDestroyHandler, global: true },
{ type: 'click', target: '[name=ab-smile]', handler: answerboxSmileHandler, global: true }
Expand Down
44 changes: 0 additions & 44 deletions app/javascript/retrospring/features/answerbox/subscribe.ts

This file was deleted.

9 changes: 2 additions & 7 deletions app/views/actions/_answer.html.haml
Original file line number Diff line number Diff line change
@@ -1,13 +1,8 @@
.dropdown-menu.dropdown-menu-end{ role: :menu }
- if subscribed_answer_ids&.include?(answer.id)
-# fun joke should subscribe?
%a.dropdown-item{ href: "#", data: { a_id: answer.id, action: "ab-submarine", torpedo: "no" } }
%i.fa.fa-fw.fa-anchor
= t("voc.unsubscribe")
= render "subscriptions/destroy", answer: answer
- else
%a.dropdown-item{ href: "#", data: { a_id: answer.id, action: "ab-submarine", torpedo: "yes" } }
%i.fa.fa-fw.fa-anchor
= t("voc.subscribe")
= render "subscriptions/create", answer: answer
- if privileged? answer.user
%a.dropdown-item.text-danger{ href: "#", data: { a_id: answer.id, action: "ab-destroy" } }
%i.fa.fa-fw.fa-trash-o
Expand Down
3 changes: 3 additions & 0 deletions app/views/subscriptions/_create.html.haml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
= button_to subscriptions_path(answer: answer.id), class: "dropdown-item", form: { id: "subscription-#{answer.id}" } do
%i.fa.fa-fw.fa-bell
= t("voc.subscribe")
3 changes: 3 additions & 0 deletions app/views/subscriptions/_destroy.html.haml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
= button_to subscriptions_path(answer: answer.id), method: :delete, class: "dropdown-item", form: { id: "subscription-#{answer.id}" } do
%i.fa.fa-fw.fa-bell-slash
= t("voc.unsubscribe")
7 changes: 7 additions & 0 deletions config/locales/controllers.en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,13 @@ en:
error: :errors.invalid_otp
destroy:
success: "Two factor authentication has been disabled for your account."
subscriptions:
create:
success: "Successfully subscribed."
error: "Failed to subscribe to answer."
destroy:
success: "Successfully unsubscribed."
error: "Failed to unsubscribe from answer."
user:
sessions:
create:
Expand Down
6 changes: 0 additions & 6 deletions config/locales/frontend.en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,6 @@ en:
error:
title: "Uh-oh…"
message: "An error occurred, a developer should check the console for details"
subscription:
subscribe: "Successfully subscribed."
unsubscribe: "Successfully unsubscribed."
fail:
subscribe: "Failed to subscribe to answer."
unsubscribe: "Failed to unsubscribe from answer."
list:
confirm:
title: "Are you sure?"
Expand Down
4 changes: 2 additions & 2 deletions config/routes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -128,8 +128,6 @@
post "/create_list", to: "list#create", as: :create_list
post "/destroy_list", to: "list#destroy", as: :destroy_list
post "/list_membership", to: "list#membership", as: :list_membership
post "/subscribe", to: "subscription#subscribe", as: :subscribe_answer
post "/unsubscribe", to: "subscription#unsubscribe", as: :unsubscribe_answer
get "/webpush/key", to: "web_push#key", as: :webpush_key
post "/webpush/check", to: "web_push#check", as: :webpush_check
post "/webpush", to: "web_push#subscribe", as: :webpush_subscribe
Expand All @@ -148,6 +146,8 @@
post "/inbox/create", to: "inbox#create", as: :inbox_create
get "/inbox", to: "inbox#show", as: :inbox

resource :subscriptions, controller: :subscriptions, only: %i[create destroy]

get "/user/:username", to: "user#show"
get "/@:username", to: "user#show", as: :user
get "/@:username/a/:id", to: "answer#show", as: :answer
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,41 +2,33 @@

require "rails_helper"

describe Ajax::SubscriptionController, :ajax_controller, type: :controller do
describe SubscriptionsController, type: :controller do
# need to use a different user here, as after a create the user owning the
# answer is automatically subscribed to it
let(:answer_user) { FactoryBot.create(:user) }
let(:answer) { FactoryBot.create(:answer, user: answer_user) }
let(:user) { FactoryBot.create(:user) }

describe "#subscribe" do
describe "#create" do
let(:params) do
{
answer: answer_id
answer: answer_id,
}
end

subject { post(:subscribe, params: params) }
subject { post(:create, params:, format: :turbo_stream) }

context "when user is signed in" do
before(:each) { sign_in(user) }

context "when answer exists" do
let(:answer_id) { answer.id }
let(:expected_response) do
{
"success" => true,
"status" => "okay",
"message" => anything
}
end

context "when subscription does not exist" do
it "creates a subscription on the answer" do
expect { subject }.to(change { answer.subscriptions.count }.by(1))
expect(answer.subscriptions.map { |s| s.user.id }.sort).to eq([answer_user.id, user.id].sort)
end

include_examples "returns the expected response"
end

context "when subscription already exists" do
Expand All @@ -46,26 +38,15 @@
expect { subject }.to(change { answer.subscriptions.count }.by(0))
expect(answer.subscriptions.map { |s| s.user.id }.sort).to eq([answer_user.id, user.id].sort)
end

include_examples "returns the expected response"
end
end

context "when answer does not exist" do
let(:answer_id) { "Bielefeld" }
let(:expected_response) do
{
"success" => false,
"status" => "not_found",
"message" => anything
}
end

it "does not create a new subscription" do
expect { subject }.not_to(change { Subscription.count })
end

include_examples "returns the expected response"
end
end

Expand All @@ -79,27 +60,20 @@
end
end

describe "#unsubscribe" do
describe "#destroy" do
let(:params) do
{
answer: answer_id
answer: answer_id,
}
end

subject { post(:unsubscribe, params: params) }
subject { delete(:destroy, params:, format: :turbo_stream) }

context "when user is signed in" do
before(:each) { sign_in(user) }

context "when answer exists" do
let(:answer_id) { answer.id }
let(:expected_response) do
{
"success" => true,
"status" => "okay",
"message" => anything
}
end

context "when subscription exists" do
before(:each) { Subscription.subscribe(user, answer) }
Expand All @@ -108,43 +82,22 @@
expect { subject }.to(change { answer.subscriptions.count }.by(-1))
expect(answer.subscriptions.map { |s| s.user.id }.sort).to eq([answer_user.id].sort)
end

include_examples "returns the expected response"
end

context "when subscription does not exist" do
let(:expected_response) do
{
"success" => false,
"status" => "okay",
"message" => anything
}
end

it "does not modify the answer's subscriptions" do
expect { subject }.to(change { answer.subscriptions.count }.by(0))
expect(answer.subscriptions.map { |s| s.user.id }.sort).to eq([answer_user.id].sort)
end

include_examples "returns the expected response"
end
end

context "when answer does not exist" do
let(:answer_id) { "Bielefeld" }
let(:expected_response) do
{
"success" => false,
"status" => "not_found",
"message" => anything
}
end

it "does not create a new subscription" do
expect { subject }.not_to(change { Subscription.count })
end

include_examples "returns the expected response"
end
end

Expand Down