mirror of
https://github.com/Retrospring/retrospring.git
synced 2025-02-26 00:53:01 +01:00
Merge pull request #824 from Retrospring/feature/anonymous-block-tuuuuuuurbo
Migrate anonymous blocks to Turbo Streams
This commit is contained in:
commit
cb61db02eb
14 changed files with 84 additions and 215 deletions
app
controllers
javascript/retrospring/features
policies
views
config
spec/controllers
|
@ -1,39 +0,0 @@
|
||||||
# frozen_string_literal: true
|
|
||||||
|
|
||||||
class Ajax::AnonymousBlockController < AjaxController
|
|
||||||
def create
|
|
||||||
params.require :question
|
|
||||||
|
|
||||||
question = Question.find(params[:question])
|
|
||||||
|
|
||||||
raise Errors::Forbidden if params[:global] && !current_user.mod?
|
|
||||||
|
|
||||||
AnonymousBlock.create!(
|
|
||||||
user: params[:global] ? nil : current_user,
|
|
||||||
identifier: question.author_identifier,
|
|
||||||
question:
|
|
||||||
)
|
|
||||||
|
|
||||||
question.inboxes.first&.destroy
|
|
||||||
|
|
||||||
@response[:status] = :okay
|
|
||||||
@response[:message] = t(".success")
|
|
||||||
@response[:success] = true
|
|
||||||
end
|
|
||||||
|
|
||||||
def destroy
|
|
||||||
params.require :id
|
|
||||||
|
|
||||||
block = AnonymousBlock.find(params[:id])
|
|
||||||
if current_user != block.user
|
|
||||||
@response[:status] = :nopriv
|
|
||||||
@response[:message] = t(".nopriv")
|
|
||||||
end
|
|
||||||
|
|
||||||
block.destroy!
|
|
||||||
|
|
||||||
@response[:status] = :okay
|
|
||||||
@response[:message] = t(".success")
|
|
||||||
@response[:success] = true
|
|
||||||
end
|
|
||||||
end
|
|
46
app/controllers/anonymous_block_controller.rb
Normal file
46
app/controllers/anonymous_block_controller.rb
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
class AnonymousBlockController < ApplicationController
|
||||||
|
before_action :authenticate_user!
|
||||||
|
|
||||||
|
def create
|
||||||
|
params.require :question
|
||||||
|
|
||||||
|
question = Question.find(params[:question])
|
||||||
|
authorize AnonymousBlock, :create_global? if params[:global]
|
||||||
|
|
||||||
|
AnonymousBlock.create!(
|
||||||
|
user: params[:global] ? nil : current_user,
|
||||||
|
identifier: question.author_identifier,
|
||||||
|
question:
|
||||||
|
)
|
||||||
|
|
||||||
|
inbox_id = question.inboxes.first.id
|
||||||
|
question.inboxes.first&.destroy
|
||||||
|
|
||||||
|
respond_to do |format|
|
||||||
|
format.turbo_stream do
|
||||||
|
render turbo_stream: turbo_stream.remove("inbox_#{inbox_id}")
|
||||||
|
end
|
||||||
|
|
||||||
|
format.html { redirect_back(fallback_location: inbox_path) }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def destroy
|
||||||
|
params.require :id
|
||||||
|
|
||||||
|
block = AnonymousBlock.find(params[:id])
|
||||||
|
authorize block
|
||||||
|
|
||||||
|
block.destroy!
|
||||||
|
|
||||||
|
respond_to do |format|
|
||||||
|
format.turbo_stream do
|
||||||
|
render turbo_stream: turbo_stream.remove("block_#{params[:id]}")
|
||||||
|
end
|
||||||
|
|
||||||
|
format.html { redirect_back(fallback_location: settings_blocks_path) }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -1,31 +0,0 @@
|
||||||
import { post } from '@rails/request.js';
|
|
||||||
|
|
||||||
import { showErrorNotification, showNotification } from "utilities/notifications";
|
|
||||||
import I18n from "retrospring/i18n";
|
|
||||||
|
|
||||||
export function blockAnonEventHandler(event: Event): void {
|
|
||||||
const element: HTMLAnchorElement = event.target as HTMLAnchorElement;
|
|
||||||
|
|
||||||
const data = {
|
|
||||||
question: element.getAttribute('data-q-id'),
|
|
||||||
};
|
|
||||||
|
|
||||||
post('/ajax/block_anon', {
|
|
||||||
body: data,
|
|
||||||
contentType: 'application/json'
|
|
||||||
})
|
|
||||||
.then(async response => {
|
|
||||||
const data = await response.json;
|
|
||||||
|
|
||||||
if (!data.success) return false;
|
|
||||||
const inboxEntry: Node = element.closest('.inbox-entry');
|
|
||||||
|
|
||||||
showNotification(data.message);
|
|
||||||
|
|
||||||
(inboxEntry as HTMLElement).remove();
|
|
||||||
})
|
|
||||||
.catch(err => {
|
|
||||||
console.log(err);
|
|
||||||
showErrorNotification(I18n.translate('frontend.error.message'));
|
|
||||||
});
|
|
||||||
}
|
|
|
@ -3,15 +3,13 @@ import { answerEntryHandler, answerEntryInputHandler } from './answer';
|
||||||
import { deleteEntryHandler } from './delete';
|
import { deleteEntryHandler } from './delete';
|
||||||
import optionsEntryHandler from './options';
|
import optionsEntryHandler from './options';
|
||||||
import { reportEventHandler } from './report';
|
import { reportEventHandler } from './report';
|
||||||
import { blockAnonEventHandler } from "retrospring/features/inbox/entry/blockAnon";
|
|
||||||
|
|
||||||
export default (): void => {
|
export default (): void => {
|
||||||
registerEvents([
|
registerEvents([
|
||||||
{ type: 'click', target: 'button[name="ib-answer"]', handler: answerEntryHandler, global: true },
|
{ type: 'click', target: 'button[name="ib-answer"]', handler: answerEntryHandler, global: true },
|
||||||
{ type: 'click', target: '[name="ib-destroy"]', handler: deleteEntryHandler, global: true },
|
{ type: 'click', target: '[name="ib-destroy"]', handler: deleteEntryHandler, global: true },
|
||||||
{ type: 'click', target: '[name=ib-report]', handler: reportEventHandler, global: true },
|
{ type: 'click', target: '[name=ib-report]', handler: reportEventHandler, global: true },
|
||||||
{ type: 'click', target: '[name=ib-block-anon]', handler: blockAnonEventHandler, global: true },
|
|
||||||
{ type: 'click', target: 'button[name=ib-options]', handler: optionsEntryHandler, global: true },
|
{ type: 'click', target: 'button[name=ib-options]', handler: optionsEntryHandler, global: true },
|
||||||
{ type: 'keydown', target: 'textarea[name=ib-answer]', handler: answerEntryInputHandler, global: true }
|
{ type: 'keydown', target: 'textarea[name=ib-answer]', handler: answerEntryInputHandler, global: true }
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,47 +0,0 @@
|
||||||
import { post } from '@rails/request.js';
|
|
||||||
import swal from 'sweetalert';
|
|
||||||
|
|
||||||
import { showErrorNotification, showNotification } from "utilities/notifications";
|
|
||||||
import I18n from "retrospring/i18n";
|
|
||||||
|
|
||||||
export function blockAnonEventHandler(event: Event): void {
|
|
||||||
event.preventDefault();
|
|
||||||
|
|
||||||
swal({
|
|
||||||
title: I18n.translate('frontend.mod_mute.confirm.title'),
|
|
||||||
text: I18n.translate('frontend.mod_mute.confirm.text'),
|
|
||||||
type: 'warning',
|
|
||||||
showCancelButton: true,
|
|
||||||
confirmButtonColor: "#DD6B55",
|
|
||||||
confirmButtonText: I18n.translate('voc.y'),
|
|
||||||
cancelButtonText: I18n.translate('voc.n'),
|
|
||||||
closeOnConfirm: true,
|
|
||||||
}, (dialogResult) => {
|
|
||||||
if (!dialogResult) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const sender: HTMLAnchorElement = event.target as HTMLAnchorElement;
|
|
||||||
|
|
||||||
const data = {
|
|
||||||
question: sender.getAttribute('data-q-id'),
|
|
||||||
global: 'true'
|
|
||||||
};
|
|
||||||
|
|
||||||
post('/ajax/block_anon', {
|
|
||||||
body: data,
|
|
||||||
contentType: 'application/json'
|
|
||||||
})
|
|
||||||
.then(async response => {
|
|
||||||
const data = await response.json;
|
|
||||||
|
|
||||||
if (!data.success) return false;
|
|
||||||
|
|
||||||
showNotification(data.message);
|
|
||||||
})
|
|
||||||
.catch(err => {
|
|
||||||
console.log(err);
|
|
||||||
showErrorNotification(I18n.translate('frontend.error.message'));
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
|
@ -2,15 +2,13 @@ import registerEvents from 'utilities/registerEvents';
|
||||||
import { banCheckboxHandler, banFormHandler, permanentBanCheckboxHandler } from './ban';
|
import { banCheckboxHandler, banFormHandler, permanentBanCheckboxHandler } from './ban';
|
||||||
import { destroyReportHandler } from './destroy';
|
import { destroyReportHandler } from './destroy';
|
||||||
import { privilegeCheckHandler } from './privilege';
|
import { privilegeCheckHandler } from './privilege';
|
||||||
import { blockAnonEventHandler } from './blockAnon';
|
|
||||||
|
|
||||||
export default (): void => {
|
export default (): void => {
|
||||||
registerEvents([
|
registerEvents([
|
||||||
{ type: 'click', target: '[type="checkbox"][name="check-your-privileges"]', handler: privilegeCheckHandler, global: true },
|
{ type: 'click', target: '[type="checkbox"][name="check-your-privileges"]', handler: privilegeCheckHandler, global: true },
|
||||||
{ type: 'click', target: '[name="mod-delete-report"]', handler: destroyReportHandler, global: true },
|
{ type: 'click', target: '[name="mod-delete-report"]', handler: destroyReportHandler, global: true },
|
||||||
{ type: 'click', target: '[name="mod-block-anon"]', handler: blockAnonEventHandler, global: true },
|
|
||||||
{ type: 'change', target: '[name="ban"][type="checkbox"]', handler: banCheckboxHandler, global: true },
|
{ type: 'change', target: '[name="ban"][type="checkbox"]', handler: banCheckboxHandler, global: true },
|
||||||
{ type: 'change', target: '[name="permaban"][type="checkbox"]', handler: permanentBanCheckboxHandler, global: true },
|
{ type: 'change', target: '[name="permaban"][type="checkbox"]', handler: permanentBanCheckboxHandler, global: true },
|
||||||
{ type: 'submit', target: '#modal-ban form', handler: banFormHandler, global: true }
|
{ type: 'submit', target: '#modal-ban form', handler: banFormHandler, global: true }
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,21 +0,0 @@
|
||||||
import { destroy } from '@rails/request.js';
|
|
||||||
import { showNotification, showErrorNotification } from 'utilities/notifications';
|
|
||||||
import I18n from 'retrospring/i18n';
|
|
||||||
|
|
||||||
export function unblockAnonymousHandler(event: Event): void {
|
|
||||||
const button: HTMLButtonElement = event.currentTarget as HTMLButtonElement;
|
|
||||||
const targetId = button.dataset.target;
|
|
||||||
|
|
||||||
destroy(`/ajax/block_anon/${targetId}`)
|
|
||||||
.then(async response => {
|
|
||||||
if (!response.ok) return;
|
|
||||||
|
|
||||||
const data = await response.json;
|
|
||||||
showNotification(data.message, data.success);
|
|
||||||
button.closest('.list-group-item').remove();
|
|
||||||
})
|
|
||||||
.catch(err => {
|
|
||||||
console.log(err);
|
|
||||||
showErrorNotification(I18n.translate('frontend.error.message'));
|
|
||||||
});
|
|
||||||
}
|
|
|
@ -2,7 +2,6 @@ import registerEvents from "utilities/registerEvents";
|
||||||
import { profileHeaderChangeHandler, profilePictureChangeHandler } from "./crop";
|
import { profileHeaderChangeHandler, profilePictureChangeHandler } from "./crop";
|
||||||
import { themeDocumentHandler, themeSubmitHandler } from "./theme";
|
import { themeDocumentHandler, themeSubmitHandler } from "./theme";
|
||||||
import { userSubmitHandler } from "./password";
|
import { userSubmitHandler } from "./password";
|
||||||
import { unblockAnonymousHandler } from "./block";
|
|
||||||
|
|
||||||
export default (): void => {
|
export default (): void => {
|
||||||
themeDocumentHandler();
|
themeDocumentHandler();
|
||||||
|
@ -11,7 +10,6 @@ export default (): void => {
|
||||||
{ type: 'submit', target: document.querySelector('form.edit_theme, form.new_theme'), handler: themeSubmitHandler },
|
{ type: 'submit', target: document.querySelector('form.edit_theme, form.new_theme'), handler: themeSubmitHandler },
|
||||||
{ type: 'submit', target: document.querySelector('#edit_user'), handler: userSubmitHandler },
|
{ type: 'submit', target: document.querySelector('#edit_user'), handler: userSubmitHandler },
|
||||||
{ type: 'change', target: document.querySelector('#user_profile_picture[type=file]'), handler: profilePictureChangeHandler },
|
{ type: 'change', target: document.querySelector('#user_profile_picture[type=file]'), handler: profilePictureChangeHandler },
|
||||||
{ type: 'change', target: document.querySelector('#user_profile_header[type=file]'), handler: profileHeaderChangeHandler },
|
{ type: 'change', target: document.querySelector('#user_profile_header[type=file]'), handler: profileHeaderChangeHandler }
|
||||||
{ type: 'click', target: document.querySelectorAll('[data-action="anon-unblock"]'), handler: unblockAnonymousHandler }
|
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
18
app/policies/anonymous_block_policy.rb
Normal file
18
app/policies/anonymous_block_policy.rb
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
class AnonymousBlockPolicy
|
||||||
|
attr_reader :user, :anonymous_block
|
||||||
|
|
||||||
|
def initialize(user, anonymous_block)
|
||||||
|
@user = user
|
||||||
|
@anonymous_block = anonymous_block
|
||||||
|
end
|
||||||
|
|
||||||
|
def create_global?
|
||||||
|
user.mod?
|
||||||
|
end
|
||||||
|
|
||||||
|
def destroy?
|
||||||
|
user == anonymous_block.user || user.mod?
|
||||||
|
end
|
||||||
|
end
|
|
@ -8,11 +8,11 @@
|
||||||
%i.fa.fa-fw.fa-exclamation-triangle
|
%i.fa.fa-fw.fa-exclamation-triangle
|
||||||
= t("voc.report")
|
= t("voc.report")
|
||||||
- if question.anonymous? && !question.generated?
|
- if question.anonymous? && !question.generated?
|
||||||
%a.dropdown-item{ name: "ib-block-anon", data: { q_id: question.id } }
|
= button_to anonymous_block_path, method: :post, params: { question: question.id }, class: "dropdown-item" do
|
||||||
%i.fa.fa-fw.fa-minus-circle
|
%i.fa.fa-fw.fa-minus-circle
|
||||||
= t("voc.block")
|
= t("voc.block")
|
||||||
- if current_user.mod?
|
- if current_user.mod?
|
||||||
%a.dropdown-item{ href: "#", name: "mod-block-anon", data: { q_id: question.id } }
|
= button_to anonymous_block_path, method: :post, params: { question: question.id, global: true }, class: "dropdown-item" do
|
||||||
%i.fa.fa-fw.fa-volume-off
|
%i.fa.fa-fw.fa-volume-off
|
||||||
= t("voc.block_site_wide")
|
= t("voc.block_site_wide")
|
||||||
%a.dropdown-item{ href: moderation_questions_path(author_identifier: question.author_identifier) }
|
%a.dropdown-item{ href: moderation_questions_path(author_identifier: question.author_identifier) }
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
.card.inbox-entry{ class: i.new? ? "inbox-entry--new" : "", data: { id: i.id } }
|
.card.inbox-entry{ id: "inbox_#{i.id}", class: i.new? ? "inbox-entry--new" : "", data: { id: i.id } }
|
||||||
.card-header
|
.card-header
|
||||||
.media
|
.media
|
||||||
- unless i.question.author_is_anonymous
|
- unless i.question.author_is_anonymous
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
%li.list-group-item
|
%li.list-group-item{ id: "block_#{block.id}" }
|
||||||
.d-flex
|
.d-flex
|
||||||
%div
|
%div
|
||||||
- if block.question.present?
|
- if block.question.present?
|
||||||
|
@ -7,5 +7,5 @@
|
||||||
%p.mb-0.text-muted.font-italic= t(".deleted_question")
|
%p.mb-0.text-muted.font-italic= t(".deleted_question")
|
||||||
%p.text-muted.mb-0= t(".blocked", time: time_ago_in_words(block.created_at))
|
%p.text-muted.mb-0= t(".blocked", time: time_ago_in_words(block.created_at))
|
||||||
.ml-auto.d-inline-flex
|
.ml-auto.d-inline-flex
|
||||||
%button.btn.btn-default.align-self-center{ data: { action: "anon-unblock", target: block.id } }
|
= button_to anonymous_block_path, method: :delete, params: { id: block.id }, class: "btn btn-default align-self-center" do
|
||||||
%span.pe-none= t("voc.unblock")
|
%span.pe-none= t("voc.unblock")
|
||||||
|
|
|
@ -132,10 +132,10 @@ Rails.application.routes.draw do
|
||||||
post "/list_membership", to: "list#membership", as: :list_membership
|
post "/list_membership", to: "list#membership", as: :list_membership
|
||||||
post "/subscribe", to: "subscription#subscribe", as: :subscribe_answer
|
post "/subscribe", to: "subscription#subscribe", as: :subscribe_answer
|
||||||
post "/unsubscribe", to: "subscription#unsubscribe", as: :unsubscribe_answer
|
post "/unsubscribe", to: "subscription#unsubscribe", as: :unsubscribe_answer
|
||||||
post "/block_anon", to: "anonymous_block#create", as: :block_anon
|
|
||||||
delete "/block_anon/:id", to: "anonymous_block#destroy", as: :unblock_anon
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
resource :anonymous_block, controller: :anonymous_block, only: %i[create destroy]
|
||||||
|
|
||||||
get "/discover", to: "discover#index", as: :discover
|
get "/discover", to: "discover#index", as: :discover
|
||||||
match "/public", to: "timeline#public", via: [:get, :post], as: :public_timeline if APP_CONFIG.dig(:features, :public, :enabled)
|
match "/public", to: "timeline#public", via: [:get, :post], as: :public_timeline if APP_CONFIG.dig(:features, :public, :enabled)
|
||||||
match "/list/:list_name", to: "timeline#list", via: [:get, :post], as: :list_timeline
|
match "/list/:list_name", to: "timeline#list", via: [:get, :post], as: :list_timeline
|
||||||
|
|
|
@ -2,9 +2,9 @@
|
||||||
|
|
||||||
require "rails_helper"
|
require "rails_helper"
|
||||||
|
|
||||||
describe Ajax::AnonymousBlockController, :ajax_controller, type: :controller do
|
describe AnonymousBlockController, type: :controller do
|
||||||
describe "#create" do
|
describe "#create" do
|
||||||
subject { post(:create, params: params) }
|
subject { post(:create, params:) }
|
||||||
|
|
||||||
context "user signed in" do
|
context "user signed in" do
|
||||||
let(:user) { FactoryBot.create(:user) }
|
let(:user) { FactoryBot.create(:user) }
|
||||||
|
@ -20,19 +20,9 @@ describe Ajax::AnonymousBlockController, :ajax_controller, type: :controller do
|
||||||
{ question: question.id }
|
{ question: question.id }
|
||||||
end
|
end
|
||||||
|
|
||||||
let(:expected_response) do
|
|
||||||
{
|
|
||||||
"success" => true,
|
|
||||||
"status" => "okay",
|
|
||||||
"message" => anything
|
|
||||||
}
|
|
||||||
end
|
|
||||||
|
|
||||||
it "creates an anonymous block" do
|
it "creates an anonymous block" do
|
||||||
expect { subject }.to(change { AnonymousBlock.count }.by(1))
|
expect { subject }.to(change { AnonymousBlock.count }.by(1))
|
||||||
end
|
end
|
||||||
|
|
||||||
include_examples "returns the expected response"
|
|
||||||
end
|
end
|
||||||
|
|
||||||
context "when blocking a user globally" do
|
context "when blocking a user globally" do
|
||||||
|
@ -43,14 +33,6 @@ describe Ajax::AnonymousBlockController, :ajax_controller, type: :controller do
|
||||||
end
|
end
|
||||||
|
|
||||||
context "as a moderator" do
|
context "as a moderator" do
|
||||||
let(:expected_response) do
|
|
||||||
{
|
|
||||||
"success" => true,
|
|
||||||
"status" => "okay",
|
|
||||||
"message" => anything
|
|
||||||
}
|
|
||||||
end
|
|
||||||
|
|
||||||
before do
|
before do
|
||||||
user.add_role(:moderator)
|
user.add_role(:moderator)
|
||||||
end
|
end
|
||||||
|
@ -59,48 +41,19 @@ describe Ajax::AnonymousBlockController, :ajax_controller, type: :controller do
|
||||||
expect { subject }.to(change { AnonymousBlock.count }.by(1))
|
expect { subject }.to(change { AnonymousBlock.count }.by(1))
|
||||||
expect(AnonymousBlock.last.user_id).to be_nil
|
expect(AnonymousBlock.last.user_id).to be_nil
|
||||||
end
|
end
|
||||||
|
|
||||||
include_examples "returns the expected response"
|
|
||||||
end
|
end
|
||||||
|
|
||||||
context "as a regular user" do
|
context "as a regular user" do
|
||||||
let(:expected_response) do
|
|
||||||
{
|
|
||||||
"success" => false,
|
|
||||||
"status" => "forbidden",
|
|
||||||
"message" => anything
|
|
||||||
}
|
|
||||||
end
|
|
||||||
|
|
||||||
it "does not create an anonymous block" do
|
it "does not create an anonymous block" do
|
||||||
expect { subject }.not_to(change { AnonymousBlock.count })
|
expect { subject }.to raise_error(Pundit::NotAuthorizedError)
|
||||||
end
|
end
|
||||||
|
|
||||||
include_examples "returns the expected response"
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
context "when parameters are missing" do
|
|
||||||
let(:params) { {} }
|
|
||||||
let(:expected_response) do
|
|
||||||
{
|
|
||||||
"success" => false,
|
|
||||||
"status" => "parameter_error",
|
|
||||||
"message" => anything
|
|
||||||
}
|
|
||||||
end
|
|
||||||
|
|
||||||
it "does not create an anonymous block" do
|
|
||||||
expect { subject }.not_to(change { AnonymousBlock.count })
|
|
||||||
end
|
|
||||||
|
|
||||||
include_examples "returns the expected response"
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "#destroy" do
|
describe "#destroy" do
|
||||||
subject { delete(:destroy, params: params) }
|
subject { delete(:destroy, params:) }
|
||||||
|
|
||||||
context "user signed in" do
|
context "user signed in" do
|
||||||
let(:user) { FactoryBot.create(:user) }
|
let(:user) { FactoryBot.create(:user) }
|
||||||
|
@ -111,20 +64,16 @@ describe Ajax::AnonymousBlockController, :ajax_controller, type: :controller do
|
||||||
|
|
||||||
context "when all parameters are given" do
|
context "when all parameters are given" do
|
||||||
let(:question) { FactoryBot.create(:question, author_identifier: "someidentifier") }
|
let(:question) { FactoryBot.create(:question, author_identifier: "someidentifier") }
|
||||||
let(:block) { AnonymousBlock.create(user: user, identifier: "someidentifier", question: question) }
|
let(:block) { AnonymousBlock.create(user:, identifier: "someidentifier", question:) }
|
||||||
let(:params) do
|
let(:params) do
|
||||||
{ id: block.id }
|
{ id: block.id }
|
||||||
end
|
end
|
||||||
|
|
||||||
let(:expected_response) do
|
it "destroys the anonymous block" do
|
||||||
{
|
subject
|
||||||
"success" => true,
|
|
||||||
"status" => "okay",
|
|
||||||
"message" => anything
|
|
||||||
}
|
|
||||||
end
|
|
||||||
|
|
||||||
include_examples "returns the expected response"
|
expect(AnonymousBlock.exists?(block.id)).to eq(false)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
Loading…
Reference in a new issue