diff --git a/CleanArchitecture.Api/CleanArchitecture.Api.csproj b/CleanArchitecture.Api/CleanArchitecture.Api.csproj
index 3662059..3ffe10b 100644
--- a/CleanArchitecture.Api/CleanArchitecture.Api.csproj
+++ b/CleanArchitecture.Api/CleanArchitecture.Api.csproj
@@ -7,22 +7,22 @@
-
-
+
+
- all
- runtime; build; native; contentfiles; analyzers; buildtransitive
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
-
-
-
+
+
+
-
-
-
-
+
+
+
+
diff --git a/CleanArchitecture.Api/Controllers/ApiController.cs b/CleanArchitecture.Api/Controllers/ApiController.cs
index a191d22..c092d04 100644
--- a/CleanArchitecture.Api/Controllers/ApiController.cs
+++ b/CleanArchitecture.Api/Controllers/ApiController.cs
@@ -62,7 +62,7 @@ public class ApiController : ControllerBase
{
return HttpStatusCode.NotFound;
}
-
+
if (_notifications.GetNotifications().Any(n => n.Code == ErrorCodes.InsufficientPermissions))
{
return HttpStatusCode.Forbidden;
diff --git a/CleanArchitecture.Api/Controllers/UserController.cs b/CleanArchitecture.Api/Controllers/UserController.cs
index 3d822b4..7df8108 100644
--- a/CleanArchitecture.Api/Controllers/UserController.cs
+++ b/CleanArchitecture.Api/Controllers/UserController.cs
@@ -46,7 +46,7 @@ public class UserController : ApiController
var user = await _userService.GetUserByUserIdAsync(id, isDeleted);
return Response(user);
}
-
+
[Authorize]
[HttpGet("me")]
[SwaggerOperation("Get the current active user")]
@@ -56,7 +56,7 @@ public class UserController : ApiController
var user = await _userService.GetCurrentUserAsync();
return Response(user);
}
-
+
[HttpPost]
[SwaggerOperation("Create a new user")]
[SwaggerResponse(200, "Request successful", typeof(ResponseMessage))]
diff --git a/CleanArchitecture.Api/Program.cs b/CleanArchitecture.Api/Program.cs
index 9a76f47..6bfc87b 100644
--- a/CleanArchitecture.Api/Program.cs
+++ b/CleanArchitecture.Api/Program.cs
@@ -28,37 +28,36 @@ builder.Services.AddSwaggerGen(c =>
{
Title = "CleanArchitecture",
Version = "v1",
- Description = "A clean architecture API",
+ Description = "A clean architecture API"
});
c.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme
{
Description = "JWT Authorization header using the Bearer scheme. " +
- "Use the /auth/azureLogin endpoint to generate a token (use the id_token here), " +
- "or create a personal access token in centralhub.",
+ "Use the /api/v1/user/login endpoint to generate a token",
Name = "Authorization",
In = ParameterLocation.Header,
Type = SecuritySchemeType.Http,
Scheme = "bearer"
});
- c.AddSecurityRequirement(new OpenApiSecurityRequirement()
+ c.AddSecurityRequirement(new OpenApiSecurityRequirement
+ {
+ {
+ new OpenApiSecurityScheme
{
+ Reference = new OpenApiReference
{
- new OpenApiSecurityScheme
- {
- Reference = new OpenApiReference
- {
- Type = ReferenceType.SecurityScheme,
- Id = "Bearer"
- },
- Scheme = "oauth2",
- Name = "Bearer",
- In = ParameterLocation.Header,
- },
- new List()
- }
- });
+ Type = ReferenceType.SecurityScheme,
+ Id = "Bearer"
+ },
+ Scheme = "oauth2",
+ Name = "Bearer",
+ In = ParameterLocation.Header
+ },
+ new List()
+ }
+ });
});
builder.Services.AddHealthChecks();
@@ -72,15 +71,9 @@ builder.Services.AddDbContext(options =>
});
builder.Services.AddAuthentication(
- options =>
- {
- options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
- })
+ options => { options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme; })
.AddJwtBearer(
- jwtOptions =>
- {
- jwtOptions.TokenValidationParameters = CreateTokenValidationParameters();
- });
+ jwtOptions => { jwtOptions.TokenValidationParameters = CreateTokenValidationParameters(); });
builder.Services.AddInfrastructure();
builder.Services.AddQueryHandlers();
@@ -94,10 +87,7 @@ builder.Services
.Bind(builder.Configuration.GetSection("Auth"))
.ValidateOnStart();
-builder.Services.AddMediatR(cfg =>
-{
- cfg.RegisterServicesFromAssemblies(typeof(Program).Assembly);
-});
+builder.Services.AddMediatR(cfg => { cfg.RegisterServicesFromAssemblies(typeof(Program).Assembly); });
var app = builder.Build();
@@ -116,10 +106,10 @@ app.MapControllers();
app.MapHealthChecks("/health");
app.MapGrpcService();
-using (IServiceScope scope = app.Services.CreateScope())
+using (var scope = app.Services.CreateScope())
{
var services = scope.ServiceProvider;
- ApplicationDbContext appDbContext = services.GetRequiredService();
+ var appDbContext = services.GetRequiredService();
appDbContext.EnsureMigrationsApplied();
}
@@ -137,8 +127,8 @@ TokenValidationParameters CreateTokenValidationParameters()
ValidIssuer = builder.Configuration["Auth:Issuer"],
ValidAudience = builder.Configuration["Auth:Audience"],
IssuerSigningKey = new SymmetricSecurityKey(
- Encoding.UTF8.GetBytes(
- builder.Configuration["Auth:Secret"]!)),
+ Encoding.UTF8.GetBytes(
+ builder.Configuration["Auth:Secret"]!)),
RequireSignedTokens = false
};
@@ -146,4 +136,6 @@ TokenValidationParameters CreateTokenValidationParameters()
}
// Needed for integration tests webapplication factory
-public partial class Program { }
\ No newline at end of file
+public partial class Program
+{
+}
\ No newline at end of file
diff --git a/CleanArchitecture.Application.Tests/CleanArchitecture.Application.Tests.csproj b/CleanArchitecture.Application.Tests/CleanArchitecture.Application.Tests.csproj
index 082265f..9af11da 100644
--- a/CleanArchitecture.Application.Tests/CleanArchitecture.Application.Tests.csproj
+++ b/CleanArchitecture.Application.Tests/CleanArchitecture.Application.Tests.csproj
@@ -8,11 +8,11 @@
-
-
-
-
-
+
+
+
+
+
runtime; build; native; contentfiles; analyzers; buildtransitive
all
@@ -24,8 +24,8 @@
-
-
+
+
diff --git a/CleanArchitecture.Application.Tests/Fixtures/Queries/QueryHandlerBaseFixture.cs b/CleanArchitecture.Application.Tests/Fixtures/Queries/QueryHandlerBaseFixture.cs
index 204e29c..2d995f8 100644
--- a/CleanArchitecture.Application.Tests/Fixtures/Queries/QueryHandlerBaseFixture.cs
+++ b/CleanArchitecture.Application.Tests/Fixtures/Queries/QueryHandlerBaseFixture.cs
@@ -7,7 +7,7 @@ namespace CleanArchitecture.Application.Tests.Fixtures.Queries;
public class QueryHandlerBaseFixture
{
public Mock Bus { get; } = new();
-
+
public QueryHandlerBaseFixture VerifyExistingNotification(string key, string errorCode, string message)
{
Bus.Verify(
diff --git a/CleanArchitecture.Application.Tests/Fixtures/Queries/Users/GetAllUsersTestFixture.cs b/CleanArchitecture.Application.Tests/Fixtures/Queries/Users/GetAllUsersTestFixture.cs
index e53901c..9dde37d 100644
--- a/CleanArchitecture.Application.Tests/Fixtures/Queries/Users/GetAllUsersTestFixture.cs
+++ b/CleanArchitecture.Application.Tests/Fixtures/Queries/Users/GetAllUsersTestFixture.cs
@@ -11,30 +11,30 @@ namespace CleanArchitecture.Application.Tests.Fixtures.Queries.Users;
public sealed class GetAllUsersTestFixture : QueryHandlerBaseFixture
{
+ public GetAllUsersTestFixture()
+ {
+ UserRepository = new Mock();
+
+ Handler = new GetAllUsersQueryHandler(UserRepository.Object);
+ }
+
private Mock UserRepository { get; }
public GetAllUsersQueryHandler Handler { get; }
public Guid ExistingUserId { get; } = Guid.NewGuid();
- public GetAllUsersTestFixture()
- {
- UserRepository = new();
-
- Handler = new(UserRepository.Object);
- }
-
public void SetupUserAsync()
{
var user = new Mock(() =>
- new User(
- ExistingUserId,
- "max@mustermann.com",
- "Max",
- "Mustermann",
- "Password",
- UserRole.User));
+ new User(
+ ExistingUserId,
+ "max@mustermann.com",
+ "Max",
+ "Mustermann",
+ "Password",
+ UserRole.User));
var query = new[] { user.Object }.AsQueryable().BuildMock();
-
+
UserRepository
.Setup(x => x.GetAllNoTracking())
.Returns(query);
@@ -43,13 +43,13 @@ public sealed class GetAllUsersTestFixture : QueryHandlerBaseFixture
public void SetupDeletedUserAsync()
{
var user = new Mock(() =>
- new User(
- ExistingUserId,
- "max@mustermann.com",
- "Max",
- "Mustermann",
- "Password",
- UserRole.User));
+ new User(
+ ExistingUserId,
+ "max@mustermann.com",
+ "Max",
+ "Mustermann",
+ "Password",
+ UserRole.User));
user.Object.Delete();
diff --git a/CleanArchitecture.Application.Tests/Fixtures/Queries/Users/GetUserByIdTestFixture.cs b/CleanArchitecture.Application.Tests/Fixtures/Queries/Users/GetUserByIdTestFixture.cs
index b7c0201..e175faa 100644
--- a/CleanArchitecture.Application.Tests/Fixtures/Queries/Users/GetUserByIdTestFixture.cs
+++ b/CleanArchitecture.Application.Tests/Fixtures/Queries/Users/GetUserByIdTestFixture.cs
@@ -11,30 +11,30 @@ namespace CleanArchitecture.Application.Tests.Fixtures.Queries.Users;
public sealed class GetUserByIdTestFixture : QueryHandlerBaseFixture
{
+ public GetUserByIdTestFixture()
+ {
+ UserRepository = new Mock();
+
+ Handler = new GetUserByIdQueryHandler(UserRepository.Object, Bus.Object);
+ }
+
private Mock UserRepository { get; }
public GetUserByIdQueryHandler Handler { get; }
public Guid ExistingUserId { get; } = Guid.NewGuid();
- public GetUserByIdTestFixture()
- {
- UserRepository = new();
-
- Handler = new(UserRepository.Object, Bus.Object);
- }
-
public void SetupUserAsync()
{
var user = new Mock(() =>
new User(
- ExistingUserId,
- "max@mustermann.com",
- "Max",
+ ExistingUserId,
+ "max@mustermann.com",
+ "Max",
"Mustermann",
"Password",
UserRole.User));
var query = new[] { user.Object }.AsQueryable().BuildMock();
-
+
UserRepository
.Setup(x => x.GetAllNoTracking())
.Returns(query);
diff --git a/CleanArchitecture.Application.Tests/Queries/Users/GetAllUsersQueryHandlerTests.cs b/CleanArchitecture.Application.Tests/Queries/Users/GetAllUsersQueryHandlerTests.cs
index f1ec70e..7f2f3a5 100644
--- a/CleanArchitecture.Application.Tests/Queries/Users/GetAllUsersQueryHandlerTests.cs
+++ b/CleanArchitecture.Application.Tests/Queries/Users/GetAllUsersQueryHandlerTests.cs
@@ -1,5 +1,6 @@
using System.Linq;
using System.Threading.Tasks;
+using CleanArchitecture.Application.Queries.Users.GetAll;
using CleanArchitecture.Application.Tests.Fixtures.Queries.Users;
using FluentAssertions;
using Xunit;
@@ -16,11 +17,11 @@ public sealed class GetAllUsersQueryHandlerTests
_fixture.SetupUserAsync();
var result = await _fixture.Handler.Handle(
- new(),
+ new GetAllUsersQuery(),
default);
-
+
_fixture.VerifyNoDomainNotification();
-
+
result.Should().NotBeNull();
result.Should().ContainSingle();
result.FirstOrDefault()!.Id.Should().Be(_fixture.ExistingUserId);
@@ -32,7 +33,7 @@ public sealed class GetAllUsersQueryHandlerTests
_fixture.SetupDeletedUserAsync();
var result = await _fixture.Handler.Handle(
- new(),
+ new GetAllUsersQuery(),
default);
_fixture.VerifyNoDomainNotification();
diff --git a/CleanArchitecture.Application.Tests/Queries/Users/GetUserByIdQueryHandlerTests.cs b/CleanArchitecture.Application.Tests/Queries/Users/GetUserByIdQueryHandlerTests.cs
index a65da4c..4b3aec0 100644
--- a/CleanArchitecture.Application.Tests/Queries/Users/GetUserByIdQueryHandlerTests.cs
+++ b/CleanArchitecture.Application.Tests/Queries/Users/GetUserByIdQueryHandlerTests.cs
@@ -18,15 +18,15 @@ public sealed class GetUserByIdQueryHandlerTests
_fixture.SetupUserAsync();
var result = await _fixture.Handler.Handle(
- new(_fixture.ExistingUserId, false),
+ new GetUserByIdQuery(_fixture.ExistingUserId, false),
default);
-
+
_fixture.VerifyNoDomainNotification();
result.Should().NotBeNull();
result!.Id.Should().Be(_fixture.ExistingUserId);
}
-
+
[Fact]
public async Task Should_Raise_Notification_For_No_User()
{
@@ -36,7 +36,7 @@ public sealed class GetUserByIdQueryHandlerTests
var result = await _fixture.Handler.Handle(
request,
default);
-
+
_fixture.VerifyExistingNotification(
nameof(GetUserByIdQuery),
ErrorCodes.ObjectNotFound,
@@ -51,7 +51,7 @@ public sealed class GetUserByIdQueryHandlerTests
_fixture.SetupDeletedUserAsync();
var result = await _fixture.Handler.Handle(
- new(_fixture.ExistingUserId, false),
+ new GetUserByIdQuery(_fixture.ExistingUserId, false),
default);
_fixture.VerifyExistingNotification(
diff --git a/CleanArchitecture.Application/CleanArchitecture.Application.csproj b/CleanArchitecture.Application/CleanArchitecture.Application.csproj
index 2f39ab9..2b5f8ef 100644
--- a/CleanArchitecture.Application/CleanArchitecture.Application.csproj
+++ b/CleanArchitecture.Application/CleanArchitecture.Application.csproj
@@ -6,11 +6,11 @@
-
+
-
+
diff --git a/CleanArchitecture.Application/Extensions/ServiceCollectionExtension.cs b/CleanArchitecture.Application/Extensions/ServiceCollectionExtension.cs
index beaec9f..784380f 100644
--- a/CleanArchitecture.Application/Extensions/ServiceCollectionExtension.cs
+++ b/CleanArchitecture.Application/Extensions/ServiceCollectionExtension.cs
@@ -14,15 +14,15 @@ public static class ServiceCollectionExtension
public static IServiceCollection AddServices(this IServiceCollection services)
{
services.AddScoped();
-
+
return services;
}
-
+
public static IServiceCollection AddQueryHandlers(this IServiceCollection services)
{
services.AddScoped, GetUserByIdQueryHandler>();
services.AddScoped>, GetAllUsersQueryHandler>();
-
+
return services;
}
}
\ No newline at end of file
diff --git a/CleanArchitecture.Application/Interfaces/IUserService.cs b/CleanArchitecture.Application/Interfaces/IUserService.cs
index a04dfcb..1fbca3e 100644
--- a/CleanArchitecture.Application/Interfaces/IUserService.cs
+++ b/CleanArchitecture.Application/Interfaces/IUserService.cs
@@ -1,6 +1,6 @@
-using System.Threading.Tasks;
using System;
using System.Collections.Generic;
+using System.Threading.Tasks;
using CleanArchitecture.Application.ViewModels.Users;
namespace CleanArchitecture.Application.Interfaces;
diff --git a/CleanArchitecture.Application/Queries/Users/GetAll/GetAllUsersQuery.cs b/CleanArchitecture.Application/Queries/Users/GetAll/GetAllUsersQuery.cs
index 40e8571..9e59d7f 100644
--- a/CleanArchitecture.Application/Queries/Users/GetAll/GetAllUsersQuery.cs
+++ b/CleanArchitecture.Application/Queries/Users/GetAll/GetAllUsersQuery.cs
@@ -4,4 +4,4 @@ using MediatR;
namespace CleanArchitecture.Application.Queries.Users.GetAll;
-public sealed record GetAllUsersQuery : IRequest>;
+public sealed record GetAllUsersQuery : IRequest>;
\ No newline at end of file
diff --git a/CleanArchitecture.Application/Queries/Users/GetUserById/GetUserByIdQuery.cs b/CleanArchitecture.Application/Queries/Users/GetUserById/GetUserByIdQuery.cs
index e394336..b4edf1e 100644
--- a/CleanArchitecture.Application/Queries/Users/GetUserById/GetUserByIdQuery.cs
+++ b/CleanArchitecture.Application/Queries/Users/GetUserById/GetUserByIdQuery.cs
@@ -4,4 +4,4 @@ using MediatR;
namespace CleanArchitecture.Application.Queries.Users.GetUserById;
-public sealed record GetUserByIdQuery(Guid UserId, bool IsDeleted) : IRequest;
+public sealed record GetUserByIdQuery(Guid UserId, bool IsDeleted) : IRequest;
\ No newline at end of file
diff --git a/CleanArchitecture.Application/Queries/Users/GetUserById/GetUserByIdQueryHandler.cs b/CleanArchitecture.Application/Queries/Users/GetUserById/GetUserByIdQueryHandler.cs
index 2c166a8..f057731 100644
--- a/CleanArchitecture.Application/Queries/Users/GetUserById/GetUserByIdQueryHandler.cs
+++ b/CleanArchitecture.Application/Queries/Users/GetUserById/GetUserByIdQueryHandler.cs
@@ -13,8 +13,8 @@ namespace CleanArchitecture.Application.Queries.Users.GetUserById;
public sealed class GetUserByIdQueryHandler :
IRequestHandler
{
- private readonly IUserRepository _userRepository;
private readonly IMediatorHandler _bus;
+ private readonly IUserRepository _userRepository;
public GetUserByIdQueryHandler(IUserRepository userRepository, IMediatorHandler bus)
{
@@ -26,7 +26,7 @@ public sealed class GetUserByIdQueryHandler :
{
var user = _userRepository
.GetAllNoTracking()
- .FirstOrDefault(x =>
+ .FirstOrDefault(x =>
x.Id == request.UserId &&
x.Deleted == request.IsDeleted);
@@ -42,4 +42,4 @@ public sealed class GetUserByIdQueryHandler :
return UserViewModel.FromUser(user);
}
-}
+}
\ No newline at end of file
diff --git a/CleanArchitecture.Application/Services/UserService.cs b/CleanArchitecture.Application/Services/UserService.cs
index ee726a5..da20411 100644
--- a/CleanArchitecture.Application/Services/UserService.cs
+++ b/CleanArchitecture.Application/Services/UserService.cs
@@ -29,7 +29,7 @@ public sealed class UserService : IUserService
{
return await _bus.QueryAsync(new GetUserByIdQuery(userId, isDeleted));
}
-
+
public async Task GetCurrentUserAsync()
{
return await _bus.QueryAsync(new GetUserByIdQuery(_user.GetUserId(), false));
@@ -39,7 +39,7 @@ public sealed class UserService : IUserService
{
return await _bus.QueryAsync(new GetAllUsersQuery());
}
-
+
public async Task CreateUserAsync(CreateUserViewModel user)
{
var userId = Guid.NewGuid();
@@ -53,7 +53,7 @@ public sealed class UserService : IUserService
return userId;
}
-
+
public async Task UpdateUserAsync(UpdateUserViewModel user)
{
await _bus.SendCommandAsync(new UpdateUserCommand(
@@ -63,7 +63,7 @@ public sealed class UserService : IUserService
user.GivenName,
user.Role));
}
-
+
public async Task DeleteUserAsync(Guid userId)
{
await _bus.SendCommandAsync(new DeleteUserCommand(userId));
diff --git a/CleanArchitecture.Application/ViewModels/Users/ChangePasswordViewModel.cs b/CleanArchitecture.Application/ViewModels/Users/ChangePasswordViewModel.cs
index fb02751..bc35cbb 100644
--- a/CleanArchitecture.Application/ViewModels/Users/ChangePasswordViewModel.cs
+++ b/CleanArchitecture.Application/ViewModels/Users/ChangePasswordViewModel.cs
@@ -1,3 +1,3 @@
namespace CleanArchitecture.Application.ViewModels.Users;
-public sealed record ChangePasswordViewModel(string Password, string NewPassword);
+public sealed record ChangePasswordViewModel(string Password, string NewPassword);
\ No newline at end of file
diff --git a/CleanArchitecture.Application/ViewModels/Users/LoginUserViewModel.cs b/CleanArchitecture.Application/ViewModels/Users/LoginUserViewModel.cs
index 3883c05..ac5e7de 100644
--- a/CleanArchitecture.Application/ViewModels/Users/LoginUserViewModel.cs
+++ b/CleanArchitecture.Application/ViewModels/Users/LoginUserViewModel.cs
@@ -1,3 +1,3 @@
namespace CleanArchitecture.Application.ViewModels.Users;
-public sealed record LoginUserViewModel(string Email, string Password);
+public sealed record LoginUserViewModel(string Email, string Password);
\ No newline at end of file
diff --git a/CleanArchitecture.Domain.Tests/CleanArchitecture.Domain.Tests.csproj b/CleanArchitecture.Domain.Tests/CleanArchitecture.Domain.Tests.csproj
index 72a5f62..dfa6f77 100644
--- a/CleanArchitecture.Domain.Tests/CleanArchitecture.Domain.Tests.csproj
+++ b/CleanArchitecture.Domain.Tests/CleanArchitecture.Domain.Tests.csproj
@@ -8,11 +8,11 @@
-
-
-
-
-
+
+
+
+
+
runtime; build; native; contentfiles; analyzers; buildtransitive
all
@@ -24,7 +24,7 @@
-
+
diff --git a/CleanArchitecture.Domain.Tests/CommandHandler/User/ChangePassword/ChangePasswordCommandHandlerTests.cs b/CleanArchitecture.Domain.Tests/CommandHandler/User/ChangePassword/ChangePasswordCommandHandlerTests.cs
index a6fc1e9..08d16ca 100644
--- a/CleanArchitecture.Domain.Tests/CommandHandler/User/ChangePassword/ChangePasswordCommandHandlerTests.cs
+++ b/CleanArchitecture.Domain.Tests/CommandHandler/User/ChangePassword/ChangePasswordCommandHandlerTests.cs
@@ -60,4 +60,4 @@ public sealed class ChangePasswordCommandHandlerTests
DomainErrorCodes.UserPasswordIncorrect,
"The password is incorrect");
}
-}
+}
\ No newline at end of file
diff --git a/CleanArchitecture.Domain.Tests/CommandHandler/User/ChangePassword/ChangePasswordCommandTestFixture.cs b/CleanArchitecture.Domain.Tests/CommandHandler/User/ChangePassword/ChangePasswordCommandTestFixture.cs
index 6162a21..77e8e55 100644
--- a/CleanArchitecture.Domain.Tests/CommandHandler/User/ChangePassword/ChangePasswordCommandTestFixture.cs
+++ b/CleanArchitecture.Domain.Tests/CommandHandler/User/ChangePassword/ChangePasswordCommandTestFixture.cs
@@ -9,14 +9,11 @@ namespace CleanArchitecture.Domain.Tests.CommandHandler.User.ChangePassword;
public sealed class ChangePasswordCommandTestFixture : CommandHandlerFixtureBase
{
- public ChangePasswordCommandHandler CommandHandler { get; set; }
- public Mock UserRepository { get; set; }
-
public ChangePasswordCommandTestFixture()
{
UserRepository = new Mock();
- CommandHandler = new(
+ CommandHandler = new ChangePasswordCommandHandler(
Bus.Object,
UnitOfWork.Object,
NotificationHandler.Object,
@@ -24,6 +21,9 @@ public sealed class ChangePasswordCommandTestFixture : CommandHandlerFixtureBase
User.Object);
}
+ public ChangePasswordCommandHandler CommandHandler { get; set; }
+ public Mock UserRepository { get; set; }
+
public Entities.User SetupUser()
{
var user = new Entities.User(
@@ -49,4 +49,4 @@ public sealed class ChangePasswordCommandTestFixture : CommandHandlerFixtureBase
User.Setup(x => x.GetUserId()).Returns(id);
return id;
}
-}
+}
\ No newline at end of file
diff --git a/CleanArchitecture.Domain.Tests/CommandHandler/User/ChangePassword/ChangePasswordCommandValidationTests.cs b/CleanArchitecture.Domain.Tests/CommandHandler/User/ChangePassword/ChangePasswordCommandValidationTests.cs
index d68220c..3b0339e 100644
--- a/CleanArchitecture.Domain.Tests/CommandHandler/User/ChangePassword/ChangePasswordCommandValidationTests.cs
+++ b/CleanArchitecture.Domain.Tests/CommandHandler/User/ChangePassword/ChangePasswordCommandValidationTests.cs
@@ -12,15 +12,15 @@ public sealed class ChangePasswordCommandValidationTests :
public ChangePasswordCommandValidationTests() : base(new ChangePasswordCommandValidation())
{
}
-
+
[Fact]
public void Should_Be_Valid()
{
var command = CreateTestCommand();
-
+
ShouldBeValid(command);
}
-
+
[Fact]
public void Should_Be_Invalid_For_Empty_Password()
{
@@ -35,60 +35,63 @@ public sealed class ChangePasswordCommandValidationTests :
DomainErrorCodes.UserUppercaseLetterPassword,
DomainErrorCodes.UserShortPassword
};
-
+
ShouldHaveExpectedErrors(command, errors.ToArray());
}
-
+
[Fact]
public void Should_Be_Invalid_For_Missing_Special_Character()
{
var command = CreateTestCommand("z8tnayvd5FNLU9AQm");
-
+
ShouldHaveSingleError(command, DomainErrorCodes.UserSpecialCharPassword);
}
-
+
[Fact]
public void Should_Be_Invalid_For_Missing_Number()
{
var command = CreateTestCommand("z]tnayvdFNLU:]AQm");
-
+
ShouldHaveSingleError(command, DomainErrorCodes.UserNumberPassword);
}
-
+
[Fact]
public void Should_Be_Invalid_For_Missing_Lowercase_Character()
{
var command = CreateTestCommand("Z8]TNAYVDFNLU:]AQM");
-
+
ShouldHaveSingleError(command, DomainErrorCodes.UserLowercaseLetterPassword);
}
-
+
[Fact]
public void Should_Be_Invalid_For_Missing_Uppercase_Character()
{
var command = CreateTestCommand("z8]tnayvd5fnlu9:]aqm");
-
+
ShouldHaveSingleError(command, DomainErrorCodes.UserUppercaseLetterPassword);
}
-
+
[Fact]
public void Should_Be_Invalid_For_Password_Too_Short()
{
var command = CreateTestCommand("zA6{");
-
+
ShouldHaveSingleError(command, DomainErrorCodes.UserShortPassword);
}
-
+
[Fact]
public void Should_Be_Invalid_For_Password_Too_Long()
{
var command = CreateTestCommand(string.Concat(Enumerable.Repeat("zA6{", 12), 12));
-
+
ShouldHaveSingleError(command, DomainErrorCodes.UserLongPassword);
}
private ChangePasswordCommand CreateTestCommand(
- string? password = null, string? newPassword = null) => new(
- password ?? "z8]tnayvd5FNLU9:]AQm",
+ string? password = null, string? newPassword = null)
+ {
+ return new(
+ password ?? "z8]tnayvd5FNLU9:]AQm",
newPassword ?? "z8]tnayvd5FNLU9:]AQw");
-}
+ }
+}
\ No newline at end of file
diff --git a/CleanArchitecture.Domain.Tests/CommandHandler/User/CreateUser/CreateUserCommandHandlerTests.cs b/CleanArchitecture.Domain.Tests/CommandHandler/User/CreateUser/CreateUserCommandHandlerTests.cs
index 50eaa79..9319274 100644
--- a/CleanArchitecture.Domain.Tests/CommandHandler/User/CreateUser/CreateUserCommandHandlerTests.cs
+++ b/CleanArchitecture.Domain.Tests/CommandHandler/User/CreateUser/CreateUserCommandHandlerTests.cs
@@ -9,19 +9,19 @@ namespace CleanArchitecture.Domain.Tests.CommandHandler.User.CreateUser;
public sealed class CreateUserCommandHandlerTests
{
private readonly CreateUserCommandTestFixture _fixture = new();
-
+
[Fact]
public void Should_Create_User()
{
_fixture.SetupUser();
-
+
var command = new CreateUserCommand(
Guid.NewGuid(),
"test@email.com",
"Test",
"Email",
"Po=PF]PC6t.?8?ks)A6W");
-
+
_fixture.CommandHandler.Handle(command, default).Wait();
_fixture
@@ -29,19 +29,19 @@ public sealed class CreateUserCommandHandlerTests
.VerifyCommit()
.VerifyRaisedEvent(x => x.UserId == command.UserId);
}
-
+
[Fact]
public void Should_Not_Create_Already_Existing_User()
{
var user = _fixture.SetupUser();
-
+
var command = new CreateUserCommand(
user.Id,
"test@email.com",
"Test",
"Email",
"Po=PF]PC6t.?8?ks)A6W");
-
+
_fixture.CommandHandler.Handle(command, default).Wait();
_fixture
diff --git a/CleanArchitecture.Domain.Tests/CommandHandler/User/CreateUser/CreateUserCommandTestFixture.cs b/CleanArchitecture.Domain.Tests/CommandHandler/User/CreateUser/CreateUserCommandTestFixture.cs
index c7ba05a..f6879b3 100644
--- a/CleanArchitecture.Domain.Tests/CommandHandler/User/CreateUser/CreateUserCommandTestFixture.cs
+++ b/CleanArchitecture.Domain.Tests/CommandHandler/User/CreateUser/CreateUserCommandTestFixture.cs
@@ -8,20 +8,20 @@ namespace CleanArchitecture.Domain.Tests.CommandHandler.User.CreateUser;
public sealed class CreateUserCommandTestFixture : CommandHandlerFixtureBase
{
- public CreateUserCommandHandler CommandHandler { get; }
- private Mock UserRepository { get; }
-
public CreateUserCommandTestFixture()
{
UserRepository = new Mock();
-
- CommandHandler = new(
+
+ CommandHandler = new CreateUserCommandHandler(
Bus.Object,
UnitOfWork.Object,
NotificationHandler.Object,
UserRepository.Object);
}
-
+
+ public CreateUserCommandHandler CommandHandler { get; }
+ private Mock UserRepository { get; }
+
public Entities.User SetupUser()
{
var user = new Entities.User(
diff --git a/CleanArchitecture.Domain.Tests/CommandHandler/User/CreateUser/CreateUserCommandValidationTests.cs b/CleanArchitecture.Domain.Tests/CommandHandler/User/CreateUser/CreateUserCommandValidationTests.cs
index 61a00ad..f3bbe6d 100644
--- a/CleanArchitecture.Domain.Tests/CommandHandler/User/CreateUser/CreateUserCommandValidationTests.cs
+++ b/CleanArchitecture.Domain.Tests/CommandHandler/User/CreateUser/CreateUserCommandValidationTests.cs
@@ -13,103 +13,103 @@ public sealed class CreateUserCommandValidationTests :
public CreateUserCommandValidationTests() : base(new CreateUserCommandValidation())
{
}
-
+
[Fact]
public void Should_Be_Valid()
{
var command = CreateTestCommand();
-
+
ShouldBeValid(command);
}
-
+
[Fact]
public void Should_Be_Invalid_For_Empty_User_Id()
{
- var command = CreateTestCommand(userId: Guid.Empty);
-
+ var command = CreateTestCommand(Guid.Empty);
+
ShouldHaveSingleError(
- command,
+ command,
DomainErrorCodes.UserEmptyId,
"User id may not be empty");
}
-
+
[Fact]
public void Should_Be_Invalid_For_Empty_Email()
{
var command = CreateTestCommand(email: string.Empty);
-
+
ShouldHaveSingleError(
command,
DomainErrorCodes.UserInvalidEmail,
"Email is not a valid email address");
}
-
+
[Fact]
public void Should_Be_Invalid_For_Invalid_Email()
{
var command = CreateTestCommand(email: "not a email");
-
+
ShouldHaveSingleError(
command,
DomainErrorCodes.UserInvalidEmail,
"Email is not a valid email address");
}
-
+
[Fact]
public void Should_Be_Invalid_For_Email_Exceeds_Max_Length()
{
var command = CreateTestCommand(email: new string('a', 320) + "@test.com");
-
+
ShouldHaveSingleError(
command,
DomainErrorCodes.UserEmailExceedsMaxLength,
"Email may not be longer than 320 characters");
}
-
+
[Fact]
public void Should_Be_Invalid_For_Empty_Surname()
{
var command = CreateTestCommand(surName: "");
-
+
ShouldHaveSingleError(
command,
DomainErrorCodes.UserEmptySurname,
"Surname may not be empty");
}
-
+
[Fact]
public void Should_Be_Invalid_For_Surname_Exceeds_Max_Length()
{
var command = CreateTestCommand(surName: new string('a', 101));
-
+
ShouldHaveSingleError(
command,
DomainErrorCodes.UserSurnameExceedsMaxLength,
"Surname may not be longer than 100 characters");
}
-
+
[Fact]
public void Should_Be_Invalid_For_Empty_Given_Name()
{
var command = CreateTestCommand(givenName: "");
-
+
ShouldHaveSingleError(
command,
DomainErrorCodes.UserEmptyGivenName,
"Given name may not be empty");
}
-
+
[Fact]
public void Should_Be_Invalid_For_Given_Name_Exceeds_Max_Length()
{
var command = CreateTestCommand(givenName: new string('a', 101));
-
+
ShouldHaveSingleError(
command,
DomainErrorCodes.UserGivenNameExceedsMaxLength,
"Given name may not be longer than 100 characters");
}
-
+
[Fact]
public void Should_Be_Invalid_For_Empty_Password()
{
@@ -124,68 +124,70 @@ public sealed class CreateUserCommandValidationTests :
DomainErrorCodes.UserUppercaseLetterPassword,
DomainErrorCodes.UserShortPassword
};
-
+
ShouldHaveExpectedErrors(command, errors.ToArray());
}
-
+
[Fact]
public void Should_Be_Invalid_For_Missing_Special_Character()
{
var command = CreateTestCommand(password: "z8tnayvd5FNLU9AQm");
-
+
ShouldHaveSingleError(command, DomainErrorCodes.UserSpecialCharPassword);
}
-
+
[Fact]
public void Should_Be_Invalid_For_Missing_Number()
{
var command = CreateTestCommand(password: "z]tnayvdFNLU:]AQm");
-
+
ShouldHaveSingleError(command, DomainErrorCodes.UserNumberPassword);
}
-
+
[Fact]
public void Should_Be_Invalid_For_Missing_Lowercase_Character()
{
var command = CreateTestCommand(password: "Z8]TNAYVDFNLU:]AQM");
-
+
ShouldHaveSingleError(command, DomainErrorCodes.UserLowercaseLetterPassword);
}
-
+
[Fact]
public void Should_Be_Invalid_For_Missing_Uppercase_Character()
{
var command = CreateTestCommand(password: "z8]tnayvd5fnlu9:]aqm");
-
+
ShouldHaveSingleError(command, DomainErrorCodes.UserUppercaseLetterPassword);
}
-
+
[Fact]
public void Should_Be_Invalid_For_Password_Too_Short()
{
var command = CreateTestCommand(password: "zA6{");
-
+
ShouldHaveSingleError(command, DomainErrorCodes.UserShortPassword);
}
-
+
[Fact]
public void Should_Be_Invalid_For_Password_Too_Long()
{
var command = CreateTestCommand(password: string.Concat(Enumerable.Repeat("zA6{", 12), 12));
-
+
ShouldHaveSingleError(command, DomainErrorCodes.UserLongPassword);
}
-
+
private CreateUserCommand CreateTestCommand(
Guid? userId = null,
string? email = null,
string? surName = null,
string? givenName = null,
- string? password = null) =>
- new (
+ string? password = null)
+ {
+ return new(
userId ?? Guid.NewGuid(),
email ?? "test@email.com",
surName ?? "test",
givenName ?? "email",
password ?? "Po=PF]PC6t.?8?ks)A6W");
+ }
}
\ No newline at end of file
diff --git a/CleanArchitecture.Domain.Tests/CommandHandler/User/DeleteUser/DeleteUserCommandHandlerTests.cs b/CleanArchitecture.Domain.Tests/CommandHandler/User/DeleteUser/DeleteUserCommandHandlerTests.cs
index dc23bd6..fabfd29 100644
--- a/CleanArchitecture.Domain.Tests/CommandHandler/User/DeleteUser/DeleteUserCommandHandlerTests.cs
+++ b/CleanArchitecture.Domain.Tests/CommandHandler/User/DeleteUser/DeleteUserCommandHandlerTests.cs
@@ -9,14 +9,14 @@ namespace CleanArchitecture.Domain.Tests.CommandHandler.User.DeleteUser;
public sealed class DeleteUserCommandHandlerTests
{
private readonly DeleteUserCommandTestFixture _fixture = new();
-
+
[Fact]
public void Should_Delete_User()
{
var user = _fixture.SetupUser();
-
+
var command = new DeleteUserCommand(user.Id);
-
+
_fixture.CommandHandler.Handle(command, default).Wait();
_fixture
@@ -24,14 +24,14 @@ public sealed class DeleteUserCommandHandlerTests
.VerifyCommit()
.VerifyRaisedEvent(x => x.UserId == user.Id);
}
-
+
[Fact]
public void Should_Not_Delete_Non_Existing_User()
{
_fixture.SetupUser();
-
+
var command = new DeleteUserCommand(Guid.NewGuid());
-
+
_fixture.CommandHandler.Handle(command, default).Wait();
_fixture
diff --git a/CleanArchitecture.Domain.Tests/CommandHandler/User/DeleteUser/DeleteUserCommandTestFixture.cs b/CleanArchitecture.Domain.Tests/CommandHandler/User/DeleteUser/DeleteUserCommandTestFixture.cs
index 149480d..aaf2e66 100644
--- a/CleanArchitecture.Domain.Tests/CommandHandler/User/DeleteUser/DeleteUserCommandTestFixture.cs
+++ b/CleanArchitecture.Domain.Tests/CommandHandler/User/DeleteUser/DeleteUserCommandTestFixture.cs
@@ -8,14 +8,11 @@ namespace CleanArchitecture.Domain.Tests.CommandHandler.User.DeleteUser;
public sealed class DeleteUserCommandTestFixture : CommandHandlerFixtureBase
{
- public DeleteUserCommandHandler CommandHandler { get; }
- private Mock UserRepository { get; }
-
public DeleteUserCommandTestFixture()
{
UserRepository = new Mock();
-
- CommandHandler = new (
+
+ CommandHandler = new DeleteUserCommandHandler(
Bus.Object,
UnitOfWork.Object,
NotificationHandler.Object,
@@ -23,6 +20,9 @@ public sealed class DeleteUserCommandTestFixture : CommandHandlerFixtureBase
User.Object);
}
+ public DeleteUserCommandHandler CommandHandler { get; }
+ private Mock UserRepository { get; }
+
public Entities.User SetupUser()
{
var user = new Entities.User(
diff --git a/CleanArchitecture.Domain.Tests/CommandHandler/User/DeleteUser/DeleteUserCommandValidationTests.cs b/CleanArchitecture.Domain.Tests/CommandHandler/User/DeleteUser/DeleteUserCommandValidationTests.cs
index 50106e5..4ace62f 100644
--- a/CleanArchitecture.Domain.Tests/CommandHandler/User/DeleteUser/DeleteUserCommandValidationTests.cs
+++ b/CleanArchitecture.Domain.Tests/CommandHandler/User/DeleteUser/DeleteUserCommandValidationTests.cs
@@ -16,21 +16,23 @@ public sealed class DeleteUserCommandValidationTests :
public void Should_Be_Valid()
{
var command = CreateTestCommand();
-
+
ShouldBeValid(command);
}
-
+
[Fact]
public void Should_Be_Invalid_For_Empty_User_Id()
{
- var command = CreateTestCommand(userId: Guid.Empty);
-
+ var command = CreateTestCommand(Guid.Empty);
+
ShouldHaveSingleError(
- command,
+ command,
DomainErrorCodes.UserEmptyId,
"User id may not be empty");
}
-
- private DeleteUserCommand CreateTestCommand(Guid? userId = null) =>
- new (userId ?? Guid.NewGuid());
+
+ private DeleteUserCommand CreateTestCommand(Guid? userId = null)
+ {
+ return new(userId ?? Guid.NewGuid());
+ }
}
\ No newline at end of file
diff --git a/CleanArchitecture.Domain.Tests/CommandHandler/User/LoginUser/LoginUserCommandHandlerTests.cs b/CleanArchitecture.Domain.Tests/CommandHandler/User/LoginUser/LoginUserCommandHandlerTests.cs
index 700da13..6137b67 100644
--- a/CleanArchitecture.Domain.Tests/CommandHandler/User/LoginUser/LoginUserCommandHandlerTests.cs
+++ b/CleanArchitecture.Domain.Tests/CommandHandler/User/LoginUser/LoginUserCommandHandlerTests.cs
@@ -79,4 +79,4 @@ public sealed class LoginUserCommandHandlerTests
token.Should().BeEmpty();
}
-}
+}
\ No newline at end of file
diff --git a/CleanArchitecture.Domain.Tests/CommandHandler/User/LoginUser/LoginUserCommandTestFixture.cs b/CleanArchitecture.Domain.Tests/CommandHandler/User/LoginUser/LoginUserCommandTestFixture.cs
index 8010194..71ee339 100644
--- a/CleanArchitecture.Domain.Tests/CommandHandler/User/LoginUser/LoginUserCommandTestFixture.cs
+++ b/CleanArchitecture.Domain.Tests/CommandHandler/User/LoginUser/LoginUserCommandTestFixture.cs
@@ -1,20 +1,16 @@
-using CleanArchitecture.Domain.Commands.Users.LoginUser;
+using System;
+using CleanArchitecture.Domain.Commands.Users.LoginUser;
using CleanArchitecture.Domain.Enums;
using CleanArchitecture.Domain.Interfaces.Repositories;
using CleanArchitecture.Domain.Settings;
using Microsoft.Extensions.Options;
using Moq;
-using System;
using BC = BCrypt.Net.BCrypt;
namespace CleanArchitecture.Domain.Tests.CommandHandler.User.LoginUser;
public sealed class LoginUserCommandTestFixture : CommandHandlerFixtureBase
{
- public LoginUserCommandHandler CommandHandler { get; set; }
- public Mock UserRepository { get; set; }
- public IOptions TokenSettings { get; set; }
-
public LoginUserCommandTestFixture()
{
UserRepository = new Mock();
@@ -26,7 +22,7 @@ public sealed class LoginUserCommandTestFixture : CommandHandlerFixtureBase
Secret = "asjdlkasjd87439284)@#(*"
});
- CommandHandler = new(
+ CommandHandler = new LoginUserCommandHandler(
Bus.Object,
UnitOfWork.Object,
NotificationHandler.Object,
@@ -34,6 +30,10 @@ public sealed class LoginUserCommandTestFixture : CommandHandlerFixtureBase
TokenSettings);
}
+ public LoginUserCommandHandler CommandHandler { get; set; }
+ public Mock UserRepository { get; set; }
+ public IOptions TokenSettings { get; set; }
+
public Entities.User SetupUser()
{
var user = new Entities.User(
@@ -52,4 +52,4 @@ public sealed class LoginUserCommandTestFixture : CommandHandlerFixtureBase
return user;
}
-}
+}
\ No newline at end of file
diff --git a/CleanArchitecture.Domain.Tests/CommandHandler/User/LoginUser/LoginUserCommandValidationTests.cs b/CleanArchitecture.Domain.Tests/CommandHandler/User/LoginUser/LoginUserCommandValidationTests.cs
index 223f711..96fa7c3 100644
--- a/CleanArchitecture.Domain.Tests/CommandHandler/User/LoginUser/LoginUserCommandValidationTests.cs
+++ b/CleanArchitecture.Domain.Tests/CommandHandler/User/LoginUser/LoginUserCommandValidationTests.cs
@@ -12,48 +12,48 @@ public sealed class LoginUserCommandValidationTests :
public LoginUserCommandValidationTests() : base(new LoginUserCommandValidation())
{
}
-
+
[Fact]
public void Should_Be_Valid()
{
var command = CreateTestCommand();
-
+
ShouldBeValid(command);
}
-
+
[Fact]
public void Should_Be_Invalid_For_Empty_Email()
{
- var command = CreateTestCommand(email: string.Empty);
-
+ var command = CreateTestCommand(string.Empty);
+
ShouldHaveSingleError(
command,
DomainErrorCodes.UserInvalidEmail,
"Email is not a valid email address");
}
-
+
[Fact]
public void Should_Be_Invalid_For_Invalid_Email()
{
- var command = CreateTestCommand(email: "not a email");
-
+ var command = CreateTestCommand("not a email");
+
ShouldHaveSingleError(
command,
DomainErrorCodes.UserInvalidEmail,
"Email is not a valid email address");
}
-
+
[Fact]
public void Should_Be_Invalid_For_Email_Exceeds_Max_Length()
{
- var command = CreateTestCommand(email: new string('a', 320) + "@test.com");
-
+ var command = CreateTestCommand(new string('a', 320) + "@test.com");
+
ShouldHaveSingleError(
command,
DomainErrorCodes.UserEmailExceedsMaxLength,
"Email may not be longer than 320 characters");
}
-
+
[Fact]
public void Should_Be_Invalid_For_Empty_Password()
{
@@ -68,62 +68,64 @@ public sealed class LoginUserCommandValidationTests :
DomainErrorCodes.UserUppercaseLetterPassword,
DomainErrorCodes.UserShortPassword
};
-
+
ShouldHaveExpectedErrors(command, errors.ToArray());
}
-
+
[Fact]
public void Should_Be_Invalid_For_Missing_Special_Character()
{
var command = CreateTestCommand(password: "z8tnayvd5FNLU9AQm");
-
+
ShouldHaveSingleError(command, DomainErrorCodes.UserSpecialCharPassword);
}
-
+
[Fact]
public void Should_Be_Invalid_For_Missing_Number()
{
var command = CreateTestCommand(password: "z]tnayvdFNLU:]AQm");
-
+
ShouldHaveSingleError(command, DomainErrorCodes.UserNumberPassword);
}
-
+
[Fact]
public void Should_Be_Invalid_For_Missing_Lowercase_Character()
{
var command = CreateTestCommand(password: "Z8]TNAYVDFNLU:]AQM");
-
+
ShouldHaveSingleError(command, DomainErrorCodes.UserLowercaseLetterPassword);
}
-
+
[Fact]
public void Should_Be_Invalid_For_Missing_Uppercase_Character()
{
var command = CreateTestCommand(password: "z8]tnayvd5fnlu9:]aqm");
-
+
ShouldHaveSingleError(command, DomainErrorCodes.UserUppercaseLetterPassword);
}
-
+
[Fact]
public void Should_Be_Invalid_For_Password_Too_Short()
{
var command = CreateTestCommand(password: "zA6{");
-
+
ShouldHaveSingleError(command, DomainErrorCodes.UserShortPassword);
}
-
+
[Fact]
public void Should_Be_Invalid_For_Password_Too_Long()
{
var command = CreateTestCommand(password: string.Concat(Enumerable.Repeat("zA6{", 12), 12));
-
+
ShouldHaveSingleError(command, DomainErrorCodes.UserLongPassword);
}
-
+
private LoginUserCommand CreateTestCommand(
string? email = null,
- string? password = null) =>
- new (
+ string? password = null)
+ {
+ return new(
email ?? "test@email.com",
password ?? "Po=PF]PC6t.?8?ks)A6W");
-}
+ }
+}
\ No newline at end of file
diff --git a/CleanArchitecture.Domain.Tests/CommandHandler/User/UpdateUser/UpdateUserCommandHandlerTests.cs b/CleanArchitecture.Domain.Tests/CommandHandler/User/UpdateUser/UpdateUserCommandHandlerTests.cs
index 3fcb757..98a13df 100644
--- a/CleanArchitecture.Domain.Tests/CommandHandler/User/UpdateUser/UpdateUserCommandHandlerTests.cs
+++ b/CleanArchitecture.Domain.Tests/CommandHandler/User/UpdateUser/UpdateUserCommandHandlerTests.cs
@@ -11,19 +11,19 @@ namespace CleanArchitecture.Domain.Tests.CommandHandler.User.UpdateUser;
public sealed class UpdateUserCommandHandlerTests
{
private readonly UpdateUserCommandTestFixture _fixture = new();
-
+
[Fact]
public async Task Should_Update_User()
{
var user = _fixture.SetupUser();
-
+
var command = new UpdateUserCommand(
user.Id,
"test@email.com",
"Test",
"Email",
UserRole.User);
-
+
await _fixture.CommandHandler.Handle(command, default);
_fixture
@@ -31,19 +31,19 @@ public sealed class UpdateUserCommandHandlerTests
.VerifyCommit()
.VerifyRaisedEvent(x => x.UserId == command.UserId);
}
-
+
[Fact]
public async Task Should_Not_Update_Non_Existing_User()
{
_fixture.SetupUser();
-
+
var command = new UpdateUserCommand(
Guid.NewGuid(),
"test@email.com",
"Test",
"Email",
UserRole.User);
-
+
await _fixture.CommandHandler.Handle(command, default);
_fixture
diff --git a/CleanArchitecture.Domain.Tests/CommandHandler/User/UpdateUser/UpdateUserCommandTestFixture.cs b/CleanArchitecture.Domain.Tests/CommandHandler/User/UpdateUser/UpdateUserCommandTestFixture.cs
index bb4e581..69bb3ca 100644
--- a/CleanArchitecture.Domain.Tests/CommandHandler/User/UpdateUser/UpdateUserCommandTestFixture.cs
+++ b/CleanArchitecture.Domain.Tests/CommandHandler/User/UpdateUser/UpdateUserCommandTestFixture.cs
@@ -8,21 +8,21 @@ namespace CleanArchitecture.Domain.Tests.CommandHandler.User.UpdateUser;
public sealed class UpdateUserCommandTestFixture : CommandHandlerFixtureBase
{
- public UpdateUserCommandHandler CommandHandler { get; }
- private Mock UserRepository { get; }
-
public UpdateUserCommandTestFixture()
{
UserRepository = new Mock();
-
- CommandHandler = new(
+
+ CommandHandler = new UpdateUserCommandHandler(
Bus.Object,
UnitOfWork.Object,
NotificationHandler.Object,
UserRepository.Object,
User.Object);
}
-
+
+ public UpdateUserCommandHandler CommandHandler { get; }
+ private Mock UserRepository { get; }
+
public Entities.User SetupUser()
{
var user = new Entities.User(
diff --git a/CleanArchitecture.Domain.Tests/CommandHandler/User/UpdateUser/UpdateUserCommandValidationTests.cs b/CleanArchitecture.Domain.Tests/CommandHandler/User/UpdateUser/UpdateUserCommandValidationTests.cs
index dcf9d11..2fe4e21 100644
--- a/CleanArchitecture.Domain.Tests/CommandHandler/User/UpdateUser/UpdateUserCommandValidationTests.cs
+++ b/CleanArchitecture.Domain.Tests/CommandHandler/User/UpdateUser/UpdateUserCommandValidationTests.cs
@@ -12,113 +12,115 @@ public sealed class UpdateUserCommandValidationTests :
public UpdateUserCommandValidationTests() : base(new UpdateUserCommandValidation())
{
}
-
+
[Fact]
public void Should_Be_Valid()
{
var command = CreateTestCommand();
-
+
ShouldBeValid(command);
}
-
+
[Fact]
public void Should_Be_Invalid_For_Empty_User_Id()
{
- var command = CreateTestCommand(userId: Guid.Empty);
-
+ var command = CreateTestCommand(Guid.Empty);
+
ShouldHaveSingleError(
- command,
+ command,
DomainErrorCodes.UserEmptyId,
"User id may not be empty");
}
-
+
[Fact]
public void Should_Be_Invalid_For_Empty_Email()
{
var command = CreateTestCommand(email: string.Empty);
-
+
ShouldHaveSingleError(
command,
DomainErrorCodes.UserInvalidEmail,
"Email is not a valid email address");
}
-
+
[Fact]
public void Should_Be_Invalid_For_Invalid_Email()
{
var command = CreateTestCommand(email: "not a email");
-
+
ShouldHaveSingleError(
command,
DomainErrorCodes.UserInvalidEmail,
"Email is not a valid email address");
}
-
+
[Fact]
public void Should_Be_Invalid_For_Email_Exceeds_Max_Length()
{
var command = CreateTestCommand(email: new string('a', 320) + "@test.com");
-
+
ShouldHaveSingleError(
command,
DomainErrorCodes.UserEmailExceedsMaxLength,
"Email may not be longer than 320 characters");
}
-
+
[Fact]
public void Should_Be_Invalid_For_Empty_Surname()
{
var command = CreateTestCommand(surName: "");
-
+
ShouldHaveSingleError(
command,
DomainErrorCodes.UserEmptySurname,
"Surname may not be empty");
}
-
+
[Fact]
public void Should_Be_Invalid_For_Surname_Exceeds_Max_Length()
{
var command = CreateTestCommand(surName: new string('a', 101));
-
+
ShouldHaveSingleError(
command,
DomainErrorCodes.UserSurnameExceedsMaxLength,
"Surname may not be longer than 100 characters");
}
-
+
[Fact]
public void Should_Be_Invalid_For_Empty_Given_Name()
{
var command = CreateTestCommand(givenName: "");
-
+
ShouldHaveSingleError(
command,
DomainErrorCodes.UserEmptyGivenName,
"Given name may not be empty");
}
-
+
[Fact]
public void Should_Be_Invalid_For_Given_Name_Exceeds_Max_Length()
{
var command = CreateTestCommand(givenName: new string('a', 101));
-
+
ShouldHaveSingleError(
command,
DomainErrorCodes.UserGivenNameExceedsMaxLength,
"Given name may not be longer than 100 characters");
}
-
+
private static UpdateUserCommand CreateTestCommand(
Guid? userId = null,
string? email = null,
string? surName = null,
string? givenName = null,
- UserRole? role = null) =>
- new (
+ UserRole? role = null)
+ {
+ return new(
userId ?? Guid.NewGuid(),
email ?? "test@email.com",
surName ?? "test",
givenName ?? "email",
role ?? UserRole.User);
+ }
}
\ No newline at end of file
diff --git a/CleanArchitecture.Domain.Tests/CommandHandlerFixtureBase.cs b/CleanArchitecture.Domain.Tests/CommandHandlerFixtureBase.cs
index a8e464c..ce8a493 100644
--- a/CleanArchitecture.Domain.Tests/CommandHandlerFixtureBase.cs
+++ b/CleanArchitecture.Domain.Tests/CommandHandlerFixtureBase.cs
@@ -9,24 +9,24 @@ namespace CleanArchitecture.Domain.Tests;
public class CommandHandlerFixtureBase
{
- protected Mock Bus { get; }
- protected Mock UnitOfWork { get; }
- protected Mock NotificationHandler { get; }
- protected Mock User { get; }
-
protected CommandHandlerFixtureBase()
{
Bus = new Mock();
UnitOfWork = new Mock();
NotificationHandler = new Mock();
User = new Mock();
-
+
User.Setup(x => x.GetUserId()).Returns(Guid.NewGuid());
User.Setup(x => x.GetUserRole()).Returns(UserRole.Admin);
UnitOfWork.Setup(unit => unit.CommitAsync()).ReturnsAsync(true);
}
+ protected Mock Bus { get; }
+ protected Mock UnitOfWork { get; }
+ protected Mock NotificationHandler { get; }
+ protected Mock User { get; }
+
public CommandHandlerFixtureBase VerifyExistingNotification(string errorCode, string message)
{
Bus.Verify(
diff --git a/CleanArchitecture.Domain.Tests/ValidationTestBase.cs b/CleanArchitecture.Domain.Tests/ValidationTestBase.cs
index cbb3692..37391ee 100644
--- a/CleanArchitecture.Domain.Tests/ValidationTestBase.cs
+++ b/CleanArchitecture.Domain.Tests/ValidationTestBase.cs
@@ -8,7 +8,7 @@ namespace CleanArchitecture.Domain.Tests;
public class ValidationTestBase
where TCommand : CommandBase
- where TValidation: AbstractValidator
+ where TValidation : AbstractValidator
{
private readonly TValidation _validation;
@@ -54,7 +54,7 @@ public class ValidationTestBase
}
protected void ShouldHaveExpectedErrors(
- TCommand command,
+ TCommand command,
params KeyValuePair[] expectedErrors)
{
var result = _validation.Validate(command);
@@ -70,9 +70,9 @@ public class ValidationTestBase
.Be(1);
}
}
-
+
protected void ShouldHaveExpectedErrors(
- TCommand command,
+ TCommand command,
params string[] expectedErrors)
{
var result = _validation.Validate(command);
diff --git a/CleanArchitecture.Domain/ApiUser.cs b/CleanArchitecture.Domain/ApiUser.cs
index c991c79..15912af 100644
--- a/CleanArchitecture.Domain/ApiUser.cs
+++ b/CleanArchitecture.Domain/ApiUser.cs
@@ -29,19 +29,6 @@ public sealed class ApiUser : IUser
throw new ArgumentException("Could not parse user id to guid");
}
- public string GetUserEmail()
- {
- var claim = _httpContextAccessor.HttpContext?.User.Claims
- .FirstOrDefault(x => string.Equals(x.Type, ClaimTypes.Email));
-
- if (!string.IsNullOrWhiteSpace(claim?.Value))
- {
- return claim?.Value!;
- }
-
- throw new ArgumentException("Could not parse user email");
- }
-
public UserRole GetUserRole()
{
var claim = _httpContextAccessor.HttpContext?.User.Claims
@@ -56,4 +43,17 @@ public sealed class ApiUser : IUser
}
public string Name => _httpContextAccessor.HttpContext?.User.Identity?.Name ?? string.Empty;
-}
+
+ public string GetUserEmail()
+ {
+ var claim = _httpContextAccessor.HttpContext?.User.Claims
+ .FirstOrDefault(x => string.Equals(x.Type, ClaimTypes.Email));
+
+ if (!string.IsNullOrWhiteSpace(claim?.Value))
+ {
+ return claim?.Value!;
+ }
+
+ throw new ArgumentException("Could not parse user email");
+ }
+}
\ No newline at end of file
diff --git a/CleanArchitecture.Domain/CleanArchitecture.Domain.csproj b/CleanArchitecture.Domain/CleanArchitecture.Domain.csproj
index bd7f84a..3774cae 100644
--- a/CleanArchitecture.Domain/CleanArchitecture.Domain.csproj
+++ b/CleanArchitecture.Domain/CleanArchitecture.Domain.csproj
@@ -6,12 +6,12 @@
-
-
-
-
-
-
+
+
+
+
+
+
diff --git a/CleanArchitecture.Domain/Commands/CommandBase.cs b/CleanArchitecture.Domain/Commands/CommandBase.cs
index 25f84f6..02d78d1 100644
--- a/CleanArchitecture.Domain/Commands/CommandBase.cs
+++ b/CleanArchitecture.Domain/Commands/CommandBase.cs
@@ -6,17 +6,17 @@ namespace CleanArchitecture.Domain.Commands;
public abstract class CommandBase : IRequest
{
- public Guid AggregateId { get; }
- public string MessageType { get; }
- public DateTime Timestamp { get; }
- public ValidationResult? ValidationResult { get; protected set; }
-
protected CommandBase(Guid aggregateId)
{
MessageType = GetType().Name;
Timestamp = DateTime.Now;
AggregateId = aggregateId;
}
-
+
+ public Guid AggregateId { get; }
+ public string MessageType { get; }
+ public DateTime Timestamp { get; }
+ public ValidationResult? ValidationResult { get; protected set; }
+
public abstract bool IsValid();
}
\ No newline at end of file
diff --git a/CleanArchitecture.Domain/Commands/CommandHandlerBase.cs b/CleanArchitecture.Domain/Commands/CommandHandlerBase.cs
index fe9b36c..14d6877 100644
--- a/CleanArchitecture.Domain/Commands/CommandHandlerBase.cs
+++ b/CleanArchitecture.Domain/Commands/CommandHandlerBase.cs
@@ -10,8 +10,8 @@ namespace CleanArchitecture.Domain.Commands;
public abstract class CommandHandlerBase
{
protected readonly IMediatorHandler _bus;
- private readonly IUnitOfWork _unitOfWork;
private readonly DomainNotificationHandler _notifications;
+ private readonly IUnitOfWork _unitOfWork;
protected CommandHandlerBase(
IMediatorHandler bus,
@@ -22,7 +22,7 @@ public abstract class CommandHandlerBase
_unitOfWork = unitOfWork;
_notifications = (DomainNotificationHandler)notifications;
}
-
+
public async Task CommitAsync()
{
if (_notifications.HasNotifications())
@@ -43,7 +43,7 @@ public abstract class CommandHandlerBase
return false;
}
-
+
protected async Task NotifyAsync(string key, string message, string code)
{
await _bus.RaiseEventAsync(
@@ -54,7 +54,7 @@ public abstract class CommandHandlerBase
{
await _bus.RaiseEventAsync(notification);
}
-
+
protected async ValueTask TestValidityAsync(CommandBase command)
{
if (command.IsValid())
@@ -71,8 +71,8 @@ public abstract class CommandHandlerBase
{
await NotifyAsync(
new DomainNotification(
- command.MessageType,
- error.ErrorMessage,
+ command.MessageType,
+ error.ErrorMessage,
error.ErrorCode,
error.FormattedMessagePlaceholderValues));
}
diff --git a/CleanArchitecture.Domain/Commands/Users/ChangePassword/ChangePasswordCommand.cs b/CleanArchitecture.Domain/Commands/Users/ChangePassword/ChangePasswordCommand.cs
index 44f0d86..4a27534 100644
--- a/CleanArchitecture.Domain/Commands/Users/ChangePassword/ChangePasswordCommand.cs
+++ b/CleanArchitecture.Domain/Commands/Users/ChangePassword/ChangePasswordCommand.cs
@@ -6,15 +6,15 @@ public sealed class ChangePasswordCommand : CommandBase
{
private readonly ChangePasswordCommandValidation _validation = new();
- public string Password { get; }
- public string NewPassword { get; }
-
public ChangePasswordCommand(string password, string newPassword) : base(Guid.NewGuid())
{
Password = password;
NewPassword = newPassword;
}
+ public string Password { get; }
+ public string NewPassword { get; }
+
public override bool IsValid()
{
ValidationResult = _validation.Validate(this);
diff --git a/CleanArchitecture.Domain/Commands/Users/ChangePassword/ChangePasswordCommandHandler.cs b/CleanArchitecture.Domain/Commands/Users/ChangePassword/ChangePasswordCommandHandler.cs
index 4bd41e0..8b5ef24 100644
--- a/CleanArchitecture.Domain/Commands/Users/ChangePassword/ChangePasswordCommandHandler.cs
+++ b/CleanArchitecture.Domain/Commands/Users/ChangePassword/ChangePasswordCommandHandler.cs
@@ -13,8 +13,8 @@ namespace CleanArchitecture.Domain.Commands.Users.ChangePassword;
public sealed class ChangePasswordCommandHandler : CommandHandlerBase,
IRequestHandler
{
- private readonly IUserRepository _userRepository;
private readonly IUser _user;
+ private readonly IUserRepository _userRepository;
public ChangePasswordCommandHandler(
IMediatorHandler bus,
@@ -68,4 +68,4 @@ public sealed class ChangePasswordCommandHandler : CommandHandlerBase,
await _bus.RaiseEventAsync(new PasswordChangedEvent(user.Id));
}
}
-}
+}
\ No newline at end of file
diff --git a/CleanArchitecture.Domain/Commands/Users/ChangePassword/ChangePasswordCommandValidation.cs b/CleanArchitecture.Domain/Commands/Users/ChangePassword/ChangePasswordCommandValidation.cs
index e90e964..83ea0d9 100644
--- a/CleanArchitecture.Domain/Commands/Users/ChangePassword/ChangePasswordCommandValidation.cs
+++ b/CleanArchitecture.Domain/Commands/Users/ChangePassword/ChangePasswordCommandValidation.cs
@@ -22,4 +22,4 @@ public sealed class ChangePasswordCommandValidation : AbstractValidator cmd.NewPassword)
.Password();
}
-}
+}
\ No newline at end of file
diff --git a/CleanArchitecture.Domain/Commands/Users/CreateUser/CreateUserCommand.cs b/CleanArchitecture.Domain/Commands/Users/CreateUser/CreateUserCommand.cs
index 7185a16..bafd286 100644
--- a/CleanArchitecture.Domain/Commands/Users/CreateUser/CreateUserCommand.cs
+++ b/CleanArchitecture.Domain/Commands/Users/CreateUser/CreateUserCommand.cs
@@ -4,13 +4,7 @@ namespace CleanArchitecture.Domain.Commands.Users.CreateUser;
public sealed class CreateUserCommand : CommandBase
{
- private readonly CreateUserCommandValidation _validation = new();
-
- public Guid UserId { get; }
- public string Email { get; }
- public string Surname { get; }
- public string GivenName { get; }
- public string Password { get; }
+ private readonly CreateUserCommandValidation _validation = new();
public CreateUserCommand(
Guid userId,
@@ -26,6 +20,12 @@ public sealed class CreateUserCommand : CommandBase
Password = password;
}
+ public Guid UserId { get; }
+ public string Email { get; }
+ public string Surname { get; }
+ public string GivenName { get; }
+ public string Password { get; }
+
public override bool IsValid()
{
ValidationResult = _validation.Validate(this);
diff --git a/CleanArchitecture.Domain/Commands/Users/CreateUser/CreateUserCommandHandler.cs b/CleanArchitecture.Domain/Commands/Users/CreateUser/CreateUserCommandHandler.cs
index 2f7f511..382a529 100644
--- a/CleanArchitecture.Domain/Commands/Users/CreateUser/CreateUserCommandHandler.cs
+++ b/CleanArchitecture.Domain/Commands/Users/CreateUser/CreateUserCommandHandler.cs
@@ -16,7 +16,7 @@ public sealed class CreateUserCommandHandler : CommandHandlerBase,
IRequestHandler
{
private readonly IUserRepository _userRepository;
-
+
public CreateUserCommandHandler(
IMediatorHandler bus,
IUnitOfWork unitOfWork,
@@ -44,9 +44,9 @@ public sealed class CreateUserCommandHandler : CommandHandlerBase,
DomainErrorCodes.UserAlreadyExists));
return;
}
-
+
existingUser = await _userRepository.GetByEmailAsync(request.Email);
-
+
if (existingUser != null)
{
await _bus.RaiseEventAsync(
@@ -60,15 +60,15 @@ public sealed class CreateUserCommandHandler : CommandHandlerBase,
var passwordHash = BC.HashPassword(request.Password);
var user = new User(
- request.UserId,
+ request.UserId,
request.Email,
request.Surname,
request.GivenName,
passwordHash,
UserRole.User);
-
+
_userRepository.Add(user);
-
+
if (await CommitAsync())
{
await _bus.RaiseEventAsync(new UserCreatedEvent(user.Id));
diff --git a/CleanArchitecture.Domain/Commands/Users/CreateUser/CreateUserCommandValidation.cs b/CleanArchitecture.Domain/Commands/Users/CreateUser/CreateUserCommandValidation.cs
index e1b7ed9..23be1aa 100644
--- a/CleanArchitecture.Domain/Commands/Users/CreateUser/CreateUserCommandValidation.cs
+++ b/CleanArchitecture.Domain/Commands/Users/CreateUser/CreateUserCommandValidation.cs
@@ -22,7 +22,7 @@ public sealed class CreateUserCommandValidation : AbstractValidator cmd.Email)
@@ -33,7 +33,7 @@ public sealed class CreateUserCommandValidation : AbstractValidator cmd.Surname)
@@ -44,7 +44,7 @@ public sealed class CreateUserCommandValidation : AbstractValidator cmd.GivenName)
@@ -55,7 +55,7 @@ public sealed class CreateUserCommandValidation : AbstractValidator cmd.Password)
diff --git a/CleanArchitecture.Domain/Commands/Users/DeleteUser/DeleteUserCommand.cs b/CleanArchitecture.Domain/Commands/Users/DeleteUser/DeleteUserCommand.cs
index a15d7d6..48c42f5 100644
--- a/CleanArchitecture.Domain/Commands/Users/DeleteUser/DeleteUserCommand.cs
+++ b/CleanArchitecture.Domain/Commands/Users/DeleteUser/DeleteUserCommand.cs
@@ -4,15 +4,15 @@ namespace CleanArchitecture.Domain.Commands.Users.DeleteUser;
public sealed class DeleteUserCommand : CommandBase
{
- private readonly DeleteUserCommandValidation _validation = new();
-
- public Guid UserId { get; }
-
+ private readonly DeleteUserCommandValidation _validation = new();
+
public DeleteUserCommand(Guid userId) : base(userId)
{
UserId = userId;
}
+ public Guid UserId { get; }
+
public override bool IsValid()
{
ValidationResult = _validation.Validate(this);
diff --git a/CleanArchitecture.Domain/Commands/Users/DeleteUser/DeleteUserCommandHandler.cs b/CleanArchitecture.Domain/Commands/Users/DeleteUser/DeleteUserCommandHandler.cs
index 366c240..d40495f 100644
--- a/CleanArchitecture.Domain/Commands/Users/DeleteUser/DeleteUserCommandHandler.cs
+++ b/CleanArchitecture.Domain/Commands/Users/DeleteUser/DeleteUserCommandHandler.cs
@@ -13,8 +13,8 @@ namespace CleanArchitecture.Domain.Commands.Users.DeleteUser;
public sealed class DeleteUserCommandHandler : CommandHandlerBase,
IRequestHandler
{
- private readonly IUserRepository _userRepository;
private readonly IUser _user;
+ private readonly IUserRepository _userRepository;
public DeleteUserCommandHandler(
IMediatorHandler bus,
@@ -35,7 +35,7 @@ public sealed class DeleteUserCommandHandler : CommandHandlerBase,
}
var user = await _userRepository.GetByIdAsync(request.UserId);
-
+
if (user == null)
{
await NotifyAsync(
@@ -54,7 +54,7 @@ public sealed class DeleteUserCommandHandler : CommandHandlerBase,
request.MessageType,
$"No permission to delete user {request.UserId}",
ErrorCodes.InsufficientPermissions));
-
+
return;
}
diff --git a/CleanArchitecture.Domain/Commands/Users/LoginUser/LoginUserCommand.cs b/CleanArchitecture.Domain/Commands/Users/LoginUser/LoginUserCommand.cs
index b0a7999..2fcdc00 100644
--- a/CleanArchitecture.Domain/Commands/Users/LoginUser/LoginUserCommand.cs
+++ b/CleanArchitecture.Domain/Commands/Users/LoginUser/LoginUserCommand.cs
@@ -8,9 +8,6 @@ public sealed class LoginUserCommand : CommandBase,
{
private readonly LoginUserCommandValidation _validation = new();
- public string Email { get; set; }
- public string Password { get; set; }
-
public LoginUserCommand(
string email,
@@ -20,6 +17,9 @@ public sealed class LoginUserCommand : CommandBase,
Password = password;
}
+ public string Email { get; set; }
+ public string Password { get; set; }
+
public override bool IsValid()
{
ValidationResult = _validation.Validate(this);
diff --git a/CleanArchitecture.Domain/Commands/Users/LoginUser/LoginUserCommandHandler.cs b/CleanArchitecture.Domain/Commands/Users/LoginUser/LoginUserCommandHandler.cs
index 9998952..c93e2c1 100644
--- a/CleanArchitecture.Domain/Commands/Users/LoginUser/LoginUserCommandHandler.cs
+++ b/CleanArchitecture.Domain/Commands/Users/LoginUser/LoginUserCommandHandler.cs
@@ -1,6 +1,7 @@
-using System.Security.Claims;
+using System;
+using System.IdentityModel.Tokens.Jwt;
+using System.Security.Claims;
using System.Text;
-using System;
using System.Threading;
using System.Threading.Tasks;
using CleanArchitecture.Domain.Enums;
@@ -10,10 +11,9 @@ using CleanArchitecture.Domain.Interfaces.Repositories;
using CleanArchitecture.Domain.Notifications;
using CleanArchitecture.Domain.Settings;
using MediatR;
-using BC = BCrypt.Net.BCrypt;
-using System.IdentityModel.Tokens.Jwt;
-using Microsoft.IdentityModel.Tokens;
using Microsoft.Extensions.Options;
+using Microsoft.IdentityModel.Tokens;
+using BC = BCrypt.Net.BCrypt;
namespace CleanArchitecture.Domain.Commands.Users.LoginUser;
@@ -21,9 +21,9 @@ public sealed class LoginUserCommandHandler : CommandHandlerBase,
IRequestHandler
{
private const double ExpiryDurationMinutes = 30;
+ private readonly TokenSettings _tokenSettings;
private readonly IUserRepository _userRepository;
- private readonly TokenSettings _tokenSettings;
public LoginUserCommandHandler(
IMediatorHandler bus,
@@ -80,10 +80,10 @@ public sealed class LoginUserCommandHandler : CommandHandlerBase,
{
var claims = new[]
{
- new Claim(ClaimTypes.Email, email),
- new Claim(ClaimTypes.Role, role.ToString()),
- new Claim(ClaimTypes.NameIdentifier, id.ToString())
- };
+ new Claim(ClaimTypes.Email, email),
+ new Claim(ClaimTypes.Role, role.ToString()),
+ new Claim(ClaimTypes.NameIdentifier, id.ToString())
+ };
var securityKey = new SymmetricSecurityKey(
Encoding.UTF8.GetBytes(tokenSettings.Secret));
@@ -101,4 +101,4 @@ public sealed class LoginUserCommandHandler : CommandHandlerBase,
return new JwtSecurityTokenHandler().WriteToken(tokenDescriptor);
}
-}
+}
\ No newline at end of file
diff --git a/CleanArchitecture.Domain/Commands/Users/LoginUser/LoginUserCommandValidation.cs b/CleanArchitecture.Domain/Commands/Users/LoginUser/LoginUserCommandValidation.cs
index 64bc452..9f668cd 100644
--- a/CleanArchitecture.Domain/Commands/Users/LoginUser/LoginUserCommandValidation.cs
+++ b/CleanArchitecture.Domain/Commands/Users/LoginUser/LoginUserCommandValidation.cs
@@ -28,4 +28,4 @@ public sealed class LoginUserCommandValidation : AbstractValidator cmd.Password)
.Password();
}
-}
+}
\ No newline at end of file
diff --git a/CleanArchitecture.Domain/Commands/Users/UpdateUser/UpdateUserCommand.cs b/CleanArchitecture.Domain/Commands/Users/UpdateUser/UpdateUserCommand.cs
index d561e47..918bec9 100644
--- a/CleanArchitecture.Domain/Commands/Users/UpdateUser/UpdateUserCommand.cs
+++ b/CleanArchitecture.Domain/Commands/Users/UpdateUser/UpdateUserCommand.cs
@@ -6,12 +6,6 @@ namespace CleanArchitecture.Domain.Commands.Users.UpdateUser;
public sealed class UpdateUserCommand : CommandBase
{
private readonly UpdateUserCommandValidation _validation = new();
-
- public Guid UserId { get; }
- public string Email { get; }
- public string Surname { get; }
- public string GivenName { get; }
- public UserRole Role { get; }
public UpdateUserCommand(
Guid userId,
@@ -27,6 +21,12 @@ public sealed class UpdateUserCommand : CommandBase
Role = role;
}
+ public Guid UserId { get; }
+ public string Email { get; }
+ public string Surname { get; }
+ public string GivenName { get; }
+ public UserRole Role { get; }
+
public override bool IsValid()
{
ValidationResult = _validation.Validate(this);
diff --git a/CleanArchitecture.Domain/Commands/Users/UpdateUser/UpdateUserCommandHandler.cs b/CleanArchitecture.Domain/Commands/Users/UpdateUser/UpdateUserCommandHandler.cs
index bbf140c..02d87cd 100644
--- a/CleanArchitecture.Domain/Commands/Users/UpdateUser/UpdateUserCommandHandler.cs
+++ b/CleanArchitecture.Domain/Commands/Users/UpdateUser/UpdateUserCommandHandler.cs
@@ -1,6 +1,5 @@
using System.Threading;
using System.Threading.Tasks;
-using CleanArchitecture.Domain.Entities;
using CleanArchitecture.Domain.Enums;
using CleanArchitecture.Domain.Errors;
using CleanArchitecture.Domain.Events.User;
@@ -14,8 +13,8 @@ namespace CleanArchitecture.Domain.Commands.Users.UpdateUser;
public sealed class UpdateUserCommandHandler : CommandHandlerBase,
IRequestHandler
{
- private readonly IUserRepository _userRepository;
private readonly IUser _user;
+ private readonly IUserRepository _userRepository;
public UpdateUserCommandHandler(
IMediatorHandler bus,
@@ -54,7 +53,7 @@ public sealed class UpdateUserCommandHandler : CommandHandlerBase,
request.MessageType,
$"No permission to update user {request.UserId}",
ErrorCodes.InsufficientPermissions));
-
+
return;
}
@@ -68,7 +67,7 @@ public sealed class UpdateUserCommandHandler : CommandHandlerBase,
user.SetGivenName(request.GivenName);
_userRepository.Update(user);
-
+
if (await CommitAsync())
{
await _bus.RaiseEventAsync(new UserUpdatedEvent(user.Id));
diff --git a/CleanArchitecture.Domain/Commands/Users/UpdateUser/UpdateUserCommandValidation.cs b/CleanArchitecture.Domain/Commands/Users/UpdateUser/UpdateUserCommandValidation.cs
index 58a901f..f0afc67 100644
--- a/CleanArchitecture.Domain/Commands/Users/UpdateUser/UpdateUserCommandValidation.cs
+++ b/CleanArchitecture.Domain/Commands/Users/UpdateUser/UpdateUserCommandValidation.cs
@@ -21,7 +21,7 @@ public sealed class UpdateUserCommandValidation : AbstractValidator cmd.Email)
@@ -32,7 +32,7 @@ public sealed class UpdateUserCommandValidation : AbstractValidator cmd.Surname)
@@ -43,7 +43,7 @@ public sealed class UpdateUserCommandValidation : AbstractValidator cmd.GivenName)
diff --git a/CleanArchitecture.Domain/Entities/User.cs b/CleanArchitecture.Domain/Entities/User.cs
index 2d14858..b92cd3e 100644
--- a/CleanArchitecture.Domain/Entities/User.cs
+++ b/CleanArchitecture.Domain/Entities/User.cs
@@ -6,14 +6,6 @@ namespace CleanArchitecture.Domain.Entities;
public class User : Entity
{
- public string Email { get; private set; }
- public string GivenName { get; private set; }
- public string Surname { get; private set; }
- public string Password { get; private set; }
- public UserRole Role { get; private set; }
-
- public string FullName => $"{Surname}, {GivenName}";
-
public User(
Guid id,
string email,
@@ -29,6 +21,14 @@ public class User : Entity
Role = role;
}
+ public string Email { get; private set; }
+ public string GivenName { get; private set; }
+ public string Surname { get; private set; }
+ public string Password { get; private set; }
+ public UserRole Role { get; private set; }
+
+ public string FullName => $"{Surname}, {GivenName}";
+
[MemberNotNull(nameof(Email))]
public void SetEmail(string email)
{
@@ -45,7 +45,7 @@ public class User : Entity
Email = email;
}
-
+
[MemberNotNull(nameof(GivenName))]
public void SetGivenName(string givenName)
{
@@ -62,7 +62,7 @@ public class User : Entity
GivenName = givenName;
}
-
+
[MemberNotNull(nameof(Surname))]
public void SetSurname(string surname)
{
diff --git a/CleanArchitecture.Domain/Enums/UserRole.cs b/CleanArchitecture.Domain/Enums/UserRole.cs
index 95c9259..f95d8e1 100644
--- a/CleanArchitecture.Domain/Enums/UserRole.cs
+++ b/CleanArchitecture.Domain/Enums/UserRole.cs
@@ -4,4 +4,4 @@ public enum UserRole
{
Admin,
User
-}
+}
\ No newline at end of file
diff --git a/CleanArchitecture.Domain/Errors/DomainErrorCodes.cs b/CleanArchitecture.Domain/Errors/DomainErrorCodes.cs
index 76925e2..6c486cf 100644
--- a/CleanArchitecture.Domain/Errors/DomainErrorCodes.cs
+++ b/CleanArchitecture.Domain/Errors/DomainErrorCodes.cs
@@ -20,7 +20,7 @@ public static class DomainErrorCodes
public const string UserLowercaseLetterPassword = "USER_PASSWORD_MUST_CONTAIN_A_LOWERCASE_LETTER";
public const string UserNumberPassword = "USER_PASSWORD_MUST_CONTAIN_A_NUMBER";
public const string UserSpecialCharPassword = "USER_PASSWORD_MUST_CONTAIN_A_SPECIAL_CHARACTER";
-
+
// User
public const string UserAlreadyExists = "USER_ALREADY_EXISTS";
public const string UserPasswordIncorrect = "USER_PASSWORD_INCORRECT";
diff --git a/CleanArchitecture.Domain/EventHandler/UserEventHandler.cs b/CleanArchitecture.Domain/EventHandler/UserEventHandler.cs
index a6f7e47..3e29e28 100644
--- a/CleanArchitecture.Domain/EventHandler/UserEventHandler.cs
+++ b/CleanArchitecture.Domain/EventHandler/UserEventHandler.cs
@@ -11,7 +11,7 @@ public sealed class UserEventHandler :
INotificationHandler,
INotificationHandler
{
- public Task Handle(UserDeletedEvent notification, CancellationToken cancellationToken)
+ public Task Handle(PasswordChangedEvent notification, CancellationToken cancellationToken)
{
return Task.CompletedTask;
}
@@ -20,13 +20,13 @@ public sealed class UserEventHandler :
{
return Task.CompletedTask;
}
-
- public Task Handle(UserUpdatedEvent notification, CancellationToken cancellationToken)
+
+ public Task Handle(UserDeletedEvent notification, CancellationToken cancellationToken)
{
return Task.CompletedTask;
}
- public Task Handle(PasswordChangedEvent notification, CancellationToken cancellationToken)
+ public Task Handle(UserUpdatedEvent notification, CancellationToken cancellationToken)
{
return Task.CompletedTask;
}
diff --git a/CleanArchitecture.Domain/Events/User/PasswordChangedEvent.cs b/CleanArchitecture.Domain/Events/User/PasswordChangedEvent.cs
index 32e7a53..7ebb021 100644
--- a/CleanArchitecture.Domain/Events/User/PasswordChangedEvent.cs
+++ b/CleanArchitecture.Domain/Events/User/PasswordChangedEvent.cs
@@ -4,10 +4,10 @@ namespace CleanArchitecture.Domain.Events.User;
public sealed class PasswordChangedEvent : DomainEvent
{
- public Guid UserId { get; }
-
public PasswordChangedEvent(Guid userId) : base(userId)
{
UserId = userId;
}
-}
+
+ public Guid UserId { get; }
+}
\ No newline at end of file
diff --git a/CleanArchitecture.Domain/Events/User/UserCreatedEvent.cs b/CleanArchitecture.Domain/Events/User/UserCreatedEvent.cs
index 19f3658..2a67c9b 100644
--- a/CleanArchitecture.Domain/Events/User/UserCreatedEvent.cs
+++ b/CleanArchitecture.Domain/Events/User/UserCreatedEvent.cs
@@ -4,10 +4,10 @@ namespace CleanArchitecture.Domain.Events.User;
public sealed class UserCreatedEvent : DomainEvent
{
- public Guid UserId { get; }
-
public UserCreatedEvent(Guid userId) : base(userId)
{
UserId = userId;
}
+
+ public Guid UserId { get; }
}
\ No newline at end of file
diff --git a/CleanArchitecture.Domain/Events/User/UserDeletedEvent.cs b/CleanArchitecture.Domain/Events/User/UserDeletedEvent.cs
index 576bcbf..89fadc1 100644
--- a/CleanArchitecture.Domain/Events/User/UserDeletedEvent.cs
+++ b/CleanArchitecture.Domain/Events/User/UserDeletedEvent.cs
@@ -4,10 +4,10 @@ namespace CleanArchitecture.Domain.Events.User;
public sealed class UserDeletedEvent : DomainEvent
{
- public Guid UserId { get; }
-
public UserDeletedEvent(Guid userId) : base(userId)
{
UserId = userId;
}
+
+ public Guid UserId { get; }
}
\ No newline at end of file
diff --git a/CleanArchitecture.Domain/Events/User/UserUpdatedEvent.cs b/CleanArchitecture.Domain/Events/User/UserUpdatedEvent.cs
index 996c7e6..92a09cf 100644
--- a/CleanArchitecture.Domain/Events/User/UserUpdatedEvent.cs
+++ b/CleanArchitecture.Domain/Events/User/UserUpdatedEvent.cs
@@ -4,10 +4,10 @@ namespace CleanArchitecture.Domain.Events.User;
public sealed class UserUpdatedEvent : DomainEvent
{
- public Guid UserId { get; }
-
public UserUpdatedEvent(Guid userId) : base(userId)
{
UserId = userId;
}
+
+ public Guid UserId { get; }
}
\ No newline at end of file
diff --git a/CleanArchitecture.Domain/Extensions/ServiceCollectionExtension.cs b/CleanArchitecture.Domain/Extensions/ServiceCollectionExtension.cs
index d56c338..4c3b2b9 100644
--- a/CleanArchitecture.Domain/Extensions/ServiceCollectionExtension.cs
+++ b/CleanArchitecture.Domain/Extensions/ServiceCollectionExtension.cs
@@ -25,7 +25,7 @@ public static class ServiceCollectionExtension
return services;
}
-
+
public static IServiceCollection AddNotificationHandlers(this IServiceCollection services)
{
// User
@@ -41,7 +41,7 @@ public static class ServiceCollectionExtension
{
// User
services.AddScoped();
-
+
return services;
}
}
\ No newline at end of file
diff --git a/CleanArchitecture.Domain/Extensions/Validation/CustomValidator.cs b/CleanArchitecture.Domain/Extensions/Validation/CustomValidator.cs
index ecacf87..c94ff0d 100644
--- a/CleanArchitecture.Domain/Extensions/Validation/CustomValidator.cs
+++ b/CleanArchitecture.Domain/Extensions/Validation/CustomValidator.cs
@@ -17,7 +17,10 @@ public static class CustomValidator
return base64.Length % 4 == 0 && Regex.IsMatch(base64, @"^[a-zA-Z0-9\+/]*={0,3}$", RegexOptions.None);
}
- public static IRuleBuilder Password(this IRuleBuilder ruleBuilder, int minLength = 8, int maxLength = 50)
+ public static IRuleBuilder Password(
+ this IRuleBuilder ruleBuilder,
+ int minLength = 8,
+ int maxLength = 50)
{
var options = ruleBuilder
.NotEmpty().WithErrorCode(DomainErrorCodes.UserEmptyPassword)
diff --git a/CleanArchitecture.Domain/Interfaces/IUser.cs b/CleanArchitecture.Domain/Interfaces/IUser.cs
index 55e953c..26cbe1a 100644
--- a/CleanArchitecture.Domain/Interfaces/IUser.cs
+++ b/CleanArchitecture.Domain/Interfaces/IUser.cs
@@ -5,8 +5,7 @@ namespace CleanArchitecture.Domain.Interfaces;
public interface IUser
{
+ string Name { get; }
Guid GetUserId();
UserRole GetUserRole();
-
- string Name { get; }
-}
+}
\ No newline at end of file
diff --git a/CleanArchitecture.Domain/Notifications/DomainNotification.cs b/CleanArchitecture.Domain/Notifications/DomainNotification.cs
index c9b2719..e57a891 100644
--- a/CleanArchitecture.Domain/Notifications/DomainNotification.cs
+++ b/CleanArchitecture.Domain/Notifications/DomainNotification.cs
@@ -4,11 +4,6 @@ namespace CleanArchitecture.Domain.Notifications;
public sealed class DomainNotification : DomainEvent
{
- public string Key { get; private set; }
- public string Value { get; private set; }
- public string Code { get; private set; }
- public object? Data { get; set; }
-
public DomainNotification(
string key,
string value,
@@ -23,4 +18,9 @@ public sealed class DomainNotification : DomainEvent
Data = data;
}
+
+ public string Key { get; }
+ public string Value { get; }
+ public string Code { get; }
+ public object? Data { get; set; }
}
\ No newline at end of file
diff --git a/CleanArchitecture.Domain/Notifications/DomainNotificationHandler.cs b/CleanArchitecture.Domain/Notifications/DomainNotificationHandler.cs
index d1e579d..59f9235 100644
--- a/CleanArchitecture.Domain/Notifications/DomainNotificationHandler.cs
+++ b/CleanArchitecture.Domain/Notifications/DomainNotificationHandler.cs
@@ -15,18 +15,18 @@ public class DomainNotificationHandler : INotificationHandler();
}
- public virtual List GetNotifications()
- {
- return _notifications;
- }
-
public Task Handle(DomainNotification notification, CancellationToken cancellationToken = default)
{
_notifications.Add(notification);
return Task.CompletedTask;
}
-
+
+ public virtual List GetNotifications()
+ {
+ return _notifications;
+ }
+
public virtual bool HasNotifications()
{
return GetNotifications().Any();
diff --git a/CleanArchitecture.Infrastructure.Tests/CleanArchitecture.Infrastructure.Tests.csproj b/CleanArchitecture.Infrastructure.Tests/CleanArchitecture.Infrastructure.Tests.csproj
index 574a54c..45957b8 100644
--- a/CleanArchitecture.Infrastructure.Tests/CleanArchitecture.Infrastructure.Tests.csproj
+++ b/CleanArchitecture.Infrastructure.Tests/CleanArchitecture.Infrastructure.Tests.csproj
@@ -8,10 +8,10 @@
-
-
-
-
+
+
+
+
runtime; build; native; contentfiles; analyzers; buildtransitive
all
@@ -23,7 +23,7 @@
-
+
diff --git a/CleanArchitecture.Infrastructure.Tests/DomainNotificationHandlerTests.cs b/CleanArchitecture.Infrastructure.Tests/DomainNotificationHandlerTests.cs
index 95148af..4ebf2a2 100644
--- a/CleanArchitecture.Infrastructure.Tests/DomainNotificationHandlerTests.cs
+++ b/CleanArchitecture.Infrastructure.Tests/DomainNotificationHandlerTests.cs
@@ -16,9 +16,9 @@ public sealed class DomainNotificationHandlerTests
[Fact]
public void Should_Handle_DomainNotification()
{
- string key = "Key";
- string value = "Value";
- string code = "Code";
+ var key = "Key";
+ var value = "Value";
+ var code = "Code";
var domainNotification = new DomainNotification(key, value, code);
var domainNotificationHandler = new DomainNotificationHandler();
@@ -29,9 +29,9 @@ public sealed class DomainNotificationHandlerTests
[Fact]
public void Should_Handle_DomainNotification_Overload()
{
- string key = "Key";
- string value = "Value";
- string code = "Code";
+ var key = "Key";
+ var value = "Value";
+ var code = "Code";
var domainNotification = new DomainNotification(key, value, code);
var domainNotificationHandler = new DomainNotificationHandler();
@@ -42,9 +42,9 @@ public sealed class DomainNotificationHandlerTests
[Fact]
public void DomainNotification_HasNotifications_After_Handling_One()
{
- string key = "Key";
- string value = "Value";
- string code = "Code";
+ var key = "Key";
+ var value = "Value";
+ var code = "Code";
var domainNotification = new DomainNotification(key, value, code);
var domainNotificationHandler = new DomainNotificationHandler();
@@ -60,4 +60,4 @@ public sealed class DomainNotificationHandlerTests
domainNotificationHandler.HasNotifications().Should().BeFalse();
}
-}
+}
\ No newline at end of file
diff --git a/CleanArchitecture.Infrastructure.Tests/DomainNotificationTests.cs b/CleanArchitecture.Infrastructure.Tests/DomainNotificationTests.cs
index d942a92..f34d1c0 100644
--- a/CleanArchitecture.Infrastructure.Tests/DomainNotificationTests.cs
+++ b/CleanArchitecture.Infrastructure.Tests/DomainNotificationTests.cs
@@ -10,9 +10,9 @@ public sealed class DomainNotificationTests
[Fact]
public void Should_Create_DomainNotification_Instance()
{
- string key = "Key";
- string value = "Value";
- string code = "Code";
+ var key = "Key";
+ var value = "Value";
+ var code = "Code";
var domainNotification = new DomainNotification(
key, value, code);
@@ -26,9 +26,9 @@ public sealed class DomainNotificationTests
[Fact]
public void Should_Create_DomainNotification_Overload_Instance()
{
- string key = "Key";
- string value = "Value";
- string code = "Code";
+ var key = "Key";
+ var value = "Value";
+ var code = "Code";
var domainNotification = new DomainNotification(
key, value, code);
@@ -38,4 +38,4 @@ public sealed class DomainNotificationTests
domainNotification.Code.Should().Be(code);
domainNotification.Should().NotBe(default(Guid));
}
-}
+}
\ No newline at end of file
diff --git a/CleanArchitecture.Infrastructure.Tests/UnitOfWorkTests.cs b/CleanArchitecture.Infrastructure.Tests/UnitOfWorkTests.cs
index 2a0e51f..5700ae1 100644
--- a/CleanArchitecture.Infrastructure.Tests/UnitOfWorkTests.cs
+++ b/CleanArchitecture.Infrastructure.Tests/UnitOfWorkTests.cs
@@ -19,18 +19,18 @@ public sealed class UnitOfWorkTests
var options = new DbContextOptionsBuilder();
var dbContextMock = new Mock(options.Options);
var loggerMock = new Mock>>();
-
+
dbContextMock
.Setup(x => x.SaveChangesAsync(CancellationToken.None))
.Returns(Task.FromResult(1));
-
+
var unitOfWork = UnitOfWorkTestFixture.GetUnitOfWork(dbContextMock.Object, loggerMock.Object);
-
+
var result = await unitOfWork.CommitAsync();
result.Should().BeTrue();
}
-
+
[Fact]
public async Task Should_Commit_Async_Returns_False()
{
@@ -45,7 +45,7 @@ public sealed class UnitOfWorkTests
var unitOfWork = UnitOfWorkTestFixture.GetUnitOfWork(dbContextMock.Object, loggerMock.Object);
var result = await unitOfWork.CommitAsync();
-
+
result.Should().BeFalse();
}
diff --git a/CleanArchitecture.Infrastructure/CleanArchitecture.Infrastructure.csproj b/CleanArchitecture.Infrastructure/CleanArchitecture.Infrastructure.csproj
index 6b37ff6..01399f8 100644
--- a/CleanArchitecture.Infrastructure/CleanArchitecture.Infrastructure.csproj
+++ b/CleanArchitecture.Infrastructure/CleanArchitecture.Infrastructure.csproj
@@ -6,18 +6,18 @@
-
+
-
-
-
-
-
- all
- runtime; build; native; contentfiles; analyzers; buildtransitive
-
+
+
+
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
diff --git a/CleanArchitecture.Infrastructure/Configurations/UserConfiguration.cs b/CleanArchitecture.Infrastructure/Configurations/UserConfiguration.cs
index 6fe7426..4763c9c 100644
--- a/CleanArchitecture.Infrastructure/Configurations/UserConfiguration.cs
+++ b/CleanArchitecture.Infrastructure/Configurations/UserConfiguration.cs
@@ -24,7 +24,7 @@ public sealed class UserConfiguration : IEntityTypeConfiguration
.Property(user => user.Surname)
.IsRequired()
.HasMaxLength(100);
-
+
builder
.Property(user => user.Password)
.IsRequired()
diff --git a/CleanArchitecture.Infrastructure/Database/ApplicationDbContext.cs b/CleanArchitecture.Infrastructure/Database/ApplicationDbContext.cs
index f4b4323..4280c4d 100644
--- a/CleanArchitecture.Infrastructure/Database/ApplicationDbContext.cs
+++ b/CleanArchitecture.Infrastructure/Database/ApplicationDbContext.cs
@@ -6,12 +6,12 @@ namespace CleanArchitecture.Infrastructure.Database;
public class ApplicationDbContext : DbContext
{
- public DbSet Users { get; set; } = null!;
-
public ApplicationDbContext(DbContextOptions options) : base(options)
{
}
+ public DbSet Users { get; set; } = null!;
+
protected override void OnModelCreating(ModelBuilder builder)
{
builder.ApplyConfiguration(new UserConfiguration());
diff --git a/CleanArchitecture.Infrastructure/Extensions/DbContextExtension.cs b/CleanArchitecture.Infrastructure/Extensions/DbContextExtension.cs
index 9192d48..869c1ea 100644
--- a/CleanArchitecture.Infrastructure/Extensions/DbContextExtension.cs
+++ b/CleanArchitecture.Infrastructure/Extensions/DbContextExtension.cs
@@ -18,4 +18,4 @@ public static class DbContextExtension
context.Database.Migrate();
}
}
-}
+}
\ No newline at end of file
diff --git a/CleanArchitecture.Infrastructure/Extensions/ServiceCollectionExtensions.cs b/CleanArchitecture.Infrastructure/Extensions/ServiceCollectionExtensions.cs
index ff72bb8..a7a68a8 100644
--- a/CleanArchitecture.Infrastructure/Extensions/ServiceCollectionExtensions.cs
+++ b/CleanArchitecture.Infrastructure/Extensions/ServiceCollectionExtensions.cs
@@ -22,4 +22,4 @@ public static class ServiceCollectionExtensions
return services;
}
-}
+}
\ No newline at end of file
diff --git a/CleanArchitecture.Infrastructure/InMemoryBus.cs b/CleanArchitecture.Infrastructure/InMemoryBus.cs
index 5896d83..2df646c 100644
--- a/CleanArchitecture.Infrastructure/InMemoryBus.cs
+++ b/CleanArchitecture.Infrastructure/InMemoryBus.cs
@@ -14,7 +14,7 @@ public sealed class InMemoryBus : IMediatorHandler
{
_mediator = mediator;
}
-
+
public Task QueryAsync(IRequest query)
{
return _mediator.Send(query);
diff --git a/CleanArchitecture.Infrastructure/Repositories/BaseRepository.cs b/CleanArchitecture.Infrastructure/Repositories/BaseRepository.cs
index 52b768d..db13d69 100644
--- a/CleanArchitecture.Infrastructure/Repositories/BaseRepository.cs
+++ b/CleanArchitecture.Infrastructure/Repositories/BaseRepository.cs
@@ -50,19 +50,6 @@ public class BaseRepository : IRepository where TEntity : Enti
return await DbSet.FindAsync(id);
}
- public int SaveChanges()
- {
- return _dbContext.SaveChanges();
- }
-
- protected virtual void Dispose(bool disposing)
- {
- if (disposing)
- {
- _dbContext.Dispose();
- }
- }
-
public virtual void Update(TEntity entity)
{
DbSet.Update(entity);
@@ -72,7 +59,7 @@ public class BaseRepository : IRepository where TEntity : Enti
{
return DbSet.AnyAsync(entity => entity.Id == id);
}
-
+
public void Remove(TEntity entity, bool hardDelete = false)
{
if (hardDelete)
@@ -86,4 +73,16 @@ public class BaseRepository : IRepository where TEntity : Enti
}
}
+ public int SaveChanges()
+ {
+ return _dbContext.SaveChanges();
+ }
+
+ protected virtual void Dispose(bool disposing)
+ {
+ if (disposing)
+ {
+ _dbContext.Dispose();
+ }
+ }
}
\ No newline at end of file
diff --git a/CleanArchitecture.Infrastructure/UnitOfWork.cs b/CleanArchitecture.Infrastructure/UnitOfWork.cs
index 97d88a9..735590e 100644
--- a/CleanArchitecture.Infrastructure/UnitOfWork.cs
+++ b/CleanArchitecture.Infrastructure/UnitOfWork.cs
@@ -45,4 +45,4 @@ public sealed class UnitOfWork : IUnitOfWork where TContext : DbContex
_context.Dispose();
}
}
-}
+}
\ No newline at end of file
diff --git a/CleanArchitecture.IntegrationTests/CleanArchitecture.IntegrationTests.csproj b/CleanArchitecture.IntegrationTests/CleanArchitecture.IntegrationTests.csproj
index 5f128a0..5768a6d 100644
--- a/CleanArchitecture.IntegrationTests/CleanArchitecture.IntegrationTests.csproj
+++ b/CleanArchitecture.IntegrationTests/CleanArchitecture.IntegrationTests.csproj
@@ -8,14 +8,14 @@
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
runtime; build; native; contentfiles; analyzers; buildtransitive
all
@@ -27,8 +27,8 @@
-
-
+
+
diff --git a/CleanArchitecture.IntegrationTests/Controller/UserControllerTests.cs b/CleanArchitecture.IntegrationTests/Controller/UserControllerTests.cs
index 357dd35..a06ecfa 100644
--- a/CleanArchitecture.IntegrationTests/Controller/UserControllerTests.cs
+++ b/CleanArchitecture.IntegrationTests/Controller/UserControllerTests.cs
@@ -24,12 +24,13 @@ public sealed class UserControllerTests : IClassFixture
_fixture = fixture;
}
- [Fact, Priority(0)]
+ [Fact]
+ [Priority(0)]
public async Task Should_Create_User()
{
var user = new CreateUserViewModel(
- _fixture.CreatedUserEmail,
- "Test",
+ _fixture.CreatedUserEmail,
+ "Test",
"Email",
_fixture.CreatedUserPassword);
@@ -43,12 +44,13 @@ public sealed class UserControllerTests : IClassFixture
_fixture.CreatedUserId = message!.Data;
}
-
- [Fact, Priority(5)]
+
+ [Fact]
+ [Priority(5)]
public async Task Should_Login_User()
{
var user = new LoginUserViewModel(
- _fixture.CreatedUserEmail,
+ _fixture.CreatedUserEmail,
_fixture.CreatedUserPassword);
var response = await _fixture.ServerClient.PostAsJsonAsync("/api/v1/user/login", user);
@@ -63,7 +65,8 @@ public sealed class UserControllerTests : IClassFixture
_fixture.EnableAuthentication();
}
- [Fact, Priority(10)]
+ [Fact]
+ [Priority(10)]
public async Task Should_Get_Created_Users()
{
var response = await _fixture.ServerClient.GetAsync("/api/v1/user/" + _fixture.CreatedUserId);
@@ -81,8 +84,9 @@ public sealed class UserControllerTests : IClassFixture
content.Surname.Should().Be("Test");
content.GivenName.Should().Be("Email");
}
-
- [Fact, Priority(10)]
+
+ [Fact]
+ [Priority(10)]
public async Task Should_Get_The_Current_Active_Users()
{
var response = await _fixture.ServerClient.GetAsync("/api/v1/user/me");
@@ -101,7 +105,8 @@ public sealed class UserControllerTests : IClassFixture
content.GivenName.Should().Be("Email");
}
- [Fact, Priority(15)]
+ [Fact]
+ [Priority(15)]
public async Task Should_Update_User()
{
var user = new UpdateUserViewModel(
@@ -124,7 +129,8 @@ public sealed class UserControllerTests : IClassFixture
content.Should().BeEquivalentTo(user);
}
- [Fact, Priority(20)]
+ [Fact]
+ [Priority(20)]
public async Task Should_Get_Updated_Users()
{
var response = await _fixture.ServerClient.GetAsync("/api/v1/user/" + _fixture.CreatedUserId);
@@ -141,11 +147,12 @@ public sealed class UserControllerTests : IClassFixture
content.Email.Should().Be("newtest@email.com");
content.Surname.Should().Be("NewTest");
content.GivenName.Should().Be("NewEmail");
-
+
_fixture.CreatedUserEmail = content.Email;
}
-
- [Fact, Priority(25)]
+
+ [Fact]
+ [Priority(25)]
public async Task Should_Change_User_Password()
{
var user = new ChangePasswordViewModel(
@@ -163,10 +170,10 @@ public sealed class UserControllerTests : IClassFixture
var content = message!.Data;
content.Should().BeEquivalentTo(user);
-
+
// Verify the user can login with the new password
var login = new LoginUserViewModel(
- _fixture.CreatedUserEmail,
+ _fixture.CreatedUserEmail,
_fixture.CreatedUserPassword + "1");
var loginResponse = await _fixture.ServerClient.PostAsJsonAsync("/api/v1/user/login", login);
@@ -178,7 +185,8 @@ public sealed class UserControllerTests : IClassFixture
loginMessage?.Data.Should().NotBeEmpty();
}
- [Fact, Priority(30)]
+ [Fact]
+ [Priority(30)]
public async Task Should_Get_All_User()
{
var response = await _fixture.ServerClient.GetAsync("/api/v1/user");
@@ -192,23 +200,24 @@ public sealed class UserControllerTests : IClassFixture
var content = message!.Data!.ToList();
content.Count.Should().Be(2);
-
+
var currentUser = content.First(x => x.Id == _fixture.CreatedUserId);
-
+
currentUser.Id.Should().Be(_fixture.CreatedUserId);
currentUser.Role.Should().Be(UserRole.User);
currentUser.Email.Should().Be("newtest@email.com");
currentUser.Surname.Should().Be("NewTest");
currentUser.GivenName.Should().Be("NewEmail");
-
+
var adminUser = content.First(x => x.Role == UserRole.Admin);
-
+
adminUser.Email.Should().Be("admin@email.com");
adminUser.Surname.Should().Be("Admin");
adminUser.GivenName.Should().Be("User");
}
- [Fact, Priority(35)]
+ [Fact]
+ [Priority(35)]
public async Task Should_Delete_User()
{
var response = await _fixture.ServerClient.DeleteAsync("/api/v1/user/" + _fixture.CreatedUserId);
@@ -222,4 +231,4 @@ public sealed class UserControllerTests : IClassFixture
var content = message!.Data;
content.Should().Be(_fixture.CreatedUserId);
}
-}
+}
\ No newline at end of file
diff --git a/CleanArchitecture.IntegrationTests/Extensions/FunctionalTestsServiceCollectionExtensions.cs b/CleanArchitecture.IntegrationTests/Extensions/FunctionalTestsServiceCollectionExtensions.cs
index 8cb7fad..d81e2c0 100644
--- a/CleanArchitecture.IntegrationTests/Extensions/FunctionalTestsServiceCollectionExtensions.cs
+++ b/CleanArchitecture.IntegrationTests/Extensions/FunctionalTestsServiceCollectionExtensions.cs
@@ -2,28 +2,29 @@
using System.Collections.Generic;
using System.Data.Common;
using System.Linq;
-using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore;
-using Microsoft.Extensions.DependencyInjection;
using Microsoft.EntityFrameworkCore.Diagnostics;
+using Microsoft.EntityFrameworkCore.Infrastructure;
+using Microsoft.Extensions.DependencyInjection;
namespace CleanArchitecture.IntegrationTests.Extensions;
public static class FunctionalTestsServiceCollectionExtensions
{
- public static IServiceCollection SetupTestDatabase(this IServiceCollection services, DbConnection connection) where TContext : DbContext
+ public static IServiceCollection SetupTestDatabase(this IServiceCollection services,
+ DbConnection connection) where TContext : DbContext
{
var descriptor = services.SingleOrDefault(d => d.ServiceType == typeof(DbContextOptions));
if (descriptor != null)
services.Remove(descriptor);
services.AddScoped(p =>
- DbContextOptionsFactory(
- p,
- (_, options) => options
- .ConfigureWarnings(b => b.Log(CoreEventId.ManyServiceProvidersCreatedWarning))
- .UseLazyLoadingProxies()
- .UseSqlite(connection)));
+ DbContextOptionsFactory(
+ p,
+ (_, options) => options
+ .ConfigureWarnings(b => b.Log(CoreEventId.ManyServiceProvidersCreatedWarning))
+ .UseLazyLoadingProxies()
+ .UseSqlite(connection)));
return services;
}
@@ -42,4 +43,4 @@ public static class FunctionalTestsServiceCollectionExtensions
return builder.Options;
}
-}
+}
\ No newline at end of file
diff --git a/CleanArchitecture.IntegrationTests/Extensions/HttpExtensions.cs b/CleanArchitecture.IntegrationTests/Extensions/HttpExtensions.cs
index f765a9c..3ac2378 100644
--- a/CleanArchitecture.IntegrationTests/Extensions/HttpExtensions.cs
+++ b/CleanArchitecture.IntegrationTests/Extensions/HttpExtensions.cs
@@ -10,7 +10,7 @@ public static class HttpExtensions
{
private static readonly JsonSerializerOptions JsonSerializerOptions = new()
{
- PropertyNameCaseInsensitive = true,
+ PropertyNameCaseInsensitive = true
};
private static T? Deserialize(string json)
@@ -55,4 +55,4 @@ public static class HttpExtensions
return httpClient.PutAsync(url, content);
}
-}
+}
\ No newline at end of file
diff --git a/CleanArchitecture.IntegrationTests/Fixtures/TestFixtureBase.cs b/CleanArchitecture.IntegrationTests/Fixtures/TestFixtureBase.cs
index 2d4994e..cfe5a52 100644
--- a/CleanArchitecture.IntegrationTests/Fixtures/TestFixtureBase.cs
+++ b/CleanArchitecture.IntegrationTests/Fixtures/TestFixtureBase.cs
@@ -9,8 +9,6 @@ namespace CleanArchitecture.IntegrationTests.Fixtures;
public class TestFixtureBase
{
- public HttpClient ServerClient { get; }
-
public TestFixtureBase()
{
var projectDir = Directory.GetCurrentDirectory();
@@ -25,6 +23,8 @@ public class TestFixtureBase
ServerClient.Timeout = TimeSpan.FromMinutes(5);
}
+ public HttpClient ServerClient { get; }
+
protected virtual void SeedTestData(ApplicationDbContext context)
{
}
@@ -35,4 +35,4 @@ public class TestFixtureBase
IServiceProvider scopedServices)
{
}
-}
+}
\ No newline at end of file
diff --git a/CleanArchitecture.IntegrationTests/Fixtures/UserTestFixture.cs b/CleanArchitecture.IntegrationTests/Fixtures/UserTestFixture.cs
index 3d8fa2e..5769927 100644
--- a/CleanArchitecture.IntegrationTests/Fixtures/UserTestFixture.cs
+++ b/CleanArchitecture.IntegrationTests/Fixtures/UserTestFixture.cs
@@ -8,9 +8,9 @@ public sealed class UserTestFixture : TestFixtureBase
public string CreatedUserEmail { get; set; } = "test@email.com";
public string CreatedUserPassword { get; set; } = "z8]tnayvd5FNLU9:]AQm";
public string CreatedUserToken { get; set; } = string.Empty;
-
+
public void EnableAuthentication()
{
ServerClient.DefaultRequestHeaders.Add("Authorization", $"Bearer {CreatedUserToken}");
}
-}
+}
\ No newline at end of file
diff --git a/CleanArchitecture.IntegrationTests/Infrastructure/CleanArchitectureWebApplicationFactory.cs b/CleanArchitecture.IntegrationTests/Infrastructure/CleanArchitectureWebApplicationFactory.cs
index 0e9f243..b35bbdf 100644
--- a/CleanArchitecture.IntegrationTests/Infrastructure/CleanArchitectureWebApplicationFactory.cs
+++ b/CleanArchitecture.IntegrationTests/Infrastructure/CleanArchitectureWebApplicationFactory.cs
@@ -18,11 +18,11 @@ public sealed class CleanArchitectureWebApplicationFactory : WebApplicationFacto
ServiceProvider serviceProvider,
IServiceProvider scopedServices);
- private readonly SqliteConnection _connection = new($"DataSource=:memory:");
-
private readonly AddCustomSeedDataHandler? _addCustomSeedDataHandler;
- private readonly RegisterCustomServicesHandler? _registerCustomServicesHandler;
+
+ private readonly SqliteConnection _connection = new("DataSource=:memory:");
private readonly string? _environment;
+ private readonly RegisterCustomServicesHandler? _registerCustomServicesHandler;
public CleanArchitectureWebApplicationFactory(
AddCustomSeedDataHandler? addCustomSeedDataHandler,
@@ -51,7 +51,7 @@ public sealed class CleanArchitectureWebApplicationFactory : WebApplicationFacto
var sp = services.BuildServiceProvider();
- using IServiceScope scope = sp.CreateScope();
+ using var scope = sp.CreateScope();
var scopedServices = scope.ServiceProvider;
var applicationDbContext = scopedServices.GetRequiredService();
@@ -62,4 +62,4 @@ public sealed class CleanArchitectureWebApplicationFactory : WebApplicationFacto
_registerCustomServicesHandler?.Invoke(services, sp, scopedServices);
});
}
-}
+}
\ No newline at end of file
diff --git a/CleanArchitecture.Proto/CleanArchitecture.Proto.csproj b/CleanArchitecture.Proto/CleanArchitecture.Proto.csproj
index 1f914a1..de1ac9c 100644
--- a/CleanArchitecture.Proto/CleanArchitecture.Proto.csproj
+++ b/CleanArchitecture.Proto/CleanArchitecture.Proto.csproj
@@ -6,19 +6,19 @@
-
-
+
+
-
-
+
+
-
-
-
+
+
+
diff --git a/CleanArchitecture.gRPC.Tests/CleanArchitecture.gRPC.Tests.csproj b/CleanArchitecture.gRPC.Tests/CleanArchitecture.gRPC.Tests.csproj
index 6d11a38..b6443c4 100644
--- a/CleanArchitecture.gRPC.Tests/CleanArchitecture.gRPC.Tests.csproj
+++ b/CleanArchitecture.gRPC.Tests/CleanArchitecture.gRPC.Tests.csproj
@@ -8,11 +8,11 @@
-
-
-
-
-
+
+
+
+
+
runtime; build; native; contentfiles; analyzers; buildtransitive
all
@@ -24,8 +24,8 @@
-
-
+
+
diff --git a/CleanArchitecture.gRPC.Tests/Fixtures/UserTestsFixture.cs b/CleanArchitecture.gRPC.Tests/Fixtures/UserTestsFixture.cs
index 9cac355..5b04bef 100644
--- a/CleanArchitecture.gRPC.Tests/Fixtures/UserTestsFixture.cs
+++ b/CleanArchitecture.gRPC.Tests/Fixtures/UserTestsFixture.cs
@@ -11,37 +11,31 @@ namespace CleanArchitecture.gRPC.Tests.Fixtures;
public sealed class UserTestsFixture
{
- private Mock UserRepository { get; } = new ();
-
- public UsersApiImplementation UsersApiImplementation { get; }
-
- public IEnumerable ExistingUsers { get; }
-
public UserTestsFixture()
{
- ExistingUsers = new List()
+ ExistingUsers = new List
{
- new (
- Guid.NewGuid(),
- "test@test.de",
- "Test First Name",
+ new(
+ Guid.NewGuid(),
+ "test@test.de",
+ "Test First Name",
"Test Last Name",
"Test Password",
UserRole.User),
- new (
- Guid.NewGuid(),
- "email@Email.de",
- "Email First Name",
+ new(
+ Guid.NewGuid(),
+ "email@Email.de",
+ "Email First Name",
"Email Last Name",
"Email Password",
UserRole.Admin),
- new (
- Guid.NewGuid(),
- "user@user.de",
- "User First Name",
+ new(
+ Guid.NewGuid(),
+ "user@user.de",
+ "User First Name",
"User Last Name",
"User Password",
- UserRole.User),
+ UserRole.User)
};
var queryable = ExistingUsers.AsQueryable().BuildMock();
@@ -52,4 +46,10 @@ public sealed class UserTestsFixture
UsersApiImplementation = new UsersApiImplementation(UserRepository.Object);
}
+
+ private Mock UserRepository { get; } = new();
+
+ public UsersApiImplementation UsersApiImplementation { get; }
+
+ public IEnumerable ExistingUsers { get; }
}
\ No newline at end of file
diff --git a/CleanArchitecture.gRPC/CleanArchitecture.gRPC.csproj b/CleanArchitecture.gRPC/CleanArchitecture.gRPC.csproj
index 82b6f59..1268e7f 100644
--- a/CleanArchitecture.gRPC/CleanArchitecture.gRPC.csproj
+++ b/CleanArchitecture.gRPC/CleanArchitecture.gRPC.csproj
@@ -6,12 +6,12 @@
-
-
+
+
-
+