docbrown/spec/services/reaction_handler_spec.rb
Joshua Wehner 2ff67bda24
Try an idempotentish reaction create API (#18377)
* Try an idempotentish reaction create API

* Add tests for create API endpoint

* Try -> ReactionHandler

* Fix existing tests first

* Tests for .toggle; fix broken handle_existing

* Use the Handler

* Tweak http status for reaction create

* Use the category reader

Co-authored-by: Ridhwana <Ridhwana.Khan16@gmail.com>

Co-authored-by: Ridhwana <Ridhwana.Khan16@gmail.com>
2022-08-30 16:43:18 +02:00

113 lines
3.4 KiB
Ruby

require "rails_helper"
RSpec.describe ReactionHandler, type: :service do
# existing reaction by other user
# existing reaction by same user, other category
# no existing reaction = create
# existing reaction = no-op
# existing contradictory mod reaction
let(:user) { create :user }
let(:article) { create :article }
let(:category) { "like" }
let!(:other_category) { article.reactions.create! user: user, category: "hands" }
let!(:other_existing) { article.reactions.create! user: create(:user), category: "like" }
let(:moderator) { create :user, :trusted }
let!(:contradictory_mod) { article.reactions.create! user: moderator, category: "thumbsup" }
let(:params) do
{
reactable_id: article.id,
reactable_type: article.class.polymorphic_name,
category: category
}
end
describe "#create" do
subject(:result) { described_class.new(params, current_user: user).create }
context "when no existing/matching reaction by user" do
it "justs create" do
expect(result).to be_success
expect(result.action).to eq("create")
end
it "ignores other existing reactions" do
expect(Reaction.ids).to include(other_category.id, other_existing.id, contradictory_mod.id)
end
end
context "when there's an existing/matching reaction by user" do
let!(:existing) { article.reactions.create! user: user, category: "like" }
it "does nothing" do
expect(result).to be_success
expect(result.action).to eq("none")
end
it "ignores other existing reactions" do
expect(Reaction.ids).to include(other_category.id, other_existing.id, contradictory_mod.id, existing.id)
end
end
context "when there's an existing, contradictory mod reaction" do
let(:user) { moderator }
let(:category) { "vomit" }
it "creates" do
expect(result).to be_success
expect(result.action).to eq("create")
end
it "destroys the other reaction as a side-effect" do
expect(result).to be_success
expect(Reaction.ids).not_to include(contradictory_mod.id)
end
end
end
describe "#toggle" do
subject(:result) { described_class.new(params, current_user: user).toggle }
context "when no existing/matching reaction by user" do
it "justs create" do
expect(result).to be_success
expect(result.action).to eq("create")
end
it "ignores other existing reactions" do
expect(Reaction.ids).to include(other_category.id, other_existing.id, contradictory_mod.id)
end
end
context "when there's an existing/matching reaction by user" do
let!(:existing) { article.reactions.create! user: user, category: "like" }
it "un-likes" do
expect(result).to be_success
expect(result.action).to eq("destroy")
end
it "ignores other existing reactions" do
expect(Reaction.ids).to include(other_category.id, other_existing.id, contradictory_mod.id, existing.id)
end
end
context "when there's an existing, contradictory mod reaction" do
let(:user) { moderator }
let(:category) { "vomit" }
it "creates" do
expect(result).to be_success
expect(result.action).to eq("create")
end
it "destroys the other reaction as a side-effect" do
expect(result).to be_success
expect(Reaction.ids).not_to include(contradictory_mod.id)
end
end
end
end