mirror of
https://github.com/alex289/CleanArchitecture.git
synced 2025-07-01 11:02:57 +00:00
feat: Check for tenant when updating users tenant
This commit is contained in:
parent
61bcab6d77
commit
3969db2bba
@ -17,7 +17,7 @@ public sealed class CreateTenantCommandHandlerTests
|
|||||||
Guid.NewGuid(),
|
Guid.NewGuid(),
|
||||||
"Test Tenant");
|
"Test Tenant");
|
||||||
|
|
||||||
_fixture.CommandHandler.Handle(command, default!).Wait();
|
_fixture.CommandHandler.Handle(command, default).Wait();
|
||||||
|
|
||||||
_fixture
|
_fixture
|
||||||
.VerifyNoDomainNotification()
|
.VerifyNoDomainNotification()
|
||||||
@ -36,7 +36,7 @@ public sealed class CreateTenantCommandHandlerTests
|
|||||||
Guid.NewGuid(),
|
Guid.NewGuid(),
|
||||||
"Test Tenant");
|
"Test Tenant");
|
||||||
|
|
||||||
_fixture.CommandHandler.Handle(command, default!).Wait();
|
_fixture.CommandHandler.Handle(command, default).Wait();
|
||||||
|
|
||||||
_fixture
|
_fixture
|
||||||
.VerifyNoCommit()
|
.VerifyNoCommit()
|
||||||
@ -56,7 +56,7 @@ public sealed class CreateTenantCommandHandlerTests
|
|||||||
|
|
||||||
_fixture.SetupExistingTenant(command.AggregateId);
|
_fixture.SetupExistingTenant(command.AggregateId);
|
||||||
|
|
||||||
_fixture.CommandHandler.Handle(command, default!).Wait();
|
_fixture.CommandHandler.Handle(command, default).Wait();
|
||||||
|
|
||||||
_fixture
|
_fixture
|
||||||
.VerifyNoCommit()
|
.VerifyNoCommit()
|
||||||
|
@ -42,4 +42,23 @@ public sealed class DeleteTenantCommandHandlerTests
|
|||||||
ErrorCodes.ObjectNotFound,
|
ErrorCodes.ObjectNotFound,
|
||||||
$"There is no tenant with Id {command.AggregateId}");
|
$"There is no tenant with Id {command.AggregateId}");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void Should_Not_Delete_Tenant_Insufficient_Permissions()
|
||||||
|
{
|
||||||
|
var tenant = _fixture.SetupTenant();
|
||||||
|
_fixture.SetupUser();
|
||||||
|
|
||||||
|
var command = new DeleteTenantCommand(tenant.Id);
|
||||||
|
|
||||||
|
_fixture.CommandHandler.Handle(command, default).Wait();
|
||||||
|
|
||||||
|
_fixture
|
||||||
|
.VerifyNoCommit()
|
||||||
|
.VerifyNoRaisedEvent<TenantDeletedEvent>()
|
||||||
|
.VerifyAnyDomainNotification()
|
||||||
|
.VerifyExistingNotification(
|
||||||
|
ErrorCodes.InsufficientPermissions,
|
||||||
|
$"No permission to delete tenant {command.AggregateId}");
|
||||||
|
}
|
||||||
}
|
}
|
@ -1,5 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using CleanArchitecture.Domain.Commands.Tenants.DeleteTenant;
|
using CleanArchitecture.Domain.Commands.Tenants.DeleteTenant;
|
||||||
|
using CleanArchitecture.Domain.Enums;
|
||||||
using CleanArchitecture.Domain.Interfaces.Repositories;
|
using CleanArchitecture.Domain.Interfaces.Repositories;
|
||||||
using NSubstitute;
|
using NSubstitute;
|
||||||
|
|
||||||
@ -36,4 +37,9 @@ public sealed class DeleteTenantCommandTestFixture : CommandHandlerFixtureBase
|
|||||||
|
|
||||||
return tenant;
|
return tenant;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void SetupUser()
|
||||||
|
{
|
||||||
|
User.GetUserRole().Returns(UserRole.User);
|
||||||
|
}
|
||||||
}
|
}
|
@ -19,7 +19,7 @@ public sealed class UpdateTenantCommandHandlerTests
|
|||||||
|
|
||||||
_fixture.SetupExistingTenant(command.AggregateId);
|
_fixture.SetupExistingTenant(command.AggregateId);
|
||||||
|
|
||||||
_fixture.CommandHandler.Handle(command, default!).Wait();
|
_fixture.CommandHandler.Handle(command, default).Wait();
|
||||||
|
|
||||||
_fixture
|
_fixture
|
||||||
.VerifyCommit()
|
.VerifyCommit()
|
||||||
@ -38,7 +38,7 @@ public sealed class UpdateTenantCommandHandlerTests
|
|||||||
|
|
||||||
_fixture.SetupUser();
|
_fixture.SetupUser();
|
||||||
|
|
||||||
_fixture.CommandHandler.Handle(command, default!).Wait();
|
_fixture.CommandHandler.Handle(command, default).Wait();
|
||||||
|
|
||||||
_fixture
|
_fixture
|
||||||
.VerifyNoCommit()
|
.VerifyNoCommit()
|
||||||
@ -56,7 +56,7 @@ public sealed class UpdateTenantCommandHandlerTests
|
|||||||
Guid.NewGuid(),
|
Guid.NewGuid(),
|
||||||
"Tenant Name");
|
"Tenant Name");
|
||||||
|
|
||||||
_fixture.CommandHandler.Handle(command, default!).Wait();
|
_fixture.CommandHandler.Handle(command, default).Wait();
|
||||||
|
|
||||||
_fixture
|
_fixture
|
||||||
.VerifyNoCommit()
|
.VerifyNoCommit()
|
||||||
|
@ -26,6 +26,8 @@ public sealed class UpdateUserCommandHandlerTests
|
|||||||
UserRole.User,
|
UserRole.User,
|
||||||
Guid.NewGuid());
|
Guid.NewGuid());
|
||||||
|
|
||||||
|
_fixture.SetupTenant(command.TenantId);
|
||||||
|
|
||||||
await _fixture.CommandHandler.Handle(command, default);
|
await _fixture.CommandHandler.Handle(command, default);
|
||||||
|
|
||||||
_fixture
|
_fixture
|
||||||
@ -46,6 +48,8 @@ public sealed class UpdateUserCommandHandlerTests
|
|||||||
"Email",
|
"Email",
|
||||||
UserRole.User,
|
UserRole.User,
|
||||||
Guid.NewGuid());
|
Guid.NewGuid());
|
||||||
|
|
||||||
|
_fixture.SetupTenant(command.TenantId);
|
||||||
|
|
||||||
await _fixture.CommandHandler.Handle(command, default);
|
await _fixture.CommandHandler.Handle(command, default);
|
||||||
|
|
||||||
@ -70,6 +74,8 @@ public sealed class UpdateUserCommandHandlerTests
|
|||||||
"Email",
|
"Email",
|
||||||
UserRole.User,
|
UserRole.User,
|
||||||
Guid.NewGuid());
|
Guid.NewGuid());
|
||||||
|
|
||||||
|
_fixture.SetupTenant(command.TenantId);
|
||||||
|
|
||||||
_fixture.UserRepository
|
_fixture.UserRepository
|
||||||
.GetByEmailAsync(command.Email)
|
.GetByEmailAsync(command.Email)
|
||||||
@ -92,4 +98,59 @@ public sealed class UpdateUserCommandHandlerTests
|
|||||||
DomainErrorCodes.User.UserAlreadyExists,
|
DomainErrorCodes.User.UserAlreadyExists,
|
||||||
$"There is already a user with email {command.Email}");
|
$"There is already a user with email {command.Email}");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task Should_Not_Update_Non_Existing_Tenant()
|
||||||
|
{
|
||||||
|
var user = _fixture.SetupUser();
|
||||||
|
|
||||||
|
var command = new UpdateUserCommand(
|
||||||
|
user.Id,
|
||||||
|
"test@email.com",
|
||||||
|
"Test",
|
||||||
|
"Email",
|
||||||
|
UserRole.User,
|
||||||
|
Guid.NewGuid());
|
||||||
|
|
||||||
|
await _fixture.CommandHandler.Handle(command, default);
|
||||||
|
|
||||||
|
_fixture
|
||||||
|
.VerifyNoCommit()
|
||||||
|
.VerifyNoRaisedEvent<UserUpdatedEvent>()
|
||||||
|
.VerifyAnyDomainNotification()
|
||||||
|
.VerifyExistingNotification(
|
||||||
|
ErrorCodes.ObjectNotFound,
|
||||||
|
$"There is no tenant with Id {command.TenantId}");
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public async Task Should_Not_Update_Admin_Properties()
|
||||||
|
{
|
||||||
|
var user = _fixture.SetupUser();
|
||||||
|
_fixture.SetupCurrentUser(user.Id);
|
||||||
|
|
||||||
|
var command = new UpdateUserCommand(
|
||||||
|
user.Id,
|
||||||
|
"test@email.com",
|
||||||
|
"Test",
|
||||||
|
"Email",
|
||||||
|
UserRole.Admin,
|
||||||
|
Guid.NewGuid());
|
||||||
|
|
||||||
|
_fixture.SetupTenant(command.TenantId);
|
||||||
|
|
||||||
|
await _fixture.CommandHandler.Handle(command, default);
|
||||||
|
|
||||||
|
_fixture.UserRepository.Received(1).Update(Arg.Is<Entities.User>(u =>
|
||||||
|
u.TenantId == user.TenantId &&
|
||||||
|
u.Role == user.Role &&
|
||||||
|
u.Id == command.UserId &&
|
||||||
|
u.Email == command.Email &&
|
||||||
|
u.FirstName == command.FirstName));
|
||||||
|
|
||||||
|
_fixture
|
||||||
|
.VerifyNoDomainNotification()
|
||||||
|
.VerifyCommit()
|
||||||
|
.VerifyRaisedEvent<UserUpdatedEvent>(x => x.AggregateId == command.UserId);
|
||||||
|
}
|
||||||
}
|
}
|
@ -11,17 +11,20 @@ public sealed class UpdateUserCommandTestFixture : CommandHandlerFixtureBase
|
|||||||
public UpdateUserCommandTestFixture()
|
public UpdateUserCommandTestFixture()
|
||||||
{
|
{
|
||||||
UserRepository = Substitute.For<IUserRepository>();
|
UserRepository = Substitute.For<IUserRepository>();
|
||||||
|
TenantRepository = Substitute.For<ITenantRepository>();
|
||||||
|
|
||||||
CommandHandler = new UpdateUserCommandHandler(
|
CommandHandler = new UpdateUserCommandHandler(
|
||||||
Bus,
|
Bus,
|
||||||
UnitOfWork,
|
UnitOfWork,
|
||||||
NotificationHandler,
|
NotificationHandler,
|
||||||
UserRepository,
|
UserRepository,
|
||||||
User);
|
User,
|
||||||
|
TenantRepository);
|
||||||
}
|
}
|
||||||
|
|
||||||
public UpdateUserCommandHandler CommandHandler { get; }
|
public UpdateUserCommandHandler CommandHandler { get; }
|
||||||
public IUserRepository UserRepository { get; }
|
public IUserRepository UserRepository { get; }
|
||||||
|
private ITenantRepository TenantRepository { get; }
|
||||||
|
|
||||||
public Entities.User SetupUser()
|
public Entities.User SetupUser()
|
||||||
{
|
{
|
||||||
@ -40,4 +43,21 @@ public sealed class UpdateUserCommandTestFixture : CommandHandlerFixtureBase
|
|||||||
|
|
||||||
return user;
|
return user;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Entities.Tenant SetupTenant(Guid tenantId)
|
||||||
|
{
|
||||||
|
var tenant = new Entities.Tenant(tenantId, "Name");
|
||||||
|
|
||||||
|
TenantRepository
|
||||||
|
.ExistsAsync(Arg.Is<Guid>(y => y == tenant.Id))
|
||||||
|
.Returns(true);
|
||||||
|
|
||||||
|
return tenant;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetupCurrentUser(Guid userId)
|
||||||
|
{
|
||||||
|
User.GetUserId().Returns(userId);
|
||||||
|
User.GetUserRole().Returns(UserRole.User);
|
||||||
|
}
|
||||||
}
|
}
|
@ -38,8 +38,6 @@ public sealed class DeleteTenantCommandHandler : CommandHandlerBase,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Todo: Test following
|
|
||||||
|
|
||||||
if (_user.GetUserRole() != UserRole.Admin)
|
if (_user.GetUserRole() != UserRole.Admin)
|
||||||
{
|
{
|
||||||
await NotifyAsync(
|
await NotifyAsync(
|
||||||
|
@ -15,16 +15,19 @@ public sealed class UpdateUserCommandHandler : CommandHandlerBase,
|
|||||||
{
|
{
|
||||||
private readonly IUser _user;
|
private readonly IUser _user;
|
||||||
private readonly IUserRepository _userRepository;
|
private readonly IUserRepository _userRepository;
|
||||||
|
private readonly ITenantRepository _tenantRepository;
|
||||||
|
|
||||||
public UpdateUserCommandHandler(
|
public UpdateUserCommandHandler(
|
||||||
IMediatorHandler bus,
|
IMediatorHandler bus,
|
||||||
IUnitOfWork unitOfWork,
|
IUnitOfWork unitOfWork,
|
||||||
INotificationHandler<DomainNotification> notifications,
|
INotificationHandler<DomainNotification> notifications,
|
||||||
IUserRepository userRepository,
|
IUserRepository userRepository,
|
||||||
IUser user) : base(bus, unitOfWork, notifications)
|
IUser user,
|
||||||
|
ITenantRepository tenantRepository) : base(bus, unitOfWork, notifications)
|
||||||
{
|
{
|
||||||
_userRepository = userRepository;
|
_userRepository = userRepository;
|
||||||
_user = user;
|
_user = user;
|
||||||
|
_tenantRepository = tenantRepository;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task Handle(UpdateUserCommand request, CancellationToken cancellationToken)
|
public async Task Handle(UpdateUserCommand request, CancellationToken cancellationToken)
|
||||||
@ -76,8 +79,15 @@ public sealed class UpdateUserCommandHandler : CommandHandlerBase,
|
|||||||
{
|
{
|
||||||
user.SetRole(request.Role);
|
user.SetRole(request.Role);
|
||||||
|
|
||||||
// Todo: Test
|
if (!await _tenantRepository.ExistsAsync(request.TenantId))
|
||||||
// Todo: Check if tenant exists first
|
{
|
||||||
|
await NotifyAsync(
|
||||||
|
new DomainNotification(
|
||||||
|
request.MessageType,
|
||||||
|
$"There is no tenant with Id {request.TenantId}",
|
||||||
|
ErrorCodes.ObjectNotFound));
|
||||||
|
return;
|
||||||
|
}
|
||||||
user.SetTenant(request.TenantId);
|
user.SetTenant(request.TenantId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -40,7 +40,6 @@ public sealed class GetUsersByIdsTests : IClassFixture<UserTestFixture>
|
|||||||
|
|
||||||
ids.Add(nonExistingId);
|
ids.Add(nonExistingId);
|
||||||
|
|
||||||
// Todo: Use default instead of null everywhere
|
|
||||||
var result = await _fixture.UsersApiImplementation.GetByIds(
|
var result = await _fixture.UsersApiImplementation.GetByIds(
|
||||||
SetupRequest(ids),
|
SetupRequest(ids),
|
||||||
default!);
|
default!);
|
||||||
|
Loading…
Reference in New Issue
Block a user