diff --git a/app/models/assignment.rb b/app/models/assignment.rb index f60eb974d..02f81bc25 100644 --- a/app/models/assignment.rb +++ b/app/models/assignment.rb @@ -1,7 +1,18 @@ class Assignment < ApplicationRecord + LIMIT = 10 + belongs_to :account, default: -> { card.account } belongs_to :card, touch: true belongs_to :assignee, class_name: "User" belongs_to :assigner, class_name: "User" + + validate :within_limit, on: :create + + private + def within_limit + if card.assignments.count >= LIMIT + errors.add(:base, "Card already has the maximum of #{LIMIT} assignees") + end + end end diff --git a/app/models/card/assignable.rb b/app/models/card/assignable.rb index be0dd257e..6320faeb3 100644 --- a/app/models/card/assignable.rb +++ b/app/models/card/assignable.rb @@ -24,10 +24,12 @@ module Card::Assignable private def assign(user) - assignments.create! assignee: user, assigner: Current.user - watch_by user + assignment = assignments.create assignee: user, assigner: Current.user - track_event :assigned, assignee_ids: [ user.id ] + if assignment.persisted? + watch_by user + track_event :assigned, assignee_ids: [ user.id ] + end rescue ActiveRecord::RecordNotUnique # Already assigned end diff --git a/test/models/assignment_test.rb b/test/models/assignment_test.rb index ca8f09a34..3ac309619 100644 --- a/test/models/assignment_test.rb +++ b/test/models/assignment_test.rb @@ -1,7 +1,38 @@ require "test_helper" class AssignmentTest < ActiveSupport::TestCase - # test "the truth" do - # assert true - # end + test "create" do + card = cards(:text) + assignment = card.assignments.create!(assignee: users(:david), assigner: users(:jason)) + + assert_equal users(:david), assignment.assignee + assert_equal users(:jason), assignment.assigner + assert_equal card, assignment.card + end + + test "create cannot exceed assignee limit" do + card = cards(:logo) + board = card.board + account = card.account + + card.assignments.delete_all + + Assignment::LIMIT.times do |i| + identity = Identity.create!(email_address: "limit_test_#{i}@example.com") + user = account.users.create!(identity: identity, name: "Limit Test User #{i}", role: :member) + user.accesses.find_or_create_by!(board: board) + card.assignments.create!(assignee: user, assigner: users(:david)) + end + + assert_equal Assignment::LIMIT, card.assignments.count + + identity = Identity.create!(email_address: "over_limit@example.com") + extra_user = account.users.create!(identity: identity, name: "Over Limit User", role: :member) + extra_user.accesses.find_or_create_by!(board: board) + + assignment = card.assignments.build(assignee: extra_user, assigner: users(:david)) + + assert_not assignment.valid? + assert_includes assignment.errors[:base], "Card already has the maximum of #{Assignment::LIMIT} assignees" + end end diff --git a/test/models/card/assignable_test.rb b/test/models/card/assignable_test.rb index 9d0c1f1c5..6ee8a164d 100644 --- a/test/models/card/assignable_test.rb +++ b/test/models/card/assignable_test.rb @@ -12,4 +12,31 @@ class Card::AssignableTest < ActiveSupport::TestCase assert cards(:layout).assigned_to?(users(:kevin)) assert cards(:layout).watched_by?(users(:kevin)) end + + test "toggle_assignment does not add assignee when at limit" do + card = cards(:logo) + board = card.board + account = card.account + + card.assignments.delete_all + + Assignment::LIMIT.times do |i| + identity = Identity.create!(email_address: "toggle_test_#{i}@example.com") + user = account.users.create!(identity: identity, name: "Toggle Test User #{i}", role: :member) + user.accesses.find_or_create_by!(board: board) + card.assignments.create!(assignee: user, assigner: users(:david)) + end + + identity = Identity.create!(email_address: "toggle_over@example.com") + extra_user = account.users.create!(identity: identity, name: "Toggle Over User", role: :member) + extra_user.accesses.find_or_create_by!(board: board) + + with_current_user(:david) do + assert_no_difference "card.assignments.count" do + card.toggle_assignment(extra_user) + end + end + + assert_not card.reload.assigned_to?(extra_user) + end end