1
0
Fork 0
mirror of https://github.com/s-frick/effigenix.git synced 2026-03-28 12:09:35 +01:00

refactor(usermanagement,masterdata): UnitOfWork-Pattern + JdbcClient-Migration

Migriert UserManagement und MasterData BCs von JPA/Spring Data auf
JdbcClient + UnitOfWork, analog zum Production-BC. Inventory bleibt auf JPA.

- 6 neue JdbcClient-Repositories (User, Role, Article, Supplier, Customer, ProductCategory)
- 45 Use Cases: UoW für schreibende, @Transactional entfernt bei allen
- AbstractIntegrationTest + 20 Integration-Tests auf JdbcClient umgestellt
- 12 Unit-Test-Klassen mit UoW-Mock erweitert
- 34 alte JPA-Dateien gelöscht (Entities, Spring Data Repos, Adapter, Mapper)
This commit is contained in:
Sebastian Frick 2026-02-25 08:35:24 +01:00
parent e5bc5690da
commit 46275f6d59
117 changed files with 2258 additions and 3549 deletions

View file

@ -5,6 +5,7 @@ import de.effigenix.domain.masterdata.*;
import de.effigenix.shared.common.Money;
import de.effigenix.shared.common.RepositoryError;
import de.effigenix.shared.common.Result;
import de.effigenix.shared.persistence.UnitOfWork;
import de.effigenix.shared.security.ActorId;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
@ -18,6 +19,7 @@ import java.math.BigDecimal;
import java.time.OffsetDateTime;
import java.time.ZoneOffset;
import java.util.*;
import java.util.function.Supplier;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.ArgumentMatchers.any;
@ -28,6 +30,7 @@ import static org.mockito.Mockito.*;
class ArticleUseCaseTest {
@Mock private ArticleRepository articleRepository;
@Mock private UnitOfWork unitOfWork;
private final ActorId performedBy = ActorId.of("admin-user");
private final String CATEGORY_ID = UUID.randomUUID().toString();
@ -99,7 +102,9 @@ class ArticleUseCaseTest {
@BeforeEach
void setUp() {
createArticle = new CreateArticle(articleRepository);
lenient().when(unitOfWork.executeAtomically(any()))
.thenAnswer(inv -> ((Supplier<?>) inv.getArgument(0)).get());
createArticle = new CreateArticle(articleRepository, unitOfWork);
}
@Test
@ -236,7 +241,9 @@ class ArticleUseCaseTest {
@BeforeEach
void setUp() {
updateArticle = new UpdateArticle(articleRepository);
lenient().when(unitOfWork.executeAtomically(any()))
.thenAnswer(inv -> ((Supplier<?>) inv.getArgument(0)).get());
updateArticle = new UpdateArticle(articleRepository, unitOfWork);
}
@Test
@ -497,7 +504,9 @@ class ArticleUseCaseTest {
@BeforeEach
void setUp() {
activateArticle = new ActivateArticle(articleRepository);
lenient().when(unitOfWork.executeAtomically(any()))
.thenAnswer(inv -> ((Supplier<?>) inv.getArgument(0)).get());
activateArticle = new ActivateArticle(articleRepository, unitOfWork);
}
@Test
@ -576,7 +585,9 @@ class ArticleUseCaseTest {
@BeforeEach
void setUp() {
deactivateArticle = new DeactivateArticle(articleRepository);
lenient().when(unitOfWork.executeAtomically(any()))
.thenAnswer(inv -> ((Supplier<?>) inv.getArgument(0)).get());
deactivateArticle = new DeactivateArticle(articleRepository, unitOfWork);
}
@Test
@ -648,7 +659,9 @@ class ArticleUseCaseTest {
@BeforeEach
void setUp() {
addSalesUnit = new AddSalesUnit(articleRepository);
lenient().when(unitOfWork.executeAtomically(any()))
.thenAnswer(inv -> ((Supplier<?>) inv.getArgument(0)).get());
addSalesUnit = new AddSalesUnit(articleRepository, unitOfWork);
}
@Test
@ -776,7 +789,9 @@ class ArticleUseCaseTest {
@BeforeEach
void setUp() {
removeSalesUnit = new RemoveSalesUnit(articleRepository);
lenient().when(unitOfWork.executeAtomically(any()))
.thenAnswer(inv -> ((Supplier<?>) inv.getArgument(0)).get());
removeSalesUnit = new RemoveSalesUnit(articleRepository, unitOfWork);
}
@Test
@ -881,7 +896,9 @@ class ArticleUseCaseTest {
@BeforeEach
void setUp() {
updateSalesUnitPrice = new UpdateSalesUnitPrice(articleRepository);
lenient().when(unitOfWork.executeAtomically(any()))
.thenAnswer(inv -> ((Supplier<?>) inv.getArgument(0)).get());
updateSalesUnitPrice = new UpdateSalesUnitPrice(articleRepository, unitOfWork);
}
@Test
@ -1004,7 +1021,9 @@ class ArticleUseCaseTest {
@BeforeEach
void setUp() {
assignSupplier = new AssignSupplier(articleRepository);
lenient().when(unitOfWork.executeAtomically(any()))
.thenAnswer(inv -> ((Supplier<?>) inv.getArgument(0)).get());
assignSupplier = new AssignSupplier(articleRepository, unitOfWork);
}
@Test
@ -1082,7 +1101,9 @@ class ArticleUseCaseTest {
@BeforeEach
void setUp() {
removeSupplier = new RemoveSupplier(articleRepository);
lenient().when(unitOfWork.executeAtomically(any()))
.thenAnswer(inv -> ((Supplier<?>) inv.getArgument(0)).get());
removeSupplier = new RemoveSupplier(articleRepository, unitOfWork);
}
@Test

View file

@ -3,6 +3,7 @@ package de.effigenix.application.masterdata;
import de.effigenix.application.masterdata.command.*;
import de.effigenix.domain.masterdata.*;
import de.effigenix.shared.common.*;
import de.effigenix.shared.persistence.UnitOfWork;
import de.effigenix.shared.security.ActorId;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
@ -19,6 +20,7 @@ import java.time.ZoneOffset;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.function.Supplier;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.ArgumentMatchers.any;
@ -29,11 +31,14 @@ import static org.mockito.Mockito.*;
class CustomerUseCaseTest {
@Mock private CustomerRepository customerRepository;
@Mock private UnitOfWork unitOfWork;
private ActorId performedBy;
@BeforeEach
void setUp() {
lenient().when(unitOfWork.executeAtomically(any()))
.thenAnswer(inv -> ((Supplier<?>)inv.getArgument(0)).get());
performedBy = ActorId.of("admin-user");
}
@ -109,7 +114,7 @@ class CustomerUseCaseTest {
@BeforeEach
void setUp() {
createCustomer = new CreateCustomer(customerRepository);
createCustomer = new CreateCustomer(customerRepository, unitOfWork);
}
@Test
@ -215,7 +220,7 @@ class CustomerUseCaseTest {
@BeforeEach
void setUp() {
updateCustomer = new UpdateCustomer(customerRepository);
updateCustomer = new UpdateCustomer(customerRepository, unitOfWork);
}
@Test
@ -469,7 +474,7 @@ class CustomerUseCaseTest {
@BeforeEach
void setUp() {
activateCustomer = new ActivateCustomer(customerRepository);
activateCustomer = new ActivateCustomer(customerRepository, unitOfWork);
}
@Test
@ -540,7 +545,7 @@ class CustomerUseCaseTest {
@BeforeEach
void setUp() {
deactivateCustomer = new DeactivateCustomer(customerRepository);
deactivateCustomer = new DeactivateCustomer(customerRepository, unitOfWork);
}
@Test
@ -611,7 +616,7 @@ class CustomerUseCaseTest {
@BeforeEach
void setUp() {
addDeliveryAddress = new AddDeliveryAddress(customerRepository);
addDeliveryAddress = new AddDeliveryAddress(customerRepository, unitOfWork);
}
@Test
@ -712,7 +717,7 @@ class CustomerUseCaseTest {
@BeforeEach
void setUp() {
removeDeliveryAddress = new RemoveDeliveryAddress(customerRepository);
removeDeliveryAddress = new RemoveDeliveryAddress(customerRepository, unitOfWork);
}
@Test
@ -797,7 +802,7 @@ class CustomerUseCaseTest {
@BeforeEach
void setUp() {
setPreferences = new SetPreferences(customerRepository);
setPreferences = new SetPreferences(customerRepository, unitOfWork);
}
@Test
@ -887,7 +892,7 @@ class CustomerUseCaseTest {
@BeforeEach
void setUp() {
setFrameContract = new SetFrameContract(customerRepository);
setFrameContract = new SetFrameContract(customerRepository, unitOfWork);
}
private SetFrameContractCommand validFrameContractCommand(String customerId) {
@ -1049,7 +1054,7 @@ class CustomerUseCaseTest {
@BeforeEach
void setUp() {
removeFrameContract = new RemoveFrameContract(customerRepository);
removeFrameContract = new RemoveFrameContract(customerRepository, unitOfWork);
}
@Test

View file

@ -5,6 +5,7 @@ import de.effigenix.application.masterdata.command.UpdateProductCategoryCommand;
import de.effigenix.domain.masterdata.*;
import de.effigenix.shared.common.RepositoryError;
import de.effigenix.shared.common.Result;
import de.effigenix.shared.persistence.UnitOfWork;
import de.effigenix.shared.security.ActorId;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
@ -27,11 +28,14 @@ class ProductCategoryUseCaseTest {
@Mock private ProductCategoryRepository categoryRepository;
@Mock private ArticleRepository articleRepository;
@Mock private UnitOfWork unitOfWork;
private ActorId performedBy;
@BeforeEach
void setUp() {
lenient().when(unitOfWork.executeAtomically(any()))
.thenAnswer(inv -> ((java.util.function.Supplier<?>) inv.getArgument(0)).get());
performedBy = ActorId.of("admin-user");
}
@ -59,7 +63,7 @@ class ProductCategoryUseCaseTest {
@BeforeEach
void setUp() {
useCase = new CreateProductCategory(categoryRepository);
useCase = new CreateProductCategory(categoryRepository, unitOfWork);
}
@Test
@ -186,7 +190,7 @@ class ProductCategoryUseCaseTest {
@BeforeEach
void setUp() {
useCase = new UpdateProductCategory(categoryRepository);
useCase = new UpdateProductCategory(categoryRepository, unitOfWork);
}
@Test
@ -378,7 +382,7 @@ class ProductCategoryUseCaseTest {
@BeforeEach
void setUp() {
useCase = new DeleteProductCategory(categoryRepository, articleRepository);
useCase = new DeleteProductCategory(categoryRepository, articleRepository, unitOfWork);
}
@Test

View file

@ -5,6 +5,7 @@ import de.effigenix.domain.masterdata.*;
import de.effigenix.shared.common.ContactInfo;
import de.effigenix.shared.common.RepositoryError;
import de.effigenix.shared.common.Result;
import de.effigenix.shared.persistence.UnitOfWork;
import de.effigenix.shared.security.ActorId;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
@ -29,6 +30,7 @@ import static org.mockito.Mockito.*;
class SupplierUseCaseTest {
@Mock private SupplierRepository supplierRepository;
@Mock private UnitOfWork unitOfWork;
private final ActorId performedBy = ActorId.of("admin-user");
@ -105,7 +107,9 @@ class SupplierUseCaseTest {
@BeforeEach
void setUp() {
createSupplier = new CreateSupplier(supplierRepository);
lenient().when(unitOfWork.executeAtomically(any()))
.thenAnswer(inv -> ((java.util.function.Supplier<?>) inv.getArgument(0)).get());
createSupplier = new CreateSupplier(supplierRepository, unitOfWork);
}
@Test
@ -214,7 +218,9 @@ class SupplierUseCaseTest {
@BeforeEach
void setUp() {
updateSupplier = new UpdateSupplier(supplierRepository);
lenient().when(unitOfWork.executeAtomically(any()))
.thenAnswer(inv -> ((java.util.function.Supplier<?>) inv.getArgument(0)).get());
updateSupplier = new UpdateSupplier(supplierRepository, unitOfWork);
}
@Test
@ -448,7 +454,9 @@ class SupplierUseCaseTest {
@BeforeEach
void setUp() {
activateSupplier = new ActivateSupplier(supplierRepository);
lenient().when(unitOfWork.executeAtomically(any()))
.thenAnswer(inv -> ((java.util.function.Supplier<?>) inv.getArgument(0)).get());
activateSupplier = new ActivateSupplier(supplierRepository, unitOfWork);
}
@Test
@ -519,7 +527,9 @@ class SupplierUseCaseTest {
@BeforeEach
void setUp() {
deactivateSupplier = new DeactivateSupplier(supplierRepository);
lenient().when(unitOfWork.executeAtomically(any()))
.thenAnswer(inv -> ((java.util.function.Supplier<?>) inv.getArgument(0)).get());
deactivateSupplier = new DeactivateSupplier(supplierRepository, unitOfWork);
}
@Test
@ -590,7 +600,9 @@ class SupplierUseCaseTest {
@BeforeEach
void setUp() {
rateSupplier = new RateSupplier(supplierRepository);
lenient().when(unitOfWork.executeAtomically(any()))
.thenAnswer(inv -> ((java.util.function.Supplier<?>) inv.getArgument(0)).get());
rateSupplier = new RateSupplier(supplierRepository, unitOfWork);
}
@Test
@ -699,7 +711,9 @@ class SupplierUseCaseTest {
@BeforeEach
void setUp() {
addCertificate = new AddCertificate(supplierRepository);
lenient().when(unitOfWork.executeAtomically(any()))
.thenAnswer(inv -> ((java.util.function.Supplier<?>) inv.getArgument(0)).get());
addCertificate = new AddCertificate(supplierRepository, unitOfWork);
}
@Test
@ -817,7 +831,9 @@ class SupplierUseCaseTest {
@BeforeEach
void setUp() {
removeCertificate = new RemoveCertificate(supplierRepository);
lenient().when(unitOfWork.executeAtomically(any()))
.thenAnswer(inv -> ((java.util.function.Supplier<?>) inv.getArgument(0)).get());
removeCertificate = new RemoveCertificate(supplierRepository, unitOfWork);
}
@Test

View file

@ -5,6 +5,7 @@ import de.effigenix.application.usermanagement.dto.UserDTO;
import de.effigenix.domain.usermanagement.*;
import de.effigenix.shared.common.Result;
import de.effigenix.shared.security.ActorId;
import de.effigenix.shared.persistence.UnitOfWork;
import de.effigenix.shared.security.AuthorizationPort;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
@ -17,6 +18,7 @@ import java.time.OffsetDateTime;
import java.time.ZoneOffset;
import java.util.HashSet;
import java.util.Optional;
import java.util.function.Supplier;
import static org.assertj.core.api.Assertions.*;
import static org.mockito.ArgumentMatchers.*;
@ -30,6 +32,7 @@ class AssignRoleTest {
@Mock private RoleRepository roleRepository;
@Mock private AuditLogger auditLogger;
@Mock private AuthorizationPort authPort;
@Mock private UnitOfWork unitOfWork;
private AssignRole assignRole;
private ActorId performedBy;
@ -38,7 +41,9 @@ class AssignRoleTest {
@BeforeEach
void setUp() {
assignRole = new AssignRole(userRepository, roleRepository, auditLogger, authPort);
lenient().when(unitOfWork.executeAtomically(any()))
.thenAnswer(inv -> ((Supplier<?>) inv.getArgument(0)).get());
assignRole = new AssignRole(userRepository, roleRepository, auditLogger, authPort, unitOfWork);
performedBy = ActorId.of("admin-user");
testUser = User.reconstitute(
UserId.of("user-1"), "john.doe", "john@example.com",

View file

@ -4,6 +4,7 @@ import de.effigenix.application.usermanagement.command.AuthenticateCommand;
import de.effigenix.application.usermanagement.dto.SessionToken;
import de.effigenix.domain.usermanagement.*;
import de.effigenix.shared.common.Result;
import de.effigenix.shared.persistence.UnitOfWork;
import de.effigenix.shared.security.ActorId;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
@ -17,6 +18,7 @@ import java.time.OffsetDateTime;
import java.time.ZoneOffset;
import java.util.HashSet;
import java.util.Optional;
import java.util.function.Supplier;
import static org.assertj.core.api.Assertions.*;
import static org.mockito.ArgumentMatchers.*;
@ -30,6 +32,7 @@ class AuthenticateUserTest {
@Mock private PasswordHasher passwordHasher;
@Mock private SessionManager sessionManager;
@Mock private AuditLogger auditLogger;
@Mock private UnitOfWork unitOfWork;
@InjectMocks
private AuthenticateUser authenticateUser;
@ -41,6 +44,8 @@ class AuthenticateUserTest {
@BeforeEach
void setUp() {
lenient().when(unitOfWork.executeAtomically(any()))
.thenAnswer(inv -> ((Supplier<?>) inv.getArgument(0)).get());
validCommand = new AuthenticateCommand("john.doe", "Password123!");
validPasswordHash = new PasswordHash("$2a$12$R9h/cIPz0gi.URNN3kh2OPST9EBwVeL00lzQRYe3z08MZx3e8YCWW");

View file

@ -4,6 +4,7 @@ import de.effigenix.application.usermanagement.command.ChangePasswordCommand;
import de.effigenix.domain.usermanagement.*;
import de.effigenix.shared.common.Result;
import de.effigenix.shared.security.ActorId;
import de.effigenix.shared.persistence.UnitOfWork;
import de.effigenix.shared.security.AuthorizationPort;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
@ -16,6 +17,7 @@ import java.time.OffsetDateTime;
import java.time.ZoneOffset;
import java.util.HashSet;
import java.util.Optional;
import java.util.function.Supplier;
import static org.assertj.core.api.Assertions.*;
import static org.mockito.ArgumentMatchers.*;
@ -29,6 +31,7 @@ class ChangePasswordTest {
@Mock private PasswordHasher passwordHasher;
@Mock private AuditLogger auditLogger;
@Mock private AuthorizationPort authPort;
@Mock private UnitOfWork unitOfWork;
private ChangePassword changePassword;
private User testUser;
@ -39,7 +42,9 @@ class ChangePasswordTest {
@BeforeEach
void setUp() {
changePassword = new ChangePassword(userRepository, passwordHasher, auditLogger, authPort);
lenient().when(unitOfWork.executeAtomically(any()))
.thenAnswer(inv -> ((Supplier<?>) inv.getArgument(0)).get());
changePassword = new ChangePassword(userRepository, passwordHasher, auditLogger, authPort, unitOfWork);
oldPasswordHash = new PasswordHash("$2a$12$R9h/cIPz0gi.URNN3kh2OPST9EBwVeL00lzQRYe3z08MZx3e8YCWW");
newPasswordHash = new PasswordHash("$2b$12$R9h/cIPz0gi.URNN3kh2OPST9EBwVeL00lzQRYe3z08MZx3e8YCWW");

View file

@ -4,6 +4,7 @@ import de.effigenix.application.usermanagement.command.CreateUserCommand;
import de.effigenix.domain.usermanagement.*;
import de.effigenix.shared.common.Result;
import de.effigenix.shared.security.ActorId;
import de.effigenix.shared.persistence.UnitOfWork;
import de.effigenix.shared.security.AuthorizationPort;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
@ -15,6 +16,7 @@ import org.mockito.junit.jupiter.MockitoExtension;
import java.util.HashSet;
import java.util.Optional;
import java.util.Set;
import java.util.function.Supplier;
import static org.assertj.core.api.Assertions.*;
import static org.mockito.ArgumentMatchers.any;
@ -30,6 +32,7 @@ class CreateUserTest {
@Mock private PasswordHasher passwordHasher;
@Mock private AuditLogger auditLogger;
@Mock private AuthorizationPort authPort;
@Mock private UnitOfWork unitOfWork;
private CreateUser createUser;
private CreateUserCommand validCommand;
@ -38,7 +41,9 @@ class CreateUserTest {
@BeforeEach
void setUp() {
createUser = new CreateUser(userRepository, roleRepository, passwordHasher, auditLogger, authPort);
lenient().when(unitOfWork.executeAtomically(any()))
.thenAnswer(inv -> ((Supplier<?>) inv.getArgument(0)).get());
createUser = new CreateUser(userRepository, roleRepository, passwordHasher, auditLogger, authPort, unitOfWork);
performedBy = ActorId.of("admin-user");
validPasswordHash = new PasswordHash("$2a$12$R9h/cIPz0gi.URNN3kh2OPST9EBwVeL00lzQRYe3z08MZx3e8YCWW");
validCommand = new CreateUserCommand("john.doe", "john@example.com", "Password123!", Set.of(RoleName.PRODUCTION_WORKER), "branch-1");

View file

@ -5,6 +5,7 @@ import de.effigenix.application.usermanagement.dto.UserDTO;
import de.effigenix.domain.usermanagement.*;
import de.effigenix.shared.common.Result;
import de.effigenix.shared.security.ActorId;
import de.effigenix.shared.persistence.UnitOfWork;
import de.effigenix.shared.security.AuthorizationPort;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
@ -17,6 +18,7 @@ import java.time.OffsetDateTime;
import java.time.ZoneOffset;
import java.util.HashSet;
import java.util.Optional;
import java.util.function.Supplier;
import static org.assertj.core.api.Assertions.*;
import static org.mockito.ArgumentMatchers.*;
@ -29,6 +31,7 @@ class LockUserTest {
@Mock private UserRepository userRepository;
@Mock private AuditLogger auditLogger;
@Mock private AuthorizationPort authPort;
@Mock private UnitOfWork unitOfWork;
private LockUser lockUser;
private ActorId performedBy;
@ -36,7 +39,9 @@ class LockUserTest {
@BeforeEach
void setUp() {
lockUser = new LockUser(userRepository, auditLogger, authPort);
lenient().when(unitOfWork.executeAtomically(any()))
.thenAnswer(inv -> ((Supplier<?>) inv.getArgument(0)).get());
lockUser = new LockUser(userRepository, auditLogger, authPort, unitOfWork);
performedBy = ActorId.of("admin-user");
activeUser = User.reconstitute(
UserId.of("user-1"), "john.doe", "john@example.com",

View file

@ -5,6 +5,7 @@ import de.effigenix.application.usermanagement.dto.UserDTO;
import de.effigenix.domain.usermanagement.*;
import de.effigenix.shared.common.Result;
import de.effigenix.shared.security.ActorId;
import de.effigenix.shared.persistence.UnitOfWork;
import de.effigenix.shared.security.AuthorizationPort;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
@ -18,6 +19,7 @@ import java.time.ZoneOffset;
import java.util.HashSet;
import java.util.Optional;
import java.util.Set;
import java.util.function.Supplier;
import static org.assertj.core.api.Assertions.*;
import static org.mockito.ArgumentMatchers.*;
@ -31,6 +33,7 @@ class RemoveRoleTest {
@Mock private RoleRepository roleRepository;
@Mock private AuditLogger auditLogger;
@Mock private AuthorizationPort authPort;
@Mock private UnitOfWork unitOfWork;
private RemoveRole removeRole;
private ActorId performedBy;
@ -39,7 +42,9 @@ class RemoveRoleTest {
@BeforeEach
void setUp() {
removeRole = new RemoveRole(userRepository, roleRepository, auditLogger, authPort);
lenient().when(unitOfWork.executeAtomically(any()))
.thenAnswer(inv -> ((Supplier<?>) inv.getArgument(0)).get());
removeRole = new RemoveRole(userRepository, roleRepository, auditLogger, authPort, unitOfWork);
performedBy = ActorId.of("admin-user");
workerRole = Role.reconstitute(RoleId.generate(), RoleName.PRODUCTION_WORKER, new HashSet<>(), "Production Worker");
userWithRole = User.reconstitute(

View file

@ -5,6 +5,7 @@ import de.effigenix.application.usermanagement.dto.UserDTO;
import de.effigenix.domain.usermanagement.*;
import de.effigenix.shared.common.Result;
import de.effigenix.shared.security.ActorId;
import de.effigenix.shared.persistence.UnitOfWork;
import de.effigenix.shared.security.AuthorizationPort;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
@ -17,6 +18,7 @@ import java.time.OffsetDateTime;
import java.time.ZoneOffset;
import java.util.HashSet;
import java.util.Optional;
import java.util.function.Supplier;
import static org.assertj.core.api.Assertions.*;
import static org.mockito.ArgumentMatchers.*;
@ -29,6 +31,7 @@ class UnlockUserTest {
@Mock private UserRepository userRepository;
@Mock private AuditLogger auditLogger;
@Mock private AuthorizationPort authPort;
@Mock private UnitOfWork unitOfWork;
private UnlockUser unlockUser;
private ActorId performedBy;
@ -36,7 +39,9 @@ class UnlockUserTest {
@BeforeEach
void setUp() {
unlockUser = new UnlockUser(userRepository, auditLogger, authPort);
lenient().when(unitOfWork.executeAtomically(any()))
.thenAnswer(inv -> ((Supplier<?>) inv.getArgument(0)).get());
unlockUser = new UnlockUser(userRepository, auditLogger, authPort, unitOfWork);
performedBy = ActorId.of("admin-user");
lockedUser = User.reconstitute(
UserId.of("user-1"), "john.doe", "john@example.com",

View file

@ -5,6 +5,7 @@ import de.effigenix.application.usermanagement.dto.UserDTO;
import de.effigenix.domain.usermanagement.*;
import de.effigenix.shared.common.Result;
import de.effigenix.shared.security.ActorId;
import de.effigenix.shared.persistence.UnitOfWork;
import de.effigenix.shared.security.AuthorizationPort;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
@ -17,6 +18,7 @@ import java.time.OffsetDateTime;
import java.time.ZoneOffset;
import java.util.HashSet;
import java.util.Optional;
import java.util.function.Supplier;
import static org.assertj.core.api.Assertions.*;
import static org.mockito.ArgumentMatchers.*;
@ -29,6 +31,7 @@ class UpdateUserTest {
@Mock private UserRepository userRepository;
@Mock private AuditLogger auditLogger;
@Mock private AuthorizationPort authPort;
@Mock private UnitOfWork unitOfWork;
private UpdateUser updateUser;
private ActorId performedBy;
@ -36,7 +39,9 @@ class UpdateUserTest {
@BeforeEach
void setUp() {
updateUser = new UpdateUser(userRepository, auditLogger, authPort);
lenient().when(unitOfWork.executeAtomically(any()))
.thenAnswer(inv -> ((Supplier<?>) inv.getArgument(0)).get());
updateUser = new UpdateUser(userRepository, auditLogger, authPort, unitOfWork);
performedBy = ActorId.of("admin-user");
testUser = User.reconstitute(
UserId.of("user-1"), "john.doe", "john@example.com",

View file

@ -3,19 +3,12 @@ package de.effigenix.infrastructure;
import com.fasterxml.jackson.databind.ObjectMapper;
import de.effigenix.domain.usermanagement.RoleName;
import de.effigenix.domain.usermanagement.UserStatus;
import de.effigenix.infrastructure.masterdata.persistence.entity.ArticleEntity;
import de.effigenix.infrastructure.masterdata.persistence.entity.ProductCategoryEntity;
import de.effigenix.infrastructure.masterdata.persistence.repository.ArticleJpaRepository;
import de.effigenix.infrastructure.masterdata.persistence.repository.ProductCategoryJpaRepository;
import de.effigenix.infrastructure.usermanagement.persistence.entity.RoleEntity;
import de.effigenix.infrastructure.usermanagement.persistence.entity.UserEntity;
import de.effigenix.infrastructure.usermanagement.persistence.repository.RoleJpaRepository;
import de.effigenix.infrastructure.usermanagement.persistence.repository.UserJpaRepository;
import io.jsonwebtoken.Jwts;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.jdbc.core.simple.JdbcClient;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.transaction.annotation.Transactional;
@ -44,16 +37,7 @@ public abstract class AbstractIntegrationTest {
protected ObjectMapper objectMapper;
@Autowired
protected UserJpaRepository userRepository;
@Autowired
protected RoleJpaRepository roleRepository;
@Autowired
protected ArticleJpaRepository articleRepository;
@Autowired
protected ProductCategoryJpaRepository productCategoryRepository;
protected JdbcClient jdbc;
@Value("${jwt.secret}")
protected String jwtSecret;
@ -103,29 +87,70 @@ public abstract class AbstractIntegrationTest {
.compact();
}
protected RoleEntity createRole(RoleName roleName, String description) {
return roleRepository.findByName(roleName).orElseGet(() -> {
RoleEntity role = new RoleEntity(
UUID.randomUUID().toString(), roleName, Set.of(), description);
return roleRepository.save(role);
});
protected String createRole(RoleName roleName, String description) {
var existing = jdbc.sql("SELECT id FROM roles WHERE name = :name")
.param("name", roleName.name())
.query(String.class)
.optional();
if (existing.isPresent()) {
return existing.get();
}
String id = UUID.randomUUID().toString();
jdbc.sql("INSERT INTO roles (id, name, description) VALUES (:id, :name, :description)")
.param("id", id)
.param("name", roleName.name())
.param("description", description)
.update();
return id;
}
protected UserEntity createUser(String username, String email, Set<RoleEntity> roles, String branchId) {
UserEntity user = new UserEntity(
UUID.randomUUID().toString(), username, email,
BCRYPT_PASS123, roles,
branchId, UserStatus.ACTIVE, OffsetDateTime.now(ZoneOffset.UTC), null);
return userRepository.save(user);
protected String createUser(String username, String email, Set<String> roleIds, String branchId) {
String id = UUID.randomUUID().toString();
jdbc.sql("""
INSERT INTO users (id, username, email, password_hash, branch_id, status, created_at)
VALUES (:id, :username, :email, :passwordHash, :branchId, :status, :createdAt)
""")
.param("id", id)
.param("username", username)
.param("email", email)
.param("passwordHash", BCRYPT_PASS123)
.param("branchId", branchId)
.param("status", UserStatus.ACTIVE.name())
.param("createdAt", OffsetDateTime.now(ZoneOffset.UTC))
.update();
for (String roleId : roleIds) {
jdbc.sql("INSERT INTO user_roles (user_id, role_id) VALUES (:userId, :roleId)")
.param("userId", id)
.param("roleId", roleId)
.update();
}
return id;
}
protected String createArticleId() {
String categoryId = UUID.randomUUID().toString();
productCategoryRepository.save(new ProductCategoryEntity(categoryId, "TestCat-" + categoryId.substring(0, 8), null));
jdbc.sql("INSERT INTO product_categories (id, name) VALUES (:id, :name)")
.param("id", categoryId)
.param("name", "TestCat-" + categoryId.substring(0, 8))
.update();
String articleId = UUID.randomUUID().toString();
var now = OffsetDateTime.now(ZoneOffset.UTC);
var article = new ArticleEntity(
UUID.randomUUID().toString(), "TestArticle-" + UUID.randomUUID().toString().substring(0, 8),
"ART-" + UUID.randomUUID().toString().substring(0, 8), categoryId, "ACTIVE", now, now);
return articleRepository.save(article).getId();
jdbc.sql("""
INSERT INTO articles (id, name, article_number, category_id, status, created_at, updated_at)
VALUES (:id, :name, :articleNumber, :categoryId, :status, :createdAt, :updatedAt)
""")
.param("id", articleId)
.param("name", "TestArticle-" + UUID.randomUUID().toString().substring(0, 8))
.param("articleNumber", "ART-" + UUID.randomUUID().toString().substring(0, 8))
.param("categoryId", categoryId)
.param("status", "ACTIVE")
.param("createdAt", now)
.param("updatedAt", now)
.update();
return articleId;
}
}

View file

@ -5,8 +5,6 @@ import de.effigenix.infrastructure.AbstractIntegrationTest;
import de.effigenix.infrastructure.inventory.web.dto.AddStockBatchRequest;
import de.effigenix.infrastructure.inventory.web.dto.CreateStockRequest;
import de.effigenix.infrastructure.inventory.web.dto.ReserveStockRequest;
import de.effigenix.infrastructure.usermanagement.persistence.entity.RoleEntity;
import de.effigenix.infrastructure.usermanagement.persistence.entity.UserEntity;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Nested;
@ -40,14 +38,14 @@ class StockControllerIntegrationTest extends AbstractIntegrationTest {
@BeforeEach
void setUp() throws Exception {
RoleEntity adminRole = createRole(RoleName.ADMIN, "Admin");
RoleEntity viewerRole = createRole(RoleName.PRODUCTION_WORKER, "Viewer");
String adminRoleId = createRole(RoleName.ADMIN, "Admin");
String viewerRoleId = createRole(RoleName.PRODUCTION_WORKER, "Viewer");
UserEntity admin = createUser("stock.admin", "stock.admin@test.com", Set.of(adminRole), "BRANCH-01");
UserEntity viewer = createUser("stock.viewer", "stock.viewer@test.com", Set.of(viewerRole), "BRANCH-01");
String adminId = createUser("stock.admin", "stock.admin@test.com", Set.of(adminRoleId), "BRANCH-01");
String viewerId = createUser("stock.viewer", "stock.viewer@test.com", Set.of(viewerRoleId), "BRANCH-01");
adminToken = generateToken(admin.getId(), "stock.admin", "STOCK_WRITE,STOCK_READ");
viewerToken = generateToken(viewer.getId(), "stock.viewer", "USER_READ");
adminToken = generateToken(adminId, "stock.admin", "STOCK_WRITE,STOCK_READ");
viewerToken = generateToken(viewerId, "stock.viewer", "USER_READ");
storageLocationId = createStorageLocation();
}

View file

@ -5,8 +5,6 @@ import de.effigenix.infrastructure.AbstractIntegrationTest;
import de.effigenix.infrastructure.inventory.web.dto.CreateStorageLocationRequest;
import de.effigenix.infrastructure.inventory.web.dto.CreateStockRequest;
import de.effigenix.infrastructure.inventory.web.dto.UpdateStorageLocationRequest;
import de.effigenix.infrastructure.usermanagement.persistence.entity.RoleEntity;
import de.effigenix.infrastructure.usermanagement.persistence.entity.UserEntity;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
@ -35,16 +33,16 @@ class StorageLocationControllerIntegrationTest extends AbstractIntegrationTest {
@BeforeEach
void setUp() {
RoleEntity adminRole = createRole(RoleName.ADMIN, "Admin");
RoleEntity viewerRole = createRole(RoleName.PRODUCTION_WORKER, "Viewer");
String adminRoleId = createRole(RoleName.ADMIN, "Admin");
String viewerRoleId = createRole(RoleName.PRODUCTION_WORKER, "Viewer");
UserEntity admin = createUser("inv.admin", "inv.admin@test.com", Set.of(adminRole), "BRANCH-01");
UserEntity reader = createUser("inv.reader", "inv.reader@test.com", Set.of(viewerRole), "BRANCH-01");
UserEntity viewer = createUser("inv.viewer", "inv.viewer@test.com", Set.of(viewerRole), "BRANCH-01");
String adminId = createUser("inv.admin", "inv.admin@test.com", Set.of(adminRoleId), "BRANCH-01");
String readerId = createUser("inv.reader", "inv.reader@test.com", Set.of(viewerRoleId), "BRANCH-01");
String viewerId = createUser("inv.viewer", "inv.viewer@test.com", Set.of(viewerRoleId), "BRANCH-01");
adminToken = generateToken(admin.getId(), "inv.admin", "STOCK_WRITE,STOCK_READ");
readerToken = generateToken(reader.getId(), "inv.reader", "STOCK_READ");
viewerToken = generateToken(viewer.getId(), "inv.viewer", "USER_READ");
adminToken = generateToken(adminId, "inv.admin", "STOCK_WRITE,STOCK_READ");
readerToken = generateToken(readerId, "inv.reader", "STOCK_READ");
viewerToken = generateToken(viewerId, "inv.viewer", "USER_READ");
}
// ==================== Lagerort anlegen Pflichtfelder ====================

View file

@ -5,8 +5,6 @@ import de.effigenix.domain.masterdata.Unit;
import de.effigenix.domain.usermanagement.RoleName;
import de.effigenix.infrastructure.AbstractIntegrationTest;
import de.effigenix.infrastructure.masterdata.web.dto.*;
import de.effigenix.infrastructure.usermanagement.persistence.entity.RoleEntity;
import de.effigenix.infrastructure.usermanagement.persistence.entity.UserEntity;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
@ -35,14 +33,14 @@ class ArticleControllerIntegrationTest extends AbstractIntegrationTest {
@BeforeEach
void setUp() throws Exception {
RoleEntity adminRole = createRole(RoleName.ADMIN, "Admin");
RoleEntity viewerRole = createRole(RoleName.PRODUCTION_WORKER, "Viewer");
String adminRoleId = createRole(RoleName.ADMIN, "Admin");
String viewerRoleId = createRole(RoleName.PRODUCTION_WORKER, "Viewer");
UserEntity admin = createUser("art.admin", "art.admin@test.com", Set.of(adminRole), "BRANCH-01");
UserEntity viewer = createUser("art.viewer", "art.viewer@test.com", Set.of(viewerRole), "BRANCH-01");
String adminId = createUser("art.admin", "art.admin@test.com", Set.of(adminRoleId), "BRANCH-01");
String viewerId = createUser("art.viewer", "art.viewer@test.com", Set.of(viewerRoleId), "BRANCH-01");
adminToken = generateToken(admin.getId(), "art.admin", "MASTERDATA_WRITE");
viewerToken = generateToken(viewer.getId(), "art.viewer", "USER_READ");
adminToken = generateToken(adminId, "art.admin", "MASTERDATA_WRITE");
viewerToken = generateToken(viewerId, "art.viewer", "USER_READ");
// Vorbedingung: Kategorie erstellen
categoryId = createCategory("Obst & Gemüse");

View file

@ -4,8 +4,6 @@ import de.effigenix.domain.masterdata.*;
import de.effigenix.domain.usermanagement.RoleName;
import de.effigenix.infrastructure.AbstractIntegrationTest;
import de.effigenix.infrastructure.masterdata.web.dto.*;
import de.effigenix.infrastructure.usermanagement.persistence.entity.RoleEntity;
import de.effigenix.infrastructure.usermanagement.persistence.entity.UserEntity;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
@ -35,14 +33,14 @@ class CustomerControllerIntegrationTest extends AbstractIntegrationTest {
@BeforeEach
void setUp() {
RoleEntity adminRole = createRole(RoleName.ADMIN, "Admin");
RoleEntity viewerRole = createRole(RoleName.PRODUCTION_WORKER, "Viewer");
String adminRoleId = createRole(RoleName.ADMIN, "Admin");
String viewerRoleId = createRole(RoleName.PRODUCTION_WORKER, "Viewer");
UserEntity admin = createUser("cus.admin", "cus.admin@test.com", Set.of(adminRole), "BRANCH-01");
UserEntity viewer = createUser("cus.viewer", "cus.viewer@test.com", Set.of(viewerRole), "BRANCH-01");
String adminId = createUser("cus.admin", "cus.admin@test.com", Set.of(adminRoleId), "BRANCH-01");
String viewerId = createUser("cus.viewer", "cus.viewer@test.com", Set.of(viewerRoleId), "BRANCH-01");
adminToken = generateToken(admin.getId(), "cus.admin", "MASTERDATA_WRITE");
viewerToken = generateToken(viewer.getId(), "cus.viewer", "USER_READ");
adminToken = generateToken(adminId, "cus.admin", "MASTERDATA_WRITE");
viewerToken = generateToken(viewerId, "cus.viewer", "USER_READ");
}
// ==================== TC-CUS-01: B2C-Kunde erstellen ====================

View file

@ -4,8 +4,6 @@ import de.effigenix.domain.usermanagement.RoleName;
import de.effigenix.infrastructure.AbstractIntegrationTest;
import de.effigenix.infrastructure.masterdata.web.dto.CreateProductCategoryRequest;
import de.effigenix.infrastructure.masterdata.web.dto.UpdateProductCategoryRequest;
import de.effigenix.infrastructure.usermanagement.persistence.entity.RoleEntity;
import de.effigenix.infrastructure.usermanagement.persistence.entity.UserEntity;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
@ -32,14 +30,14 @@ class ProductCategoryControllerIntegrationTest extends AbstractIntegrationTest {
@BeforeEach
void setUp() {
RoleEntity adminRole = createRole(RoleName.ADMIN, "Admin");
RoleEntity viewerRole = createRole(RoleName.PRODUCTION_WORKER, "Viewer");
String adminRoleId = createRole(RoleName.ADMIN, "Admin");
String viewerRoleId = createRole(RoleName.PRODUCTION_WORKER, "Viewer");
UserEntity admin = createUser("cat.admin", "cat.admin@test.com", Set.of(adminRole), "BRANCH-01");
UserEntity viewer = createUser("cat.viewer", "cat.viewer@test.com", Set.of(viewerRole), "BRANCH-01");
String adminId = createUser("cat.admin", "cat.admin@test.com", Set.of(adminRoleId), "BRANCH-01");
String viewerId = createUser("cat.viewer", "cat.viewer@test.com", Set.of(viewerRoleId), "BRANCH-01");
adminToken = generateToken(admin.getId(), "cat.admin", "MASTERDATA_WRITE");
viewerToken = generateToken(viewer.getId(), "cat.viewer", "USER_READ");
adminToken = generateToken(adminId, "cat.admin", "MASTERDATA_WRITE");
viewerToken = generateToken(viewerId, "cat.viewer", "USER_READ");
}
// ==================== TC-CAT-01: Kategorie erstellen (Happy Path) ====================

View file

@ -3,8 +3,6 @@ package de.effigenix.infrastructure.masterdata.web;
import de.effigenix.domain.usermanagement.RoleName;
import de.effigenix.infrastructure.AbstractIntegrationTest;
import de.effigenix.infrastructure.masterdata.web.dto.*;
import de.effigenix.infrastructure.usermanagement.persistence.entity.RoleEntity;
import de.effigenix.infrastructure.usermanagement.persistence.entity.UserEntity;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
@ -32,14 +30,14 @@ class SupplierControllerIntegrationTest extends AbstractIntegrationTest {
@BeforeEach
void setUp() {
RoleEntity adminRole = createRole(RoleName.ADMIN, "Admin");
RoleEntity viewerRole = createRole(RoleName.PRODUCTION_WORKER, "Viewer");
String adminRoleId = createRole(RoleName.ADMIN, "Admin");
String viewerRoleId = createRole(RoleName.PRODUCTION_WORKER, "Viewer");
UserEntity admin = createUser("sup.admin", "sup.admin@test.com", Set.of(adminRole), "BRANCH-01");
UserEntity viewer = createUser("sup.viewer", "sup.viewer@test.com", Set.of(viewerRole), "BRANCH-01");
String adminId = createUser("sup.admin", "sup.admin@test.com", Set.of(adminRoleId), "BRANCH-01");
String viewerId = createUser("sup.viewer", "sup.viewer@test.com", Set.of(viewerRoleId), "BRANCH-01");
adminToken = generateToken(admin.getId(), "sup.admin", "MASTERDATA_WRITE");
viewerToken = generateToken(viewer.getId(), "sup.viewer", "USER_READ");
adminToken = generateToken(adminId, "sup.admin", "MASTERDATA_WRITE");
viewerToken = generateToken(viewerId, "sup.viewer", "USER_READ");
}
// ==================== TC-SUP-01: Lieferant erstellen Pflichtfelder ====================

View file

@ -3,13 +3,10 @@ package de.effigenix.infrastructure.production.web;
import de.effigenix.domain.usermanagement.RoleName;
import de.effigenix.infrastructure.AbstractIntegrationTest;
import de.effigenix.infrastructure.production.web.dto.PlanBatchRequest;
import de.effigenix.infrastructure.usermanagement.persistence.entity.RoleEntity;
import de.effigenix.infrastructure.usermanagement.persistence.entity.UserEntity;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import java.time.LocalDate;
@ -30,14 +27,14 @@ class BatchControllerIntegrationTest extends AbstractIntegrationTest {
@BeforeEach
void setUp() throws Exception {
RoleEntity adminRole = createRole(RoleName.ADMIN, "Admin");
RoleEntity viewerRole = createRole(RoleName.PRODUCTION_WORKER, "Viewer");
String adminRoleId = createRole(RoleName.ADMIN, "Admin");
String viewerRoleId = createRole(RoleName.PRODUCTION_WORKER, "Viewer");
UserEntity admin = createUser("batch.admin", "batch.admin@test.com", Set.of(adminRole), "BRANCH-01");
UserEntity viewer = createUser("batch.viewer", "batch.viewer@test.com", Set.of(viewerRole), "BRANCH-01");
String adminId = createUser("batch.admin", "batch.admin@test.com", Set.of(adminRoleId), "BRANCH-01");
String viewerId = createUser("batch.viewer", "batch.viewer@test.com", Set.of(viewerRoleId), "BRANCH-01");
adminToken = generateToken(admin.getId(), "batch.admin", "BATCH_WRITE,BATCH_READ,RECIPE_WRITE,RECIPE_READ");
viewerToken = generateToken(viewer.getId(), "batch.viewer", "USER_READ");
adminToken = generateToken(adminId, "batch.admin", "BATCH_WRITE,BATCH_READ,RECIPE_WRITE,RECIPE_READ");
viewerToken = generateToken(viewerId, "batch.viewer", "USER_READ");
}
@Nested

View file

@ -2,8 +2,6 @@ package de.effigenix.infrastructure.production.web;
import de.effigenix.domain.usermanagement.RoleName;
import de.effigenix.infrastructure.AbstractIntegrationTest;
import de.effigenix.infrastructure.usermanagement.persistence.entity.RoleEntity;
import de.effigenix.infrastructure.usermanagement.persistence.entity.UserEntity;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
@ -24,14 +22,14 @@ class GetBatchIntegrationTest extends AbstractIntegrationTest {
@BeforeEach
void setUp() {
RoleEntity adminRole = createRole(RoleName.ADMIN, "Admin");
RoleEntity viewerRole = createRole(RoleName.PRODUCTION_WORKER, "Viewer");
String adminRoleId = createRole(RoleName.ADMIN, "Admin");
String viewerRoleId = createRole(RoleName.PRODUCTION_WORKER, "Viewer");
UserEntity admin = createUser("batch.admin", "batch.admin@test.com", Set.of(adminRole), "BRANCH-01");
UserEntity viewer = createUser("batch.viewer", "batch.viewer@test.com", Set.of(viewerRole), "BRANCH-01");
String adminId = createUser("batch.admin", "batch.admin@test.com", Set.of(adminRoleId), "BRANCH-01");
String viewerId = createUser("batch.viewer", "batch.viewer@test.com", Set.of(viewerRoleId), "BRANCH-01");
adminToken = generateToken(admin.getId(), "batch.admin", "BATCH_WRITE,BATCH_READ,RECIPE_WRITE,RECIPE_READ");
viewerToken = generateToken(viewer.getId(), "batch.viewer", "USER_READ");
adminToken = generateToken(adminId, "batch.admin", "BATCH_WRITE,BATCH_READ,RECIPE_WRITE,RECIPE_READ");
viewerToken = generateToken(viewerId, "batch.viewer", "USER_READ");
}
@Test

View file

@ -2,8 +2,6 @@ package de.effigenix.infrastructure.production.web;
import de.effigenix.domain.usermanagement.RoleName;
import de.effigenix.infrastructure.AbstractIntegrationTest;
import de.effigenix.infrastructure.usermanagement.persistence.entity.RoleEntity;
import de.effigenix.infrastructure.usermanagement.persistence.entity.UserEntity;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
@ -23,14 +21,14 @@ class GetRecipeIntegrationTest extends AbstractIntegrationTest {
@BeforeEach
void setUp() {
RoleEntity adminRole = createRole(RoleName.ADMIN, "Admin");
RoleEntity viewerRole = createRole(RoleName.PRODUCTION_WORKER, "Viewer");
String adminRoleId = createRole(RoleName.ADMIN, "Admin");
String viewerRoleId = createRole(RoleName.PRODUCTION_WORKER, "Viewer");
UserEntity admin = createUser("recipe.admin", "recipe.admin@test.com", Set.of(adminRole), "BRANCH-01");
UserEntity viewer = createUser("recipe.viewer", "recipe.viewer@test.com", Set.of(viewerRole), "BRANCH-01");
String adminId = createUser("recipe.admin", "recipe.admin@test.com", Set.of(adminRoleId), "BRANCH-01");
String viewerId = createUser("recipe.viewer", "recipe.viewer@test.com", Set.of(viewerRoleId), "BRANCH-01");
adminToken = generateToken(admin.getId(), "recipe.admin", "RECIPE_WRITE,RECIPE_READ");
viewerToken = generateToken(viewer.getId(), "recipe.viewer", "USER_READ");
adminToken = generateToken(adminId, "recipe.admin", "RECIPE_WRITE,RECIPE_READ");
viewerToken = generateToken(viewerId, "recipe.viewer", "USER_READ");
}
@Test

View file

@ -2,8 +2,6 @@ package de.effigenix.infrastructure.production.web;
import de.effigenix.domain.usermanagement.RoleName;
import de.effigenix.infrastructure.AbstractIntegrationTest;
import de.effigenix.infrastructure.usermanagement.persistence.entity.RoleEntity;
import de.effigenix.infrastructure.usermanagement.persistence.entity.UserEntity;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
@ -25,14 +23,14 @@ class ListBatchesIntegrationTest extends AbstractIntegrationTest {
@BeforeEach
void setUp() {
RoleEntity adminRole = createRole(RoleName.ADMIN, "Admin");
RoleEntity viewerRole = createRole(RoleName.PRODUCTION_WORKER, "Viewer");
String adminRoleId = createRole(RoleName.ADMIN, "Admin");
String viewerRoleId = createRole(RoleName.PRODUCTION_WORKER, "Viewer");
UserEntity admin = createUser("batch.admin", "batch.admin@test.com", Set.of(adminRole), "BRANCH-01");
UserEntity viewer = createUser("batch.viewer", "batch.viewer@test.com", Set.of(viewerRole), "BRANCH-01");
String adminId = createUser("batch.admin", "batch.admin@test.com", Set.of(adminRoleId), "BRANCH-01");
String viewerId = createUser("batch.viewer", "batch.viewer@test.com", Set.of(viewerRoleId), "BRANCH-01");
adminToken = generateToken(admin.getId(), "batch.admin", "BATCH_WRITE,BATCH_READ,RECIPE_WRITE,RECIPE_READ");
viewerToken = generateToken(viewer.getId(), "batch.viewer", "USER_READ");
adminToken = generateToken(adminId, "batch.admin", "BATCH_WRITE,BATCH_READ,RECIPE_WRITE,RECIPE_READ");
viewerToken = generateToken(viewerId, "batch.viewer", "USER_READ");
}
@Test

View file

@ -2,8 +2,6 @@ package de.effigenix.infrastructure.production.web;
import de.effigenix.domain.usermanagement.RoleName;
import de.effigenix.infrastructure.AbstractIntegrationTest;
import de.effigenix.infrastructure.usermanagement.persistence.entity.RoleEntity;
import de.effigenix.infrastructure.usermanagement.persistence.entity.UserEntity;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
@ -24,14 +22,14 @@ class ListRecipesIntegrationTest extends AbstractIntegrationTest {
@BeforeEach
void setUp() {
RoleEntity adminRole = createRole(RoleName.ADMIN, "Admin");
RoleEntity viewerRole = createRole(RoleName.PRODUCTION_WORKER, "Viewer");
String adminRoleId = createRole(RoleName.ADMIN, "Admin");
String viewerRoleId = createRole(RoleName.PRODUCTION_WORKER, "Viewer");
UserEntity admin = createUser("recipe.admin", "recipe.admin@test.com", Set.of(adminRole), "BRANCH-01");
UserEntity viewer = createUser("recipe.viewer", "recipe.viewer@test.com", Set.of(viewerRole), "BRANCH-01");
String adminId = createUser("recipe.admin", "recipe.admin@test.com", Set.of(adminRoleId), "BRANCH-01");
String viewerId = createUser("recipe.viewer", "recipe.viewer@test.com", Set.of(viewerRoleId), "BRANCH-01");
adminToken = generateToken(admin.getId(), "recipe.admin", "RECIPE_WRITE,RECIPE_READ");
viewerToken = generateToken(viewer.getId(), "recipe.viewer", "USER_READ");
adminToken = generateToken(adminId, "recipe.admin", "RECIPE_WRITE,RECIPE_READ");
viewerToken = generateToken(viewerId, "recipe.viewer", "USER_READ");
}
@Test

View file

@ -4,8 +4,6 @@ import de.effigenix.domain.usermanagement.RoleName;
import de.effigenix.infrastructure.AbstractIntegrationTest;
import de.effigenix.infrastructure.production.web.dto.CreateProductionOrderRequest;
import de.effigenix.infrastructure.production.web.dto.PlanBatchRequest;
import de.effigenix.infrastructure.usermanagement.persistence.entity.RoleEntity;
import de.effigenix.infrastructure.usermanagement.persistence.entity.UserEntity;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Nested;
@ -29,15 +27,15 @@ class ProductionOrderControllerIntegrationTest extends AbstractIntegrationTest {
@BeforeEach
void setUp() throws Exception {
RoleEntity adminRole = createRole(RoleName.ADMIN, "Admin");
RoleEntity viewerRole = createRole(RoleName.PRODUCTION_WORKER, "Viewer");
String adminRoleId = createRole(RoleName.ADMIN, "Admin");
String viewerRoleId = createRole(RoleName.PRODUCTION_WORKER, "Viewer");
UserEntity admin = createUser("po.admin", "po.admin@test.com", Set.of(adminRole), "BRANCH-01");
UserEntity viewer = createUser("po.viewer", "po.viewer@test.com", Set.of(viewerRole), "BRANCH-01");
String adminId = createUser("po.admin", "po.admin@test.com", Set.of(adminRoleId), "BRANCH-01");
String viewerId = createUser("po.viewer", "po.viewer@test.com", Set.of(viewerRoleId), "BRANCH-01");
adminToken = generateToken(admin.getId(), "po.admin",
adminToken = generateToken(adminId, "po.admin",
"PRODUCTION_ORDER_WRITE,PRODUCTION_ORDER_READ,RECIPE_WRITE,RECIPE_READ,BATCH_WRITE,BATCH_READ");
viewerToken = generateToken(viewer.getId(), "po.viewer", "USER_READ");
viewerToken = generateToken(viewerId, "po.viewer", "USER_READ");
}
@Nested

View file

@ -2,8 +2,6 @@ package de.effigenix.infrastructure.production.web;
import de.effigenix.domain.usermanagement.RoleName;
import de.effigenix.infrastructure.AbstractIntegrationTest;
import de.effigenix.infrastructure.usermanagement.persistence.entity.RoleEntity;
import de.effigenix.infrastructure.usermanagement.persistence.entity.UserEntity;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Nested;
@ -23,9 +21,9 @@ class RecipeLifecycleIntegrationTest extends AbstractIntegrationTest {
@BeforeEach
void setUp() {
RoleEntity adminRole = createRole(RoleName.ADMIN, "Admin");
UserEntity admin = createUser("recipe.admin", "recipe.admin@test.com", Set.of(adminRole), "BRANCH-01");
adminToken = generateToken(admin.getId(), "recipe.admin", "RECIPE_WRITE,RECIPE_READ");
String adminRoleId = createRole(RoleName.ADMIN, "Admin");
String adminId = createUser("recipe.admin", "recipe.admin@test.com", Set.of(adminRoleId), "BRANCH-01");
adminToken = generateToken(adminId, "recipe.admin", "RECIPE_WRITE,RECIPE_READ");
}
// ==================== Aktivierung ====================

View file

@ -4,8 +4,6 @@ import de.effigenix.domain.usermanagement.RoleName;
import de.effigenix.infrastructure.AbstractIntegrationTest;
import de.effigenix.infrastructure.production.web.dto.PlanBatchRequest;
import de.effigenix.infrastructure.production.web.dto.RecordConsumptionRequest;
import de.effigenix.infrastructure.usermanagement.persistence.entity.RoleEntity;
import de.effigenix.infrastructure.usermanagement.persistence.entity.UserEntity;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Nested;
@ -31,14 +29,14 @@ class RecordConsumptionIntegrationTest extends AbstractIntegrationTest {
@BeforeEach
void setUp() throws Exception {
RoleEntity adminRole = createRole(RoleName.ADMIN, "Admin");
RoleEntity viewerRole = createRole(RoleName.PRODUCTION_WORKER, "Viewer");
String adminRoleId = createRole(RoleName.ADMIN, "Admin");
String viewerRoleId = createRole(RoleName.PRODUCTION_WORKER, "Viewer");
UserEntity admin = createUser("cons.admin", "cons.admin@test.com", Set.of(adminRole), "BRANCH-01");
UserEntity viewer = createUser("cons.viewer", "cons.viewer@test.com", Set.of(viewerRole), "BRANCH-01");
String adminId = createUser("cons.admin", "cons.admin@test.com", Set.of(adminRoleId), "BRANCH-01");
String viewerId = createUser("cons.viewer", "cons.viewer@test.com", Set.of(viewerRoleId), "BRANCH-01");
adminToken = generateToken(admin.getId(), "cons.admin", "BATCH_WRITE,BATCH_READ,RECIPE_WRITE,RECIPE_READ");
viewerToken = generateToken(viewer.getId(), "cons.viewer", "USER_READ");
adminToken = generateToken(adminId, "cons.admin", "BATCH_WRITE,BATCH_READ,RECIPE_WRITE,RECIPE_READ");
viewerToken = generateToken(viewerId, "cons.viewer", "USER_READ");
}
@Nested

View file

@ -3,8 +3,6 @@ package de.effigenix.infrastructure.production.web;
import de.effigenix.domain.usermanagement.RoleName;
import de.effigenix.infrastructure.AbstractIntegrationTest;
import de.effigenix.infrastructure.production.web.dto.PlanBatchRequest;
import de.effigenix.infrastructure.usermanagement.persistence.entity.RoleEntity;
import de.effigenix.infrastructure.usermanagement.persistence.entity.UserEntity;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Nested;
@ -29,14 +27,14 @@ class StartBatchIntegrationTest extends AbstractIntegrationTest {
@BeforeEach
void setUp() throws Exception {
RoleEntity adminRole = createRole(RoleName.ADMIN, "Admin");
RoleEntity viewerRole = createRole(RoleName.PRODUCTION_WORKER, "Viewer");
String adminRoleId = createRole(RoleName.ADMIN, "Admin");
String viewerRoleId = createRole(RoleName.PRODUCTION_WORKER, "Viewer");
UserEntity admin = createUser("start.admin", "start.admin@test.com", Set.of(adminRole), "BRANCH-01");
UserEntity viewer = createUser("start.viewer", "start.viewer@test.com", Set.of(viewerRole), "BRANCH-01");
String adminId = createUser("start.admin", "start.admin@test.com", Set.of(adminRoleId), "BRANCH-01");
String viewerId = createUser("start.viewer", "start.viewer@test.com", Set.of(viewerRoleId), "BRANCH-01");
adminToken = generateToken(admin.getId(), "start.admin", "BATCH_WRITE,BATCH_READ,RECIPE_WRITE,RECIPE_READ");
viewerToken = generateToken(viewer.getId(), "start.viewer", "USER_READ");
adminToken = generateToken(adminId, "start.admin", "BATCH_WRITE,BATCH_READ,RECIPE_WRITE,RECIPE_READ");
viewerToken = generateToken(viewerId, "start.viewer", "USER_READ");
}
@Nested

View file

@ -1,350 +0,0 @@
package de.effigenix.infrastructure.usermanagement.persistence.mapper;
import de.effigenix.domain.usermanagement.*;
import de.effigenix.infrastructure.usermanagement.persistence.entity.RoleEntity;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import java.util.HashSet;
import java.util.Set;
import static org.assertj.core.api.Assertions.*;
/**
* Unit tests for RoleMapper.
* Tests bidirectional mapping between Role domain entity and RoleEntity JPA entity.
*/
@DisplayName("RoleMapper")
class RoleMapperTest {
private final RoleMapper roleMapper = new RoleMapper();
private Role domainRole;
private RoleEntity jpaEntity;
private Set<Permission> permissions;
@BeforeEach
void setUp() {
permissions = new HashSet<>(Set.of(
Permission.USER_READ,
Permission.USER_WRITE,
Permission.ROLE_READ
));
// Create JPA entity first
jpaEntity = new RoleEntity(
"role-123",
RoleName.ADMIN,
new HashSet<>(permissions),
"Administrator role with full access"
);
// Create domain role via mapper (which internally uses reconstitute)
domainRole = roleMapper.toDomain(jpaEntity);
}
@Test
@DisplayName("should_MapRoleToEntity_When_DomainRoleProvided")
void should_MapRoleToEntity_When_DomainRoleProvided() {
// Act
RoleEntity entity = roleMapper.toEntity(domainRole);
// Assert
assertThat(entity).isNotNull();
assertThat(entity.getId()).isEqualTo("role-123");
assertThat(entity.getName()).isEqualTo(RoleName.ADMIN);
assertThat(entity.getDescription()).isEqualTo("Administrator role with full access");
assertThat(entity.getPermissions()).containsAll(permissions);
}
@Test
@DisplayName("should_MapRoleToDomain_When_JpaEntityProvided")
void should_MapRoleToDomain_When_JpaEntityProvided() {
// Act
Role role = roleMapper.toDomain(jpaEntity);
// Assert
assertThat(role).isNotNull();
assertThat(role.id().value()).isEqualTo("role-123");
assertThat(role.name()).isEqualTo(RoleName.ADMIN);
assertThat(role.description()).isEqualTo("Administrator role with full access");
assertThat(role.permissions()).containsAll(permissions);
}
@Test
@DisplayName("should_ReturnNull_When_NullRoleProvidedToToEntity")
void should_ReturnNull_When_NullRoleProvidedToToEntity() {
// Act
RoleEntity entity = roleMapper.toEntity(null);
// Assert
assertThat(entity).isNull();
}
@Test
@DisplayName("should_ReturnNull_When_NullEntityProvidedToToDomain")
void should_ReturnNull_When_NullEntityProvidedToToDomain() {
// Act
Role role = roleMapper.toDomain(null);
// Assert
assertThat(role).isNull();
}
@Test
@DisplayName("should_PreserveAllRoleFields_When_MappingToEntity")
void should_PreserveAllRoleFields_When_MappingToEntity() {
// Arrange
Set<Permission> perms = new HashSet<>(Set.of(
Permission.BATCH_READ,
Permission.BATCH_WRITE,
Permission.BATCH_COMPLETE
));
Role role = roleMapper.toDomain(new RoleEntity(
"role-prod-manager",
RoleName.PRODUCTION_MANAGER,
new HashSet<>(perms),
"Production Manager role"
));
// Act
RoleEntity entity = roleMapper.toEntity(role);
// Assert
assertThat(entity.getId()).isEqualTo("role-prod-manager");
assertThat(entity.getName()).isEqualTo(RoleName.PRODUCTION_MANAGER);
assertThat(entity.getDescription()).isEqualTo("Production Manager role");
assertThat(entity.getPermissions()).containsAll(perms);
}
@Test
@DisplayName("should_PreserveAllEntityFields_When_MappingToDomain")
void should_PreserveAllEntityFields_When_MappingToDomain() {
// Arrange
Set<Permission> perms = new HashSet<>(Set.of(
Permission.STOCK_READ,
Permission.STOCK_WRITE
));
RoleEntity entity = new RoleEntity(
"role-warehouse",
RoleName.WAREHOUSE_WORKER,
perms,
"Warehouse Worker role"
);
// Act
Role role = roleMapper.toDomain(entity);
// Assert
assertThat(role.id().value()).isEqualTo("role-warehouse");
assertThat(role.name()).isEqualTo(RoleName.WAREHOUSE_WORKER);
assertThat(role.description()).isEqualTo("Warehouse Worker role");
assertThat(role.permissions()).containsAll(perms);
}
@Test
@DisplayName("should_HandleEmptyPermissions_When_RoleHasNoPermissions")
void should_HandleEmptyPermissions_When_RoleHasNoPermissions() {
// Arrange
Role roleNoPerms = roleMapper.toDomain(new RoleEntity(
"role-empty",
RoleName.ADMIN,
new HashSet<>(),
"Empty role"
));
// Act
RoleEntity entity = roleMapper.toEntity(roleNoPerms);
// Assert
assertThat(entity.getPermissions()).isEmpty();
}
@Test
@DisplayName("should_HandleNullPermissions_When_MappingToEntity")
void should_HandleNullPermissions_When_MappingToEntity() {
// Arrange
Role roleNullPerms = roleMapper.toDomain(new RoleEntity(
"role-null",
RoleName.ADMIN,
null,
"Role with null permissions"
));
// Act
RoleEntity entity = roleMapper.toEntity(roleNullPerms);
// Assert
assertThat(entity.getPermissions()).isEmpty();
}
@Test
@DisplayName("should_HandleNullPermissions_When_MappingToDomain")
void should_HandleNullPermissions_When_MappingToDomain() {
// Arrange
RoleEntity entityNullPerms = new RoleEntity(
"role-null",
RoleName.ADMIN,
null,
"Entity with null permissions"
);
// Act
Role role = roleMapper.toDomain(entityNullPerms);
// Assert
assertThat(role.permissions()).isEmpty();
}
@Test
@DisplayName("should_BidirectionalMapping_When_MappingRoleBackAndForth")
void should_BidirectionalMapping_When_MappingRoleBackAndForth() {
// Act
RoleEntity entity = roleMapper.toEntity(domainRole);
Role mappedBackRole = roleMapper.toDomain(entity);
// Assert
assertThat(mappedBackRole.id().value()).isEqualTo(domainRole.id().value());
assertThat(mappedBackRole.name()).isEqualTo(domainRole.name());
assertThat(mappedBackRole.description()).isEqualTo(domainRole.description());
assertThat(mappedBackRole.permissions()).containsAll(domainRole.permissions());
}
@Test
@DisplayName("should_CreateNewSetForPermissions_When_MappingToEntity")
void should_CreateNewSetForPermissions_When_MappingToEntity() {
// Act
RoleEntity entity = roleMapper.toEntity(domainRole);
// Assert
assertThat(entity.getPermissions()).isNotNull();
assertThat(entity.getPermissions()).isInstanceOf(Set.class);
}
@Test
@DisplayName("should_CreateNewSetForPermissions_When_MappingToDomain")
void should_CreateNewSetForPermissions_When_MappingToDomain() {
// Act
Role role = roleMapper.toDomain(jpaEntity);
// Assert
assertThat(role.permissions()).isNotNull();
assertThat(role.permissions()).isInstanceOf(Set.class);
}
@Test
@DisplayName("should_MapAllRoleNames_When_DifferentRoleNamesUsed")
void should_MapAllRoleNames_When_DifferentRoleNamesUsed() {
// Act
Role adminRole = roleMapper.toDomain(
new RoleEntity("id-1", RoleName.ADMIN, new HashSet<>(), "Admin")
);
Role prodWorkerRole = roleMapper.toDomain(
new RoleEntity("id-2", RoleName.PRODUCTION_WORKER, new HashSet<>(), "Worker")
);
Role warehouseRole = roleMapper.toDomain(
new RoleEntity("id-3", RoleName.WAREHOUSE_WORKER, new HashSet<>(), "Warehouse")
);
// Assert
assertThat(adminRole.name()).isEqualTo(RoleName.ADMIN);
assertThat(prodWorkerRole.name()).isEqualTo(RoleName.PRODUCTION_WORKER);
assertThat(warehouseRole.name()).isEqualTo(RoleName.WAREHOUSE_WORKER);
}
@Test
@DisplayName("should_MapAllPermissionTypes_When_DifferentPermissionsUsed")
void should_MapAllPermissionTypes_When_DifferentPermissionsUsed() {
// Arrange
Set<Permission> allPermissions = new HashSet<>(Set.of(
Permission.USER_READ,
Permission.BATCH_WRITE,
Permission.STOCK_READ,
Permission.ORDER_DELETE,
Permission.REPORT_GENERATE
));
Role roleWithVariousPerms = roleMapper.toDomain(new RoleEntity(
"role-various",
RoleName.ADMIN,
new HashSet<>(allPermissions),
"Role with various permissions"
));
// Act
RoleEntity entity = roleMapper.toEntity(roleWithVariousPerms);
// Assert
assertThat(entity.getPermissions()).containsAll(allPermissions);
assertThat(entity.getPermissions()).hasSize(5);
}
@Test
@DisplayName("should_HandleNullDescription_When_MappingToEntity")
void should_HandleNullDescription_When_MappingToEntity() {
// Arrange
Role roleNullDesc = roleMapper.toDomain(new RoleEntity(
"role-no-desc",
RoleName.ADMIN,
new HashSet<>(permissions),
null
));
// Act
RoleEntity entity = roleMapper.toEntity(roleNullDesc);
// Assert
assertThat(entity.getDescription()).isNull();
}
@Test
@DisplayName("should_HandleNullDescription_When_MappingToDomain")
void should_HandleNullDescription_When_MappingToDomain() {
// Arrange
RoleEntity entityNullDesc = new RoleEntity(
"role-no-desc",
RoleName.ADMIN,
permissions,
null
);
// Act
Role role = roleMapper.toDomain(entityNullDesc);
// Assert
assertThat(role.description()).isNull();
}
@Test
@DisplayName("should_MapLargePermissionSet_When_RoleHasManyPermissions")
void should_MapLargePermissionSet_When_RoleHasManyPermissions() {
// Arrange
Set<Permission> largePermSet = new HashSet<>(Set.of(
Permission.values() // All permissions
));
Role roleWithManyPerms = roleMapper.toDomain(new RoleEntity(
"role-admin-full",
RoleName.ADMIN,
new HashSet<>(largePermSet),
"Super admin with all permissions"
));
// Act
RoleEntity entity = roleMapper.toEntity(roleWithManyPerms);
Role mappedBack = roleMapper.toDomain(entity);
// Assert
assertThat(entity.getPermissions()).hasSize(largePermSet.size());
assertThat(mappedBack.permissions()).hasSize(largePermSet.size());
}
@Test
@DisplayName("should_PreservePermissionImmutability_When_MappingToEntity")
void should_PreservePermissionImmutability_When_MappingToEntity() {
// Act
RoleEntity entity = roleMapper.toEntity(domainRole);
// Assert - mapped entity should have same permissions
assertThat(entity.getPermissions()).containsAll(domainRole.permissions());
}
}

View file

@ -1,294 +0,0 @@
package de.effigenix.infrastructure.usermanagement.persistence.mapper;
import de.effigenix.domain.usermanagement.*;
import de.effigenix.infrastructure.usermanagement.persistence.entity.RoleEntity;
import de.effigenix.infrastructure.usermanagement.persistence.entity.UserEntity;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import java.time.OffsetDateTime;
import java.time.ZoneOffset;
import java.util.HashSet;
import java.util.Set;
import static org.assertj.core.api.Assertions.*;
/**
* Unit tests for UserMapper.
* Tests bidirectional mapping between User domain entity and UserEntity JPA entity.
*
* Uses real RoleMapper (no mocks) because both mappers are simple stateless components.
* Domain User/Role objects are created via the mapper's toDomain() method which internally
* calls the package-private reconstitute() factory method.
*/
@DisplayName("UserMapper")
class UserMapperTest {
private final RoleMapper roleMapper = new RoleMapper();
private final UserMapper userMapper = new UserMapper(roleMapper);
private User domainUser;
private UserEntity jpaEntity;
private OffsetDateTime createdAt;
@BeforeEach
void setUp() {
createdAt = OffsetDateTime.now(ZoneOffset.UTC);
// Create JPA entity first
jpaEntity = new UserEntity(
"user-123",
"john.doe",
"john@example.com",
"$2a$12$R9h/cIPz0gi.URNN3kh2OPST9EBwVeL00lzQRYe3z08MZx3e8YCWW",
new HashSet<>(),
"branch-1",
UserStatus.ACTIVE,
createdAt,
null
);
// Create domain user via mapper (which internally uses reconstitute)
domainUser = userMapper.toDomain(jpaEntity);
}
@Test
@DisplayName("should_MapUserToEntity_When_DomainUserProvided")
void should_MapUserToEntity_When_DomainUserProvided() {
// Act
UserEntity entity = userMapper.toEntity(domainUser);
// Assert
assertThat(entity).isNotNull();
assertThat(entity.getId()).isEqualTo("user-123");
assertThat(entity.getUsername()).isEqualTo("john.doe");
assertThat(entity.getEmail()).isEqualTo("john@example.com");
assertThat(entity.getPasswordHash()).isEqualTo("$2a$12$R9h/cIPz0gi.URNN3kh2OPST9EBwVeL00lzQRYe3z08MZx3e8YCWW");
assertThat(entity.getBranchId()).isEqualTo("branch-1");
assertThat(entity.getStatus()).isEqualTo(UserStatus.ACTIVE);
assertThat(entity.getCreatedAt()).isEqualTo(createdAt);
assertThat(entity.getLastLogin()).isNull();
}
@Test
@DisplayName("should_MapUserToDomain_When_JpaEntityProvided")
void should_MapUserToDomain_When_JpaEntityProvided() {
// Act
User user = userMapper.toDomain(jpaEntity);
// Assert
assertThat(user).isNotNull();
assertThat(user.id().value()).isEqualTo("user-123");
assertThat(user.username()).isEqualTo("john.doe");
assertThat(user.email()).isEqualTo("john@example.com");
assertThat(user.passwordHash().value()).isEqualTo("$2a$12$R9h/cIPz0gi.URNN3kh2OPST9EBwVeL00lzQRYe3z08MZx3e8YCWW");
assertThat(user.branchId()).isEqualTo("branch-1");
assertThat(user.status()).isEqualTo(UserStatus.ACTIVE);
assertThat(user.createdAt()).isEqualTo(createdAt);
assertThat(user.lastLogin()).isNull();
}
@Test
@DisplayName("should_ReturnNull_When_NullUserProvidedToToEntity")
void should_ReturnNull_When_NullUserProvidedToToEntity() {
// Act
UserEntity entity = userMapper.toEntity(null);
// Assert
assertThat(entity).isNull();
}
@Test
@DisplayName("should_ReturnNull_When_NullEntityProvidedToToDomain")
void should_ReturnNull_When_NullEntityProvidedToToDomain() {
// Act
User user = userMapper.toDomain(null);
// Assert
assertThat(user).isNull();
}
@Test
@DisplayName("should_PreserveAllUserFields_When_MappingToEntity")
void should_PreserveAllUserFields_When_MappingToEntity() {
// Arrange
OffsetDateTime lastLogin = OffsetDateTime.now(ZoneOffset.UTC);
UserEntity sourceEntity = new UserEntity(
"user-456",
"jane.smith",
"jane@example.com",
"$2b$12$R9h/cIPz0gi.URNN3kh2OPST9EBwVeL00lzQRYe3z08MZx3e8YCWW",
new HashSet<>(),
"branch-2",
UserStatus.LOCKED,
createdAt,
lastLogin
);
User userWithLastLogin = userMapper.toDomain(sourceEntity);
// Act
UserEntity entity = userMapper.toEntity(userWithLastLogin);
// Assert
assertThat(entity.getId()).isEqualTo("user-456");
assertThat(entity.getUsername()).isEqualTo("jane.smith");
assertThat(entity.getEmail()).isEqualTo("jane@example.com");
assertThat(entity.getPasswordHash()).isEqualTo("$2b$12$R9h/cIPz0gi.URNN3kh2OPST9EBwVeL00lzQRYe3z08MZx3e8YCWW");
assertThat(entity.getBranchId()).isEqualTo("branch-2");
assertThat(entity.getStatus()).isEqualTo(UserStatus.LOCKED);
assertThat(entity.getCreatedAt()).isEqualTo(createdAt);
assertThat(entity.getLastLogin()).isEqualTo(lastLogin);
}
@Test
@DisplayName("should_PreserveAllEntityFields_When_MappingToDomain")
void should_PreserveAllEntityFields_When_MappingToDomain() {
// Arrange
OffsetDateTime lastLogin = OffsetDateTime.now(ZoneOffset.UTC);
UserEntity entityWithLastLogin = new UserEntity(
"user-789",
"bob.jones",
"bob@example.com",
"$2y$12$R9h/cIPz0gi.URNN3kh2OPST9EBwVeL00lzQRYe3z08MZx3e8YCWW",
new HashSet<>(),
"branch-3",
UserStatus.INACTIVE,
createdAt,
lastLogin
);
// Act
User user = userMapper.toDomain(entityWithLastLogin);
// Assert
assertThat(user.id().value()).isEqualTo("user-789");
assertThat(user.username()).isEqualTo("bob.jones");
assertThat(user.email()).isEqualTo("bob@example.com");
assertThat(user.passwordHash().value()).isEqualTo("$2y$12$R9h/cIPz0gi.URNN3kh2OPST9EBwVeL00lzQRYe3z08MZx3e8YCWW");
assertThat(user.branchId()).isEqualTo("branch-3");
assertThat(user.status()).isEqualTo(UserStatus.INACTIVE);
assertThat(user.createdAt()).isEqualTo(createdAt);
assertThat(user.lastLogin()).isEqualTo(lastLogin);
}
@Test
@DisplayName("should_MapRoleEntitiesCorrectly_When_UserHasRoles")
void should_MapRoleEntitiesCorrectly_When_UserHasRoles() {
// Arrange
RoleEntity roleEntity1 = new RoleEntity("role-1", RoleName.ADMIN, new HashSet<>(), "Admin");
RoleEntity roleEntity2 = new RoleEntity("role-2", RoleName.PRODUCTION_WORKER, new HashSet<>(), "Worker");
UserEntity userEntityWithRoles = new UserEntity(
"user-999",
"john.doe",
"john@example.com",
"$2a$12$R9h/cIPz0gi.URNN3kh2OPST9EBwVeL00lzQRYe3z08MZx3e8YCWW",
new HashSet<>(Set.of(roleEntity1, roleEntity2)),
"branch-1",
UserStatus.ACTIVE,
createdAt,
null
);
// Map entity to domain (toDomain maps roles via real roleMapper)
User userWithRoles = userMapper.toDomain(userEntityWithRoles);
// Act
UserEntity entity = userMapper.toEntity(userWithRoles);
// Assert
assertThat(entity.getRoles()).hasSize(2);
}
@Test
@DisplayName("should_HandleEmptyRoleSet_When_UserHasNoRoles")
void should_HandleEmptyRoleSet_When_UserHasNoRoles() {
// Act
UserEntity entity = userMapper.toEntity(domainUser);
// Assert
assertThat(entity.getRoles()).isEmpty();
}
@Test
@DisplayName("should_HandleNullRolesInEntity_When_MappingToDomain")
void should_HandleNullRolesInEntity_When_MappingToDomain() {
// Arrange
jpaEntity.setRoles(null);
// Act
User user = userMapper.toDomain(jpaEntity);
// Assert
assertThat(user.roles()).isEmpty();
}
@Test
@DisplayName("should_BidirectionalMapping_When_MappingUserBackAndForth")
void should_BidirectionalMapping_When_MappingUserBackAndForth() {
// Act
UserEntity entity = userMapper.toEntity(domainUser);
User mappedBackUser = userMapper.toDomain(entity);
// Assert
assertThat(mappedBackUser.id().value()).isEqualTo(domainUser.id().value());
assertThat(mappedBackUser.username()).isEqualTo(domainUser.username());
assertThat(mappedBackUser.email()).isEqualTo(domainUser.email());
assertThat(mappedBackUser.passwordHash().value()).isEqualTo(domainUser.passwordHash().value());
assertThat(mappedBackUser.branchId()).isEqualTo(domainUser.branchId());
assertThat(mappedBackUser.status()).isEqualTo(domainUser.status());
}
@Test
@DisplayName("should_CreateNewSetForRoles_When_MappingToEntity")
void should_CreateNewSetForRoles_When_MappingToEntity() {
// Act
UserEntity entity = userMapper.toEntity(domainUser);
// Assert
assertThat(entity.getRoles()).isNotNull();
assertThat(entity.getRoles()).isInstanceOf(Set.class);
}
@Test
@DisplayName("should_CreateNewSetForRoles_When_MappingToDomain")
void should_CreateNewSetForRoles_When_MappingToDomain() {
// Act
User user = userMapper.toDomain(jpaEntity);
// Assert
assertThat(user.roles()).isNotNull();
assertThat(user.roles()).isInstanceOf(Set.class);
}
@Test
@DisplayName("should_MapAllUserStatuses_When_DifferentStatusesUsed")
void should_MapAllUserStatuses_When_DifferentStatusesUsed() {
// Arrange - create users with different statuses via entity -> domain mapping
User activeUser = userMapper.toDomain(new UserEntity(
"id-1", "user1", "u1@test.com",
"$2a$12$R9h/cIPz0gi.URNN3kh2OPST9EBwVeL00lzQRYe3z08MZx3e8YCWW",
new HashSet<>(), "b1", UserStatus.ACTIVE, createdAt, null));
User inactiveUser = userMapper.toDomain(new UserEntity(
"id-2", "user2", "u2@test.com",
"$2a$12$R9h/cIPz0gi.URNN3kh2OPST9EBwVeL00lzQRYe3z08MZx3e8YCWW",
new HashSet<>(), "b1", UserStatus.INACTIVE, createdAt, null));
User lockedUser = userMapper.toDomain(new UserEntity(
"id-3", "user3", "u3@test.com",
"$2a$12$R9h/cIPz0gi.URNN3kh2OPST9EBwVeL00lzQRYe3z08MZx3e8YCWW",
new HashSet<>(), "b1", UserStatus.LOCKED, createdAt, null));
// Act
UserEntity activeEntity = userMapper.toEntity(activeUser);
UserEntity inactiveEntity = userMapper.toEntity(inactiveUser);
UserEntity lockedEntity = userMapper.toEntity(lockedUser);
// Assert
assertThat(activeEntity.getStatus()).isEqualTo(UserStatus.ACTIVE);
assertThat(inactiveEntity.getStatus()).isEqualTo(UserStatus.INACTIVE);
assertThat(lockedEntity.getStatus()).isEqualTo(UserStatus.LOCKED);
}
}

View file

@ -1,10 +1,7 @@
package de.effigenix.infrastructure.usermanagement.web;
import de.effigenix.domain.usermanagement.RoleName;
import de.effigenix.domain.usermanagement.UserStatus;
import de.effigenix.infrastructure.AbstractIntegrationTest;
import de.effigenix.infrastructure.usermanagement.persistence.entity.RoleEntity;
import de.effigenix.infrastructure.usermanagement.persistence.entity.UserEntity;
import de.effigenix.infrastructure.usermanagement.web.dto.LoginRequest;
import de.effigenix.infrastructure.usermanagement.web.dto.LoginResponse;
import de.effigenix.infrastructure.usermanagement.web.dto.RefreshTokenRequest;
@ -35,11 +32,10 @@ class AuthControllerIntegrationTest extends AbstractIntegrationTest {
void setUp() {
validUsername = "auth.test.user";
RoleEntity adminRole = createRole(RoleName.ADMIN, "Admin role");
String adminRoleId = createRole(RoleName.ADMIN, "Admin role");
UserEntity testUser = createUser(validUsername, "auth.test@example.com",
Set.of(adminRole), "BRANCH-TEST-001");
validUserId = testUser.getId();
validUserId = createUser(validUsername, "auth.test@example.com",
Set.of(adminRoleId), "BRANCH-TEST-001");
validRefreshToken = generateRefreshToken(validUserId, validUsername);
}
@ -99,9 +95,8 @@ class AuthControllerIntegrationTest extends AbstractIntegrationTest {
@Test
@DisplayName("Login with locked user should return 401 Unauthorized")
void testLoginWithLockedUser() throws Exception {
UserEntity user = userRepository.findByUsername(validUsername).orElseThrow();
user.setStatus(UserStatus.LOCKED);
userRepository.save(user);
jdbc.sql("UPDATE users SET status = 'LOCKED' WHERE id = ?")
.param(validUserId).update();
LoginRequest request = new LoginRequest(validUsername, TEST_PASSWORD);
@ -115,9 +110,8 @@ class AuthControllerIntegrationTest extends AbstractIntegrationTest {
@Test
@DisplayName("Login with inactive user should return 401 Unauthorized")
void testLoginWithInactiveUser() throws Exception {
UserEntity user = userRepository.findByUsername(validUsername).orElseThrow();
user.setStatus(UserStatus.INACTIVE);
userRepository.save(user);
jdbc.sql("UPDATE users SET status = 'INACTIVE' WHERE id = ?")
.param(validUserId).update();
LoginRequest request = new LoginRequest(validUsername, TEST_PASSWORD);

View file

@ -2,8 +2,6 @@ package de.effigenix.infrastructure.usermanagement.web;
import de.effigenix.domain.usermanagement.RoleName;
import de.effigenix.infrastructure.AbstractIntegrationTest;
import de.effigenix.infrastructure.usermanagement.persistence.entity.RoleEntity;
import de.effigenix.infrastructure.usermanagement.persistence.entity.UserEntity;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
@ -23,14 +21,14 @@ class RoleControllerIntegrationTest extends AbstractIntegrationTest {
@BeforeEach
void setUp() {
RoleEntity adminRole = createRole(RoleName.ADMIN, "Admin");
RoleEntity viewerRole = createRole(RoleName.PRODUCTION_WORKER, "Viewer");
String adminRoleId = createRole(RoleName.ADMIN, "Admin");
String viewerRoleId = createRole(RoleName.PRODUCTION_WORKER, "Viewer");
UserEntity admin = createUser("role.admin", "role.admin@test.com", Set.of(adminRole), "BRANCH-01");
UserEntity viewer = createUser("role.viewer", "role.viewer@test.com", Set.of(viewerRole), "BRANCH-01");
String adminId = createUser("role.admin", "role.admin@test.com", Set.of(adminRoleId), "BRANCH-01");
String viewerId = createUser("role.viewer", "role.viewer@test.com", Set.of(viewerRoleId), "BRANCH-01");
adminToken = generateToken(admin.getId(), "role.admin", "ROLE_READ");
viewerToken = generateToken(viewer.getId(), "role.viewer", "USER_READ");
adminToken = generateToken(adminId, "role.admin", "ROLE_READ");
viewerToken = generateToken(viewerId, "role.viewer", "USER_READ");
}
@Test

View file

@ -1,12 +1,9 @@
package de.effigenix.infrastructure.usermanagement.web;
import de.effigenix.domain.usermanagement.RoleName;
import de.effigenix.domain.usermanagement.UserStatus;
import de.effigenix.infrastructure.AbstractIntegrationTest;
import de.effigenix.infrastructure.audit.AuditLogEntity;
import de.effigenix.infrastructure.audit.AuditLogJpaRepository;
import de.effigenix.infrastructure.usermanagement.persistence.entity.RoleEntity;
import de.effigenix.infrastructure.usermanagement.persistence.entity.UserEntity;
import de.effigenix.infrastructure.usermanagement.web.dto.CreateUserRequest;
import de.effigenix.infrastructure.usermanagement.web.dto.LoginRequest;
import de.effigenix.infrastructure.usermanagement.web.dto.UpdateUserRequest;
@ -45,21 +42,19 @@ class SecurityIntegrationTest extends AbstractIntegrationTest {
private String adminUserId;
private String regularUserId;
private RoleEntity adminRole;
private RoleEntity userRole;
private String adminRoleId;
private String userRoleId;
@BeforeEach
void setUp() {
adminRole = createRole(RoleName.ADMIN, "Admin role");
userRole = createRole(RoleName.PRODUCTION_WORKER, "Production worker role");
adminRoleId = createRole(RoleName.ADMIN, "Admin role");
userRoleId = createRole(RoleName.PRODUCTION_WORKER, "Production worker role");
UserEntity adminUser = createUser("security.admin", "admin@security.test",
Set.of(adminRole), "BRANCH-ADMIN");
adminUserId = adminUser.getId();
adminUserId = createUser("security.admin", "admin@security.test",
Set.of(adminRoleId), "BRANCH-ADMIN");
UserEntity regularUser = createUser("security.user", "user@security.test",
Set.of(userRole), "BRANCH-USER");
regularUserId = regularUser.getId();
regularUserId = createUser("security.user", "user@security.test",
Set.of(userRoleId), "BRANCH-USER");
adminToken = generateTestJWT(adminUserId, "security.admin", true);
regularUserToken = generateTestJWT(regularUserId, "security.user", false);
@ -222,8 +217,8 @@ class SecurityIntegrationTest extends AbstractIntegrationTest {
@Test
@DisplayName("Users should see data filtered by their branch (if filtering is implemented)")
void testBranchBasedDataVisibility() throws Exception {
UserEntity otherBranchUser = createUser("other.branch.user", "other@branch.test",
Set.of(userRole), "BRANCH-OTHER");
String otherBranchUserId = createUser("other.branch.user", "other@branch.test",
Set.of(userRoleId), "BRANCH-OTHER");
mockMvc.perform(get("/api/users")
.header("Authorization", "Bearer " + regularUserToken))
@ -360,9 +355,12 @@ class SecurityIntegrationTest extends AbstractIntegrationTest {
void testUnlockUserAuditLogging() throws Exception {
auditLogRepository.deleteAll();
UserEntity user = userRepository.findById(regularUserId).orElseThrow();
user.setStatus(UserStatus.LOCKED);
userRepository.save(user);
// Lock the user first via API
mockMvc.perform(post("/api/users/{id}/lock", regularUserId)
.header("Authorization", "Bearer " + adminToken))
.andExpect(status().isOk());
auditLogRepository.deleteAll();
mockMvc.perform(post("/api/users/{id}/unlock", regularUserId)
.header("Authorization", "Bearer " + adminToken))

View file

@ -1,10 +1,7 @@
package de.effigenix.infrastructure.usermanagement.web;
import de.effigenix.domain.usermanagement.RoleName;
import de.effigenix.domain.usermanagement.UserStatus;
import de.effigenix.infrastructure.AbstractIntegrationTest;
import de.effigenix.infrastructure.usermanagement.persistence.entity.RoleEntity;
import de.effigenix.infrastructure.usermanagement.persistence.entity.UserEntity;
import de.effigenix.infrastructure.usermanagement.web.dto.*;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
@ -35,19 +32,17 @@ class UserControllerIntegrationTest extends AbstractIntegrationTest {
private String adminUserId;
private String regularUserId;
private RoleEntity adminRole;
private RoleEntity userRole;
private String adminRoleId;
private String userRoleId;
@BeforeEach
void setUp() {
adminRole = createRole(RoleName.ADMIN, "Admin role");
userRole = createRole(RoleName.PRODUCTION_WORKER, "Production worker role");
adminRoleId = createRole(RoleName.ADMIN, "Admin role");
userRoleId = createRole(RoleName.PRODUCTION_WORKER, "Production worker role");
UserEntity adminUser = createUser("admin.user", "admin@example.com", Set.of(adminRole), "BRANCH-001");
adminUserId = adminUser.getId();
adminUserId = createUser("admin.user", "admin@example.com", Set.of(adminRoleId), "BRANCH-001");
UserEntity regularUser = createUser("regular.user", "regular@example.com", Set.of(userRole), "BRANCH-001");
regularUserId = regularUser.getId();
regularUserId = createUser("regular.user", "regular@example.com", Set.of(userRoleId), "BRANCH-001");
adminToken = generateTestJWT(adminUserId, "admin.user", true);
regularUserToken = generateTestJWT(regularUserId, "regular.user", false);
@ -353,8 +348,9 @@ class UserControllerIntegrationTest extends AbstractIntegrationTest {
.andReturn();
// Verify user is actually locked in database
UserEntity lockedUser = userRepository.findById(regularUserId).orElseThrow();
assertThat(lockedUser.getStatus()).isEqualTo(UserStatus.LOCKED);
String lockedStatus = jdbc.sql("SELECT status FROM users WHERE id = ?")
.param(regularUserId).query(String.class).single();
assertThat(lockedStatus).isEqualTo("LOCKED");
}
@Test
@ -383,9 +379,8 @@ class UserControllerIntegrationTest extends AbstractIntegrationTest {
@DisplayName("Unlock locked user should return 200 with ACTIVE status")
void testUnlockUser() throws Exception {
// First lock the user
UserEntity user = userRepository.findById(regularUserId).orElseThrow();
user.setStatus(UserStatus.LOCKED);
userRepository.save(user);
jdbc.sql("UPDATE users SET status = 'LOCKED' WHERE id = ?")
.param(regularUserId).update();
// Now unlock
mockMvc.perform(post("/api/users/{id}/unlock", regularUserId)
@ -395,8 +390,9 @@ class UserControllerIntegrationTest extends AbstractIntegrationTest {
.andReturn();
// Verify user is actually unlocked in database
UserEntity unlockedUser = userRepository.findById(regularUserId).orElseThrow();
assertThat(unlockedUser.getStatus()).isEqualTo(UserStatus.ACTIVE);
String unlockedStatus = jdbc.sql("SELECT status FROM users WHERE id = ?")
.param(regularUserId).query(String.class).single();
assertThat(unlockedStatus).isEqualTo("ACTIVE");
}
@Test
@ -437,8 +433,9 @@ class UserControllerIntegrationTest extends AbstractIntegrationTest {
.andReturn();
// Verify password was actually changed
UserEntity updatedUser = userRepository.findById(regularUserId).orElseThrow();
assertThat(passwordEncoder.matches("NewSecurePass456!", updatedUser.getPasswordHash())).isTrue();
String passwordHash = jdbc.sql("SELECT password_hash FROM users WHERE id = ?")
.param(regularUserId).query(String.class).single();
assertThat(passwordEncoder.matches("NewSecurePass456!", passwordHash)).isTrue();
}
@Test