diff --git a/SchengenVisaApi/VisaApiTests/Fakers/Applicants/Requests/NameModelFaker.cs b/SchengenVisaApi/VisaApiTests/Fakers/Applicants/Requests/NameModelFaker.cs new file mode 100644 index 0000000..31d476d --- /dev/null +++ b/SchengenVisaApi/VisaApiTests/Fakers/Applicants/Requests/NameModelFaker.cs @@ -0,0 +1,17 @@ +using ApplicationLayer.Services.Applicants.Models; +using Bogus; + +namespace VisaApi.Fakers.Applicants.Requests +{ + public sealed class NameModelFaker : Faker + { + public NameModelFaker() + { + RuleFor(m => m.FirstName, f => f.Name.FirstName()); + + RuleFor(m => m.Surname, f => f.Name.LastName()); + + RuleFor(m => m.Patronymic, f => f.Name.FirstName()); + } + } +} diff --git a/SchengenVisaApi/VisaApiTests/Fakers/Auth/AuthDataFaker.cs b/SchengenVisaApi/VisaApiTests/Fakers/Auth/AuthDataFaker.cs new file mode 100644 index 0000000..2309f79 --- /dev/null +++ b/SchengenVisaApi/VisaApiTests/Fakers/Auth/AuthDataFaker.cs @@ -0,0 +1,15 @@ +using ApplicationLayer.Services.AuthServices.Common; +using Bogus; + +namespace VisaApi.Fakers.Auth +{ + public sealed class AuthDataFaker : Faker + { + public AuthDataFaker() + { + RuleFor(a => a.Email, f => f.Internet.Email()); + + RuleFor(a => a.Password, f => f.Internet.Password()); + } + } +} diff --git a/SchengenVisaApi/VisaApiTests/Fakers/Auth/RegisterRequestFaker.cs b/SchengenVisaApi/VisaApiTests/Fakers/Auth/RegisterRequestFaker.cs new file mode 100644 index 0000000..2835c35 --- /dev/null +++ b/SchengenVisaApi/VisaApiTests/Fakers/Auth/RegisterRequestFaker.cs @@ -0,0 +1,15 @@ +using ApplicationLayer.Services.AuthServices.Requests; +using Bogus; + +namespace VisaApi.Fakers.Auth +{ + public sealed class RegisterRequestFaker : Faker + { + private static AuthDataFaker authDataFaker = new(); + + public RegisterRequestFaker() + { + RuleFor(r => r.AuthData, () => authDataFaker.Generate()); + } + } +} diff --git a/SchengenVisaApi/VisaApiTests/Tests/Application/Validation/Applicants/NameValidatorTests.cs b/SchengenVisaApi/VisaApiTests/Tests/Application/Validation/Applicants/NameValidatorTests.cs new file mode 100644 index 0000000..2f91c47 --- /dev/null +++ b/SchengenVisaApi/VisaApiTests/Tests/Application/Validation/Applicants/NameValidatorTests.cs @@ -0,0 +1,171 @@ +using System.Text; +using ApplicationLayer.Services.Applicants.Models; +using ApplicationLayer.Services.Applicants.Models.Validation; +using Domains; +using FluentAssertions; +using FluentValidation; +using VisaApi.Fakers.Applicants.Requests; +using Xunit; + +namespace VisaApi.Tests.Application.Validation.Applicants +{ + public class NameValidatorTests + { + private static IValidator validator = new NameModelValidator(); + private static NameModelFaker faker = new(); + + /// + /// Test for validator that should throw for empty first name + /// + [Fact] + private async Task ValidateForEmptyFirstNameShouldThrow() + { + var name = faker.Generate(); + name.FirstName = null!; + + var result = await validator.ValidateAsync(name); + + result.Errors.Where(error => error.PropertyName == nameof(name.FirstName)) + .Should().HaveCount(1); + } + + /// + /// Test for validator that should throw for empty surname + /// + [Fact] + private async Task ValidateForEmptySurnameShouldThrow() + { + var name = faker.Generate(); + name.Surname = null!; + + var result = await validator.ValidateAsync(name); + + result.Errors.Where(error => error.PropertyName == nameof(name.Surname)) + .Should().HaveCount(1); + } + + /// + /// Test for validator that should return no errors for empty patronymic + /// + [Fact] + private async Task ValidateForEmptyPatronymicShouldReturnNoErrors() + { + var name = faker.Generate(); + name.Patronymic = null; + + var result = await validator.ValidateAsync(name); + + result.Errors.Where(error => error.PropertyName == nameof(name.Patronymic)) + .Should().BeEmpty(); + } + + /// + /// Test for validator that should return error for too long first name + /// + [Fact] + private async Task ValidateForLongFirstNameShouldReturnError() + { + var name = faker.Generate(); + var stringBuilder = new StringBuilder(); + stringBuilder.Append('h', ConfigurationConstraints.NameLength + 1); + name.FirstName = stringBuilder.ToString(); + + var result = await validator.ValidateAsync(name); + + result.Errors.Where(error => error.PropertyName == nameof(name.FirstName)) + .Should().HaveCount(1); + } + + /// + /// Test for validator that should return error for too long surname + /// + [Fact] + private async Task ValidateForLongSurnameShouldReturnError() + { + var name = faker.Generate(); + var stringBuilder = new StringBuilder(); + stringBuilder.Append('h', ConfigurationConstraints.NameLength + 1); + name.Surname = stringBuilder.ToString(); + + var result = await validator.ValidateAsync(name); + + result.Errors.Where(error => error.PropertyName == nameof(name.Surname)) + .Should().HaveCount(1); + } + + /// + /// Test for validator that should return error for too long patronymic + /// + [Fact] + private async Task ValidateForLongPatronymicShouldReturnError() + { + var name = faker.Generate(); + var stringBuilder = new StringBuilder(); + stringBuilder.Append('h', ConfigurationConstraints.NameLength + 1); + name.Patronymic = stringBuilder.ToString(); + + var result = await validator.ValidateAsync(name); + + result.Errors.Where(error => error.PropertyName == nameof(name.Patronymic)) + .Should().HaveCount(1); + } + + /// + /// Test for validator that should return error for not valid firstname + /// + [Fact] + private async Task ValidateForNotValidFirstNameShouldReturnError() + { + var name = faker.Generate(); + name.FirstName = "&&7!**|"; + + var result = await validator.ValidateAsync(name); + + result.Errors.Where(error => error.PropertyName == nameof(name.FirstName)) + .Should().HaveCount(1); + } + + /// + /// Test for validator that should return error for not valid surname + /// + [Fact] + private async Task ValidateForNotValidSurnameShouldReturnError() + { + var name = faker.Generate(); + name.Surname = "&&7!**|"; + + var result = await validator.ValidateAsync(name); + + result.Errors.Where(error => error.PropertyName == nameof(name.Surname)) + .Should().HaveCount(1); + } + + /// + /// Test for validator that should return error for not valid patronymic + /// + [Fact] + private async Task ValidateForNotValidPatronymicShouldReturnError() + { + var name = faker.Generate(); + name.Patronymic = "&&7!**|"; + + var result = await validator.ValidateAsync(name); + + result.Errors.Where(error => error.PropertyName == nameof(name.Patronymic)) + .Should().HaveCount(1); + } + + /// + /// Test for validator that should return no errors for valid name + /// + [Fact] + private async Task ValidateForValidNameShouldReturnNoErrors() + { + var name = faker.Generate(); + + var result = await validator.ValidateAsync(name); + + result.Errors.Should().BeEmpty(); + } + } +} diff --git a/SchengenVisaApi/VisaApiTests/Tests/Application/Validation/Auth/AuthDataValidatorTests.cs b/SchengenVisaApi/VisaApiTests/Tests/Application/Validation/Auth/AuthDataValidatorTests.cs new file mode 100644 index 0000000..0356f0a --- /dev/null +++ b/SchengenVisaApi/VisaApiTests/Tests/Application/Validation/Auth/AuthDataValidatorTests.cs @@ -0,0 +1,114 @@ +using System.Text; +using ApplicationLayer.Services.AuthServices.Common; +using ApplicationLayer.Services.AuthServices.Requests.Validation; +using Domains; +using FluentAssertions; +using FluentValidation; +using VisaApi.Fakers.Auth; +using Xunit; + +namespace VisaApi.Tests.Application.Validation.Auth +{ + public class AuthDataValidatorTests + { + private readonly static IValidator validator = new AuthDataValidator(); + private readonly static AuthDataFaker faker = new(); + + /// + /// Test for validator that should return validation error for invalid email + /// + [Fact] + private async Task ValidateForInvalidEmailShouldReturnError() + { + var authData = faker.Generate(); + authData.Email = "alsdas'dsa"; + + var result = await validator.ValidateAsync(authData); + + result.Errors.Should() + .HaveCount(1) + .And.Contain(error => error.PropertyName == nameof(authData.Email)); + } + + /// + /// Test for validator that should return validation error for too long email + /// + [Fact] + private async Task ValidateForLongEmailShouldReturnError() + { + var authData = faker.Generate(); + var stringBuilder = new StringBuilder(); + stringBuilder.Append('d', ConfigurationConstraints.EmailLength); + stringBuilder.Append("@mail.ru"); + authData.Email = stringBuilder.ToString(); + + var result = await validator.ValidateAsync(authData); + + result.Errors.Should() + .HaveCount(1) + .And.Contain(error => error.PropertyName == nameof(authData.Email)); + } + + /// + /// Test for validator that should return no errors for valid email + /// + [Fact] + private async Task ValidateForValidEmailShouldReturnNoError() + { + var authData = faker.Generate(); + + var result = await validator.ValidateAsync(authData); + + result.Errors.Where(error => error.PropertyName == nameof(authData.Email)) + .Should().BeEmpty(); + } + + /// + /// Test for validator that should return validation error for empty password + /// + [Fact] + private async Task ValidateForEmptyPasswordShouldReturnError() + { + var authData = faker.Generate(); + authData.Password = string.Empty; + + var result = await validator.ValidateAsync(authData); + + result.Errors.Should() + .HaveCount(1) + .And.Contain(error => error.PropertyName == nameof(authData.Password)); + } + + /// + /// Test for validator that should return validation error for too long password + /// + [Fact] + private async Task ValidateForLongPasswordShouldReturnError() + { + var authData = faker.Generate(); + var stringBuilder = new StringBuilder(); + stringBuilder.Append('d', ConfigurationConstraints.PasswordLength + 1); + authData.Password = stringBuilder.ToString(); + + var result = await validator.ValidateAsync(authData); + + result.Errors.Should() + .HaveCount(1) + .And.Contain(error => error.PropertyName == nameof(authData.Password)); + } + + /// + /// Test for validator that should return no errors for valid password + /// + [Fact] + private async Task ValidateForValidPasswordShouldReturnNoError() + { + var authData = faker.Generate(); + + var result = await validator.ValidateAsync(authData); + + result.Errors.Where(error => error.PropertyName == nameof(authData.Password)) + .Should().BeEmpty(); + } + } +} diff --git a/SchengenVisaApi/VisaApiTests/Tests/Application/Validation/Auth/RegisterRequestValidatorTests.cs b/SchengenVisaApi/VisaApiTests/Tests/Application/Validation/Auth/RegisterRequestValidatorTests.cs new file mode 100644 index 0000000..eb3eae1 --- /dev/null +++ b/SchengenVisaApi/VisaApiTests/Tests/Application/Validation/Auth/RegisterRequestValidatorTests.cs @@ -0,0 +1,94 @@ +using ApplicationLayer.InfrastructureServicesInterfaces; +using ApplicationLayer.Services.AuthServices.Common; +using ApplicationLayer.Services.AuthServices.Requests; +using ApplicationLayer.Services.AuthServices.Requests.Validation; +using FluentAssertions; +using FluentValidation; +using Infrastructure.Database; +using Infrastructure.Database.Users.Repositories; +using VisaApi.Fakers.Auth; +using VisaApi.Fakers.Users; +using VisaApi.Tests.Infrastructure.Database; +using Xunit; + +namespace VisaApi.Tests.Application.Validation.Auth +{ + [Collection(Collections.ContextUsingTestCollection)] + public class RegisterRequestValidatorTests + { + private readonly static IValidator authDataValidator = new AuthDataValidator(); + private readonly static RegisterRequestFaker requestFaker = new(); + private readonly static UserFaker userFaker = new(); + + /// + /// Creates validator from context + /// + /// db context + /// RegisterRequest validator + private static IValidator GetValidator(DbContext context) + { + var repository = new UsersRepository(context, context); + return new RegisterRequestValidator(repository, authDataValidator); + } + + /// + /// Test for validator that should throw for empty auth data + /// + [Fact] + private async Task ValidateForEmptyAuthDataShouldThrow() + { + var context = InMemoryContextProvider.GetDbContext(); + var validator = GetValidator(context); + var request = requestFaker.Generate(); + request.AuthData = null!; + NullReferenceException? result = null; + + try + { + await validator.ValidateAsync(request); + } + catch (Exception e) + { + result = e as NullReferenceException; + } + + result.Should().NotBeNull(); + } + + /// + /// Test for validator that should return error for used email + /// + [Fact] + private async Task ValidateForUsedEmailShouldReturnError() + { + var context = InMemoryContextProvider.GetDbContext(); + var validator = GetValidator(context); + var user = userFaker.Generate(); + await context.AddAsync(user); + await context.SaveChangesAsync(); + var request = requestFaker.Generate(); + request.AuthData.Email = user.Email; + + var result = await validator.ValidateAsync(request); + + result.Errors.Should() + .Contain(error => error.PropertyName == nameof(request.AuthData)) + .And.HaveCount(1); + } + + /// + /// Test for validator that should return o errors for valid requests + /// + [Fact] + private async Task ValidateForValidRequestShouldReturnNoErrors() + { + var context = InMemoryContextProvider.GetDbContext(); + var validator = GetValidator(context); + var request = requestFaker.Generate(); + + var result = await validator.ValidateAsync(request); + + result.Errors.Should().BeEmpty(); + } + } +}