Add tests for question create use case

This commit is contained in:
Karina Kwiatek 2022-07-08 20:40:32 +02:00 committed by Karina Kwiatek
parent 58b212f76d
commit 5d542161a0
3 changed files with 171 additions and 3 deletions

View File

@ -5,7 +5,7 @@ class Question < ApplicationRecord
has_many :answers, dependent: :destroy
has_many :inboxes, dependent: :destroy
validates :content, length: { maximum: 512 }
validates :content, length: { minimum: 1, maximum: 512 }
before_destroy do
rep = Report.where(target_id: self.id, type: 'Reports::Question')

View File

@ -23,10 +23,10 @@ module UseCase
user: source_user_id.nil? ? nil : source_user
)
increment_asked_count
return if filtered?(question)
increment_asked_count
inbox = ::Inbox.create!(user: target_user, question: question, new: true)
{
@ -62,6 +62,7 @@ module UseCase
end
source_user.increment(:asked_count)
source_user.save
end
def filtered?(question)

View File

@ -0,0 +1,167 @@
# frozen_string_literal: true
require "rails_helper"
require "errors"
require "use_case/question/create"
describe UseCase::Question::Create do
subject do
UseCase::Question::Create.call(
source_user_id: source_user&.id,
target_user_id: target_user.id,
content: content,
anonymous: anonymous,
author_identifier: author_identifier
)
end
shared_examples "creates the question" do |should_send_to_inbox = true|
it "creates the question" do
expect { subject }.to change { Question.count }.by(1)
question = Question.last
expect(question.content).to eq(content)
expect(question.author_is_anonymous).to eq(anonymous)
expect(question.author_identifier).to eq(author_identifier)
if should_send_to_inbox
expect(target_user.inboxes.first.question_id).to eq(question.id)
else
expect(target_user.inboxes.first).to be_nil
end
end
end
shared_examples "invalid params" do
it "raises an error" do
expect { subject }.to raise_error(Errors::BadRequest)
end
end
shared_examples "forbidden" do
it "raises an error" do
expect { subject }.to raise_error(Errors::Forbidden)
end
end
shared_examples "validates content" do
context "content is empty" do
let(:content) { "" }
it "raises an error" do
expect { subject }.to raise_error(ActiveRecord::RecordInvalid)
end
end
context "content is too long" do
let(:content) { "a" * 513 }
it "raises an error" do
expect { subject }.to raise_error(ActiveRecord::RecordInvalid)
end
end
end
shared_examples "filters questions" do
context "user blocks this anon" do
before do
target_user.anonymous_blocks.create!(
identifier: author_identifier,
question_id: FactoryBot.create(:question).id
)
end
it_behaves_like "creates the question", false
end
context "user mutes a term used in the question" do
before { target_user.mute_rules.create!(muted_phrase: "hello") }
it_behaves_like "creates the question", false
end
end
context "user signed in" do
let!(:source_user) { FactoryBot.create(:user) }
context "target user exists" do
let(:target_user) { FactoryBot.create(:user, privacy_allow_anonymous_questions: allow_anon) }
let(:allow_anon) { true }
context "content is not empty" do
let(:content) { "Hello world" }
context "question is anonymous" do
let(:anonymous) { true }
let(:author_identifier) { "abcdef" }
context "recipient allows anonymous questions" do
it_behaves_like "filters questions"
it_behaves_like "creates the question"
it_behaves_like "validates content"
it "doesn't increment the source user's asked count" do
expect { subject }.not_to(change { source_user.reload.asked_count })
end
end
context "recipient does not allow anonymous questions" do
let(:allow_anon) { false }
it_behaves_like "forbidden"
end
end
context "question is not anonymous" do
let(:anonymous) { false }
let(:author_identifier) { "qwerty" }
it_behaves_like "creates the question"
it_behaves_like "validates content"
it "increments the source user's asked count" do
expect { subject }.to change { source_user.reload.asked_count }.by(1)
end
end
end
end
end
context "user not signed in" do
let!(:source_user) { nil }
context "target user exists" do
let(:target_user) { FactoryBot.create(:user, privacy_allow_anonymous_questions: allow_anon) }
context "content is not empty" do
let(:content) { "Hello world" }
context "question is anonymous" do
let(:anonymous) { true }
let(:author_identifier) { "abcdef" }
context "recipient allows anonymous questions" do
let(:allow_anon) { true }
it_behaves_like "filters questions"
it_behaves_like "creates the question"
it_behaves_like "validates content"
end
context "recipient does not allow anonymous questions" do
let(:allow_anon) { false }
it_behaves_like "forbidden"
end
end
context "question is not anonymous" do
let(:allow_anon) { true } # irrelevant for this test, but needs to be set
let(:anonymous) { false }
let(:author_identifier) { "qwerty" }
it_behaves_like "invalid params"
end
end
end
end
end