public async Task CanAssign_should_throw_exception_if_contributor_id_is_null()
        {
            var command = new AssignContributor();

            await ValidationAssert.ThrowsAsync(() => GuardAppContributors.CanAssign(command, App(contributors_0), users, appPlan),
                                               new ValidationError("Contributor ID or email is required.", "ContributorId"));
        }
        public async Task CanAssign_should_throw_exception_if_user_not_found()
        {
            var command = new AssignContributor {
                ContributorId = "notfound", Role = Role.Owner
            };

            await Assert.ThrowsAsync <DomainObjectNotFoundException>(() => GuardAppContributors.CanAssign(command, App(contributors_0), users, appPlan));
        }
        public async Task CanAssign_should_throw_exception_if_user_is_actor()
        {
            var command = new AssignContributor {
                ContributorId = "3", Role = Role.Editor, Actor = RefToken.User("3")
            };

            await Assert.ThrowsAsync <DomainForbiddenException>(() => GuardAppContributors.CanAssign(command, App(contributors_0), users, appPlan));
        }
        public async Task CanAssign_should_throw_exception_if_role_not_valid()
        {
            var command = new AssignContributor {
                ContributorId = "1", Role = "Invalid"
            };

            await ValidationAssert.ThrowsAsync(() => GuardAppContributors.CanAssign(command, App(contributors_0), users, appPlan),
                                               new ValidationError("Role is not a valid value.", "Role"));
        }
        public async Task CanAssign_should_not_throw_exception_if_user_already_exists_with_some_role_but_is_from_restore()
        {
            var command = new AssignContributor {
                ContributorId = "1", Role = Role.Owner, Restoring = true
            };

            var contributors_1 = contributors_0.Assign("1", Role.Owner);

            await GuardAppContributors.CanAssign(command, App(contributors_1), users, appPlan);
        }
        public async Task CanAssign_should_not_throw_exception_if_contributor_has_another_role()
        {
            var command = new AssignContributor {
                ContributorId = "1"
            };

            var contributors_1 = contributors_0.Assign("1", Role.Developer);

            await GuardAppContributors.CanAssign(command, App(contributors_1), users, appPlan);
        }
        public async Task CanAssign_should_not_throw_exception_if_user_found()
        {
            A.CallTo(() => appPlan.MaxContributors)
            .Returns(-1);

            var command = new AssignContributor {
                ContributorId = "1"
            };

            await GuardAppContributors.CanAssign(command, App(contributors_0), users, appPlan);
        }
        public async Task CanAssign_should_not_throw_exception_if_contributor_max_reached_but_from_restore()
        {
            A.CallTo(() => appPlan.MaxContributors)
            .Returns(2);

            var command = new AssignContributor {
                ContributorId = "3", Restoring = true
            };

            var contributors_1 = contributors_0.Assign("1", Role.Editor);
            var contributors_2 = contributors_1.Assign("2", Role.Editor);

            await GuardAppContributors.CanAssign(command, App(contributors_2), users, appPlan);
        }
        public async Task CanAssign_should_not_throw_exception_if_contributor_max_reached_but_role_changed()
        {
            A.CallTo(() => appPlan.MaxContributors)
            .Returns(2);

            var command = new AssignContributor {
                ContributorId = "1"
            };

            var contributors_1 = contributors_0.Assign("1", Role.Developer);
            var contributors_2 = contributors_1.Assign("2", Role.Developer);

            await GuardAppContributors.CanAssign(command, App(contributors_2), users, appPlan);
        }
        public async Task CanAssign_should_throw_exception_if_contributor_max_reached()
        {
            A.CallTo(() => appPlan.MaxContributors)
            .Returns(2);

            var command = new AssignContributor {
                ContributorId = "3"
            };

            var contributors_1 = contributors_0.Assign("1", Role.Owner);
            var contributors_2 = contributors_1.Assign("2", Role.Editor);

            await ValidationAssert.ThrowsAsync(() => GuardAppContributors.CanAssign(command, App(contributors_2), users, appPlan),
                                               new ValidationError("You have reached the maximum number of contributors for your plan."));
        }