-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add Advanced HTTP Methods for Users (#61)
* Add `IsDeleted` flag for users * Forbid login for deleted users * Improve users get methods Get methods now don't return deleted users * Add `onlyDeleted` flag for get users * Implement delete user method * Implement get user by id * Add DTOs and validation for user edit * Remove pointless tests * Implement `UsersService.UpdateUserAsync` * Implement `UsersService.UpdateUserRoles` * Remove regions * Implement HTTP methods for users
- Loading branch information
1 parent
2b3c93d
commit 92d8159
Showing
20 changed files
with
1,995 additions
and
129 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
using Microsoft.AspNetCore.Mvc.ModelBinding.Validation; | ||
|
||
namespace EUniversity.Core.Dtos.Users; | ||
|
||
[ValidateNever] // Remove data annotations validation | ||
public record ChangeRolesDto(bool? IsStudent = null, bool? IsTeacher = null, bool? IsAdministrator = null); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
using EUniversity.Core.Dtos.Auth; | ||
using Microsoft.AspNetCore.Mvc.ModelBinding.Validation; | ||
|
||
namespace EUniversity.Core.Dtos.Users; | ||
|
||
[ValidateNever] // Remove data annotations validation | ||
public record EditUserDto(string UserName, | ||
string Email, string FirstName, string LastName, string? MiddleName = null) : | ||
RegisterDto(Email, FirstName, LastName, MiddleName); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
namespace EUniversity.Core.Dtos.Users; | ||
|
||
public class UserViewDto | ||
{ | ||
public string Id { get; set; } = null!; | ||
public string Email { get; set; } = null!; | ||
public string UserName { get; set; } = null!; | ||
public string FirstName { get; set; } = null!; | ||
public string LastName { get; set; } = null!; | ||
public string? MiddleName { get; set; } | ||
public bool IsDeleted { get; set; } | ||
public IEnumerable<string> Roles { get; set; } = null!; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
using EUniversity.Core.Dtos.Users; | ||
using EUniversity.Core.Models; | ||
using FluentValidation; | ||
using FluentValidation.Results; | ||
|
||
namespace EUniversity.Core.Validation.Users; | ||
|
||
public class EditUserDtoValidator : RegisterDtoValidator<EditUserDto> | ||
{ | ||
public EditUserDtoValidator() : base() | ||
{ | ||
RuleFor(r => r.UserName).NotEmpty() | ||
.WithErrorCode(ValidationErrorCodes.PropertyRequired) | ||
.WithMessage("Username is required") | ||
.DependentRules(() => | ||
{ | ||
RuleFor(r => r.UserName).Custom((userName, context) => | ||
{ | ||
if (userName.All(c => ApplicationUser.AllowedUserNameCharacters.Contains(c))) | ||
{ | ||
return; | ||
} | ||
ValidationFailure failure = new() | ||
{ | ||
AttemptedValue = userName, | ||
ErrorCode = ValidationErrorCodes.InvalidUserName, | ||
ErrorMessage = "Username is invalid", | ||
PropertyName = context.PropertyPath, | ||
Severity = Severity.Error | ||
}; | ||
context.AddFailure(failure); | ||
}); | ||
}); | ||
RuleFor(x => x.UserName) | ||
.MaximumLength(ApplicationUser.MaxUserNameLength) | ||
.WithErrorCode(ValidationErrorCodes.PropertyTooLarge) | ||
.WithMessage($"Username cannot have more than {ApplicationUser.MaxEmailLength} characters"); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
94 changes: 94 additions & 0 deletions
94
EUniversity.Tests/Validation/Users/EditUserDtoValidatorTests.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
using EUniversity.Core.Dtos.Users; | ||
using EUniversity.Core.Models; | ||
using EUniversity.Core.Validation; | ||
using EUniversity.Core.Validation.Users; | ||
using FluentValidation.TestHelper; | ||
|
||
namespace EUniversity.Tests.Validation.Users; | ||
|
||
public class EditUserDtoValidatorTests | ||
{ | ||
private EditUserDtoValidator _validator; | ||
|
||
[OneTimeSetUp] | ||
public void OneTimeSetUp() | ||
{ | ||
_validator = new EditUserDtoValidator(); | ||
} | ||
|
||
[Test] | ||
[TestCase("12345")] | ||
[TestCase("waltuh")] | ||
[TestCase("jp-900")] | ||
[TestCase("Saul_Go0dmaN.CrimiNal-LAWyer")] | ||
public void UserName_Valid_Succeeds(string userName) | ||
{ | ||
// Arrange | ||
EditUserDto dto = new(userName, RegisterDtoValidatorTests.DefaultEmail, | ||
RegisterDtoValidatorTests.DefaultFirstName, RegisterDtoValidatorTests.DefaultLastName, | ||
RegisterDtoValidatorTests.DefaultMiddleName); | ||
|
||
// Act | ||
var result = _validator.TestValidate(dto); | ||
|
||
// Assert | ||
result.ShouldNotHaveAnyValidationErrors(); | ||
} | ||
|
||
[Test] | ||
[TestCase("Invąlid")] | ||
[TestCase("SomethingIs300$")] | ||
[TestCase("nOS_Svnm+-/*")] | ||
[TestCase("I have spaces")] | ||
[TestCase("IWantToBeValid!?")] | ||
public void UserName_ContainsInvalidCharacters_FailsWithInvalidUserNameError(string userName) | ||
{ | ||
// Arrange | ||
EditUserDto dto = new(userName, RegisterDtoValidatorTests.DefaultEmail, | ||
RegisterDtoValidatorTests.DefaultFirstName, RegisterDtoValidatorTests.DefaultLastName, | ||
RegisterDtoValidatorTests.DefaultMiddleName); | ||
|
||
// Act | ||
var result = _validator.TestValidate(dto); | ||
|
||
// Assert | ||
result.ShouldHaveValidationErrorFor(x => x.UserName) | ||
.WithErrorCode(ValidationErrorCodes.InvalidUserName) | ||
.Only(); | ||
} | ||
|
||
[Test] | ||
public void UserName_Empty_FailsWithPropertyRequiredError() | ||
{ | ||
// Arrange | ||
EditUserDto dto = new(string.Empty, RegisterDtoValidatorTests.DefaultEmail, | ||
RegisterDtoValidatorTests.DefaultFirstName, RegisterDtoValidatorTests.DefaultLastName, | ||
RegisterDtoValidatorTests.DefaultMiddleName); | ||
|
||
// Act | ||
var result = _validator.TestValidate(dto); | ||
|
||
// Assert | ||
result.ShouldHaveValidationErrorFor(x => x.UserName) | ||
.WithErrorCode(ValidationErrorCodes.PropertyRequired) | ||
.Only(); | ||
} | ||
|
||
[Test] | ||
public void UserName_TooLarge_FailsWithPropertyTooLargeError() | ||
{ | ||
// Arrange | ||
string largeUserName = new('0', ApplicationUser.MaxUserNameLength + 1); | ||
EditUserDto dto = new(largeUserName, RegisterDtoValidatorTests.DefaultEmail, | ||
RegisterDtoValidatorTests.DefaultFirstName, RegisterDtoValidatorTests.DefaultLastName, | ||
RegisterDtoValidatorTests.DefaultMiddleName); | ||
|
||
// Act | ||
var result = _validator.TestValidate(dto); | ||
|
||
// Assert | ||
result.ShouldHaveValidationErrorFor(x => x.UserName) | ||
.WithErrorCode(ValidationErrorCodes.PropertyTooLarge) | ||
.Only(); | ||
} | ||
} |
Oops, something went wrong.