public void Should_be_successful_when_isAuthenticated_is_true_and_user_has_at_least_one_matching_role()
        {
            // Arrange
            var requiredRoles = new List<object> {
                UserRole.Writer,
                UserRole.Publisher
            };

            var policy = new RequireRolePolicy(requiredRoles.ToArray());

            const bool authenticated = true;
            var roles = new List<object> {
                UserRole.Writer
            };
            var context = TestDataFactory.CreateSecurityContext(authenticated, roles.ToArray());

            // Act
            var result = policy.Enforce(context);

            // Assert
            Assert.That(result.ViolationOccured, Is.False);
        }
        public void Should_not_be_successful_when_isAuthenticated_is_false()
        {
            // Arrange
            var policy = new RequireRolePolicy(new object[1]);
            const bool authenticated = false;
            var context = TestDataFactory.CreateSecurityContext(authenticated);

            // Act
            var result = policy.Enforce(context);

            // Assert
            Assert.That(result.ViolationOccured, Is.True);
            Assert.That(result.Message, Is.EqualTo("Anonymous access denied"));
        }
        public void Should_not_be_successful_when_isAuthenticated_is_true_and_roles_are_does_not_match()
        {
            // Arrange
            var policy = new RequireRolePolicy("Role1", "Role2");
            const bool authenticated = true;
            var roles = new List<object> { "Role3", "Role4" }.ToArray();
            var context = TestDataFactory.CreateSecurityContext(authenticated, roles);

            // Act
            var result = policy.Enforce(context);

            // Assert
            Assert.That(result.ViolationOccured, Is.True);
            Assert.That(result.Message, Is.EqualTo("Access requires one of the following roles: Role1 or Role2."));
        }
        public void Should_not_be_successful_when_isAuthenticated_is_true_and_roles_are_null()
        {
            // Arrange
            var policy = new RequireRolePolicy(new object[1]);
            const bool authenticated = true;
            IEnumerable<object> roles = null;
            var context = TestDataFactory.CreateSecurityContext(authenticated, roles);

            // Act
            var result = policy.Enforce(context);

            // Assert
            Assert.That(result.ViolationOccured, Is.True);
            Assert.That(result.Message, Is.EqualTo("Access denied"));
        }
        public void Should_resolve_authentication_status_and_roles_exactly_once()
        {
            // Arrange
            var roles = new object[1];
            var policy = new RequireRolePolicy(roles);
            var context = new Mock<ISecurityContext>();
            context.Setup(x => x.CurrentUserIsAuthenticated()).Returns(true);
            context.Setup(x => x.CurrentUserRoles()).Returns(roles);

            // Act
            var result = policy.Enforce(context.Object);

            // Assert
            Assert.That(result.ViolationOccured, Is.False);
            context.Verify(x => x.CurrentUserIsAuthenticated(), Times.Exactly(1), "The authentication status should be resolved at most once.");
            context.Verify(x => x.CurrentUserRoles(), Times.Exactly(1), "The roles should be resolved at most once.");
        }