academia/tests/Application.Tests/Validators/ValidatorTests.cs

323 lines
8.8 KiB
C#
Raw Normal View History

namespace Application.Tests.Validators;
using Application.Enrollments.Commands;
using Application.Students.Commands;
using Domain.Ports.Repositories;
using FluentAssertions;
using FluentValidation.TestHelper;
using NSubstitute;
using Xunit;
public class CreateStudentValidatorTests
{
private readonly IStudentRepository _studentRepository;
private readonly CreateStudentValidator _validator;
public CreateStudentValidatorTests()
{
_studentRepository = Substitute.For<IStudentRepository>();
_studentRepository.EmailExistsAsync(Arg.Any<string>(), Arg.Any<int?>(), Arg.Any<CancellationToken>())
.Returns(false);
_validator = new CreateStudentValidator(_studentRepository);
}
[Fact]
public async Task Validate_WithValidCommand_ShouldNotHaveErrors()
{
// Arrange
var command = new CreateStudentCommand("John Doe", "john@example.com");
// Act
var result = await _validator.TestValidateAsync(command);
// Assert
result.ShouldNotHaveAnyValidationErrors();
}
[Fact]
public async Task Validate_WithEmptyName_ShouldHaveError()
{
// Arrange
var command = new CreateStudentCommand("", "john@example.com");
// Act
var result = await _validator.TestValidateAsync(command);
// Assert
result.ShouldHaveValidationErrorFor(x => x.Name);
}
[Fact]
public async Task Validate_WithEmptyEmail_ShouldHaveError()
{
// Arrange
var command = new CreateStudentCommand("John Doe", "");
// Act
var result = await _validator.TestValidateAsync(command);
// Assert
result.ShouldHaveValidationErrorFor(x => x.Email);
}
[Fact]
public async Task Validate_WithInvalidEmail_ShouldHaveError()
{
// Arrange
var command = new CreateStudentCommand("John Doe", "invalid-email");
// Act
var result = await _validator.TestValidateAsync(command);
// Assert
result.ShouldHaveValidationErrorFor(x => x.Email);
}
[Fact]
public async Task Validate_WithExistingEmail_ShouldHaveError()
{
// Arrange
_studentRepository.EmailExistsAsync("existing@example.com", null, Arg.Any<CancellationToken>())
.Returns(true);
var command = new CreateStudentCommand("John Doe", "existing@example.com");
// Act
var result = await _validator.TestValidateAsync(command);
// Assert
result.ShouldHaveValidationErrorFor(x => x.Email)
.WithErrorMessage("Email already exists");
}
[Fact]
public async Task Validate_WithNameTooLong_ShouldHaveError()
{
// Arrange
var longName = new string('A', 101);
var command = new CreateStudentCommand(longName, "john@example.com");
// Act
var result = await _validator.TestValidateAsync(command);
// Assert
result.ShouldHaveValidationErrorFor(x => x.Name);
}
[Fact]
public async Task Validate_WithNameTooShort_ShouldHaveError()
{
// Arrange
var command = new CreateStudentCommand("AB", "john@example.com");
// Act
var result = await _validator.TestValidateAsync(command);
// Assert
result.ShouldHaveValidationErrorFor(x => x.Name)
.WithErrorMessage("Name must be at least 3 characters");
}
[Theory]
[InlineData("<script>alert('xss')</script>")]
[InlineData("John<img src=x onerror=alert(1)>")]
[InlineData("javascript:alert(1)")]
public async Task Validate_WithDangerousName_ShouldHaveError(string dangerousName)
{
// Arrange
var command = new CreateStudentCommand(dangerousName, "john@example.com");
// Act
var result = await _validator.TestValidateAsync(command);
// Assert
result.ShouldHaveValidationErrorFor(x => x.Name);
}
[Theory]
[InlineData("John123")]
[InlineData("John@Doe")]
[InlineData("John#Doe")]
public async Task Validate_WithInvalidCharactersInName_ShouldHaveError(string invalidName)
{
// Arrange
var command = new CreateStudentCommand(invalidName, "john@example.com");
// Act
var result = await _validator.TestValidateAsync(command);
// Assert
result.ShouldHaveValidationErrorFor(x => x.Name)
.WithErrorMessage("Name contains invalid characters");
}
[Theory]
[InlineData("María García")]
[InlineData("José O'Brien")]
[InlineData("Ana-María López")]
[InlineData("Dr. Juan Pérez")]
public async Task Validate_WithValidSpecialCharactersInName_ShouldPass(string validName)
{
// Arrange
var command = new CreateStudentCommand(validName, "john@example.com");
// Act
var result = await _validator.TestValidateAsync(command);
// Assert
result.ShouldNotHaveValidationErrorFor(x => x.Name);
}
[Fact]
public async Task Validate_WithEmailTooLong_ShouldHaveError()
{
// Arrange
var longEmail = new string('a', 250) + "@example.com";
var command = new CreateStudentCommand("John Doe", longEmail);
// Act
var result = await _validator.TestValidateAsync(command);
// Assert
result.ShouldHaveValidationErrorFor(x => x.Email);
}
}
public class UpdateStudentValidatorTests
{
private readonly IStudentRepository _studentRepository;
private readonly UpdateStudentValidator _validator;
public UpdateStudentValidatorTests()
{
_studentRepository = Substitute.For<IStudentRepository>();
_studentRepository.EmailExistsAsync(Arg.Any<string>(), Arg.Any<int?>(), Arg.Any<CancellationToken>())
.Returns(false);
_validator = new UpdateStudentValidator(_studentRepository);
}
[Fact]
public async Task Validate_WithValidCommand_ShouldNotHaveErrors()
{
// Arrange
var command = new UpdateStudentCommand(1, "John Doe", "john@example.com");
// Act
var result = await _validator.TestValidateAsync(command);
// Assert
result.ShouldNotHaveAnyValidationErrors();
}
[Fact]
public async Task Validate_WithInvalidId_ShouldHaveError()
{
// Arrange
var command = new UpdateStudentCommand(0, "John Doe", "john@example.com");
// Act
var result = await _validator.TestValidateAsync(command);
// Assert
result.ShouldHaveValidationErrorFor(x => x.Id);
}
[Fact]
public async Task Validate_WithNegativeId_ShouldHaveError()
{
// Arrange
var command = new UpdateStudentCommand(-1, "John Doe", "john@example.com");
// Act
var result = await _validator.TestValidateAsync(command);
// Assert
result.ShouldHaveValidationErrorFor(x => x.Id);
}
}
public class EnrollStudentValidatorTests
{
private readonly EnrollStudentValidator _validator;
public EnrollStudentValidatorTests()
{
_validator = new EnrollStudentValidator();
}
[Fact]
public async Task Validate_WithValidCommand_ShouldNotHaveErrors()
{
// Arrange
var command = new EnrollStudentCommand(1, 1);
// Act
var result = await _validator.TestValidateAsync(command);
// Assert
result.ShouldNotHaveAnyValidationErrors();
}
[Fact]
public async Task Validate_WithInvalidStudentId_ShouldHaveError()
{
// Arrange
var command = new EnrollStudentCommand(0, 1);
// Act
var result = await _validator.TestValidateAsync(command);
// Assert
result.ShouldHaveValidationErrorFor(x => x.StudentId);
}
[Fact]
public async Task Validate_WithInvalidSubjectId_ShouldHaveError()
{
// Arrange
var command = new EnrollStudentCommand(1, 0);
// Act
var result = await _validator.TestValidateAsync(command);
// Assert
result.ShouldHaveValidationErrorFor(x => x.SubjectId);
}
}
public class UnenrollStudentValidatorTests
{
private readonly UnenrollStudentValidator _validator;
public UnenrollStudentValidatorTests()
{
_validator = new UnenrollStudentValidator();
}
[Fact]
public async Task Validate_WithValidCommand_ShouldNotHaveErrors()
{
// Arrange
var command = new UnenrollStudentCommand(1);
// Act
var result = await _validator.TestValidateAsync(command);
// Assert
result.ShouldNotHaveAnyValidationErrors();
}
[Fact]
public async Task Validate_WithInvalidEnrollmentId_ShouldHaveError()
{
// Arrange
var command = new UnenrollStudentCommand(0);
// Act
var result = await _validator.TestValidateAsync(command);
// Assert
result.ShouldHaveValidationErrorFor(x => x.EnrollmentId);
}
}