discourse-assign/spec/models/assignment_spec.rb

252 lines
7.6 KiB
Ruby

# frozen_string_literal: true
require "rails_helper"
RSpec.describe Assignment do
before { SiteSetting.assign_enabled = true }
describe ".active_for_group" do
subject(:assignments) { described_class.active_for_group(group) }
let!(:group) { Fabricate(:group) }
let!(:user1) { Fabricate(:user) }
let!(:user2) { Fabricate(:user) }
let!(:group_user1) { Fabricate(:group_user, user: user1, group: group) }
let!(:group_user2) { Fabricate(:group_user, user: user2, group: group) }
let!(:wrong_group) { Fabricate(:group) }
let!(:assignment1) { Fabricate(:topic_assignment, assigned_to: group) }
let!(:assignment2) { Fabricate(:post_assignment, assigned_to: group) }
before do
Fabricate(:post_assignment, assigned_to: group, active: false)
Fabricate(:post_assignment, assigned_to: user1)
Fabricate(:topic_assignment, assigned_to: wrong_group)
end
it "returns active assignments for the group" do
expect(assignments).to contain_exactly(assignment1, assignment2)
end
end
describe ".deactivate!" do
subject(:deactivate!) { described_class.deactivate!(topic: topic) }
let!(:assignment1) { Fabricate(:topic_assignment) }
let!(:assignment2) { Fabricate(:post_assignment, topic: topic) }
let!(:assignment3) { Fabricate(:post_assignment) }
let(:topic) { assignment1.topic }
it "deactivates each assignment of the provided topic" do
deactivate!
expect([assignment1, assignment2].map(&:reload).map(&:active?)).to all eq false
expect(assignment3.reload).to be_active
end
end
describe ".reactivate!" do
subject(:reactivate!) { described_class.reactivate!(topic: topic) }
let!(:assignment1) { Fabricate(:topic_assignment, active: false) }
let!(:assignment2) { Fabricate(:post_assignment, topic: topic, active: false) }
let!(:assignment3) { Fabricate(:post_assignment, active: false) }
let(:topic) { assignment1.topic }
it "reactivates each assignment of the provided topic" do
reactivate!
expect([assignment1, assignment2].map(&:reload)).to all be_active
expect(assignment3.reload).not_to be_active
end
end
describe "#assigned_users" do
subject(:assigned_users) { assignment.assigned_users }
let(:assignment) { Fabricate.build(:topic_assignment, assigned_to: assigned_to) }
context "when assigned to a group" do
let(:assigned_to) { Fabricate.build(:group) }
context "when group is empty" do
it "returns an empty collection" do
expect(assigned_users).to be_empty
end
end
context "when group is not empty" do
before { assigned_to.users = Fabricate.build_times(2, :user) }
it "returns users from that group" do
expect(assigned_users).to eq(assigned_to.users)
end
end
end
context "when assigned to a user" do
let(:assigned_to) { Fabricate.build(:user) }
it "returns that user" do
expect(assigned_users).to eq([assigned_to])
end
end
end
describe "#post" do
subject(:post) { assignment.post }
context "when target is a topic" do
let!(:initial_post) { Fabricate(:post) }
let(:assignment) { Fabricate.build(:topic_assignment, topic: target) }
let(:target) { initial_post.topic }
it "returns the first post of that topic" do
expect(post).to eq(initial_post)
end
end
context "when target is a post" do
let(:assignment) { Fabricate.build(:post_assignment) }
it "returns that post" do
expect(post).to eq(assignment.target)
end
end
end
describe "#create_missing_notifications!" do
subject(:create_missing_notifications) { assignment.create_missing_notifications! }
let(:assignment) do
Fabricate(:topic_assignment, assigned_to: assigned_to, assigned_by_user: assigned_by_user)
end
let(:assigned_by_user) { Fabricate(:user) }
context "when assigned to a user" do
let(:assigned_to) { Fabricate(:user) }
context "when notification already exists for that user" do
before do
Fabricate(
:notification,
notification_type: Notification.types[:assigned],
user: assigned_to,
data: { assignment_id: assignment.id }.to_json,
)
end
it "does nothing" do
DiscourseAssign::CreateNotification.expects(:call).never
create_missing_notifications
end
end
context "when notification does not exist yet" do
context "when user is the one that assigned" do
let(:assigned_by_user) { assigned_to }
it "creates the missing notification" do
DiscourseAssign::CreateNotification.expects(:call).with(
assignment: assignment,
user: assigned_to,
mark_as_read: true,
)
create_missing_notifications
end
end
context "when user is not the one that assigned" do
it "creates the missing notification" do
DiscourseAssign::CreateNotification.expects(:call).with(
assignment: assignment,
user: assigned_to,
mark_as_read: false,
)
create_missing_notifications
end
end
end
end
context "when assigned to a group" do
let(:assigned_to) { Fabricate(:group) }
let(:users) { Fabricate.times(3, :user) }
let(:assigned_by_user) { users.last }
before do
assigned_to.users = users
Fabricate(
:notification,
notification_type: Notification.types[:assigned],
user: users.first,
data: { assignment_id: assignment.id }.to_json,
)
end
it "creates missing notifications for group users" do
DiscourseAssign::CreateNotification
.expects(:call)
.with(assignment: assignment, user: users.first, mark_as_read: false)
.never
DiscourseAssign::CreateNotification.expects(:call).with(
assignment: assignment,
user: users.second,
mark_as_read: false,
)
DiscourseAssign::CreateNotification.expects(:call).with(
assignment: assignment,
user: users.last,
mark_as_read: true,
)
create_missing_notifications
end
end
end
describe "#reactivate!" do
subject(:reactivate!) { assignment.reactivate! }
fab!(:assignment) { Fabricate.create(:topic_assignment, active: false) }
context "when target does not exist" do
before { assignment.target.delete }
it "does nothing" do
expect { reactivate! }.not_to change { assignment.reload.active }
end
end
context "when target exists" do
it "sets the assignment as active" do
expect { reactivate! }.to change { assignment.reload.active? }.to true
end
it "enqueues a job to create notifications" do
reactivate!
expect_job_enqueued(job: Jobs::AssignNotification, args: { assignment_id: assignment.id })
end
end
end
describe "#deactivate!" do
subject(:deactivate!) { assignment.deactivate! }
fab!(:assignment) { Fabricate.create(:topic_assignment) }
it "sets the assignment as inactive" do
expect { deactivate! }.to change { assignment.reload.active? }.to false
end
it "enqueues a job to delete notifications" do
deactivate!
expect_job_enqueued(
job: Jobs::UnassignNotification,
args: {
topic_id: assignment.topic_id,
assigned_to_id: assignment.assigned_to_id,
assigned_to_type: assignment.assigned_to_type,
assignment_id: assignment.id,
},
)
end
end
end