mirror of
https://github.com/s-frick/effigenix.git
synced 2026-03-28 11:59:35 +01:00
refactor(production): UnitOfWork-Pattern + JdbcClient-Migration für Production-BC
Production-BC von JPA auf JdbcClient migriert und UnitOfWork-Port eingeführt, der Transaktionen explizit steuert und bei Result.failure zurückrollt — löst das Problem, dass @Transactional bei funktionalem Error-Handling keinen Rollback auslöst. - UnitOfWork-Interface (shared) + SpringUnitOfWork-Implementierung - JdbcProductionOrderRepository, JdbcRecipeRepository, JdbcBatchRepository, JdbcBatchNumberGenerator ersetzen JPA-Pendants - 17 JPA-Dateien entfernt (Entities, Mapper, Spring Data Interfaces) - Alle Production-Use-Cases nutzen UnitOfWork statt @Transactional - Liquibase-Changelogs H2-kompatibel gemacht (dbms-Attribute) - Tests auf Liquibase-Schema umgestellt (ddl-auto: none)
This commit is contained in:
parent
bfae3eff73
commit
e5bc5690da
64 changed files with 1248 additions and 1585 deletions
|
|
@ -7,6 +7,7 @@ import de.effigenix.shared.common.Result;
|
|||
import de.effigenix.shared.common.UnitOfMeasure;
|
||||
import de.effigenix.shared.security.ActorId;
|
||||
import de.effigenix.shared.security.AuthorizationPort;
|
||||
import de.effigenix.shared.persistence.UnitOfWork;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
|
@ -19,6 +20,7 @@ import java.time.OffsetDateTime;
|
|||
import java.time.ZoneOffset;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
|
|
@ -30,14 +32,16 @@ class ActivateRecipeTest {
|
|||
|
||||
@Mock private RecipeRepository recipeRepository;
|
||||
@Mock private AuthorizationPort authPort;
|
||||
@Mock private UnitOfWork unitOfWork;
|
||||
|
||||
private ActivateRecipe activateRecipe;
|
||||
private ActorId performedBy;
|
||||
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
activateRecipe = new ActivateRecipe(recipeRepository, authPort);
|
||||
activateRecipe = new ActivateRecipe(recipeRepository, authPort, unitOfWork);
|
||||
performedBy = ActorId.of("admin-user");
|
||||
lenient().when(unitOfWork.executeAtomically(any())).thenAnswer(inv -> ((Supplier<?>) inv.getArgument(0)).get());
|
||||
}
|
||||
|
||||
private Recipe draftRecipeWithIngredient() {
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ import de.effigenix.domain.production.*;
|
|||
import de.effigenix.shared.common.Result;
|
||||
import de.effigenix.shared.security.ActorId;
|
||||
import de.effigenix.shared.security.AuthorizationPort;
|
||||
import de.effigenix.shared.persistence.UnitOfWork;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
|
@ -14,6 +15,7 @@ import org.mockito.junit.jupiter.MockitoExtension;
|
|||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
|
|
@ -26,14 +28,16 @@ class AddRecipeIngredientTest {
|
|||
@Mock private RecipeRepository recipeRepository;
|
||||
@Mock private AuthorizationPort authPort;
|
||||
@Mock private RecipeCycleChecker cycleChecker;
|
||||
@Mock private UnitOfWork unitOfWork;
|
||||
|
||||
private AddRecipeIngredient addRecipeIngredient;
|
||||
private ActorId performedBy;
|
||||
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
addRecipeIngredient = new AddRecipeIngredient(recipeRepository, authPort, cycleChecker);
|
||||
addRecipeIngredient = new AddRecipeIngredient(recipeRepository, authPort, cycleChecker, unitOfWork);
|
||||
performedBy = ActorId.of("admin-user");
|
||||
lenient().when(unitOfWork.executeAtomically(any())).thenAnswer(inv -> ((Supplier<?>) inv.getArgument(0)).get());
|
||||
}
|
||||
|
||||
private Recipe draftRecipe() {
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ import de.effigenix.shared.common.Result;
|
|||
import de.effigenix.shared.common.UnitOfMeasure;
|
||||
import de.effigenix.shared.security.ActorId;
|
||||
import de.effigenix.shared.security.AuthorizationPort;
|
||||
import de.effigenix.shared.persistence.UnitOfWork;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
|
@ -19,6 +20,7 @@ import java.time.OffsetDateTime;
|
|||
import java.time.ZoneOffset;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
|
|
@ -30,14 +32,16 @@ class ArchiveRecipeTest {
|
|||
|
||||
@Mock private RecipeRepository recipeRepository;
|
||||
@Mock private AuthorizationPort authPort;
|
||||
@Mock private UnitOfWork unitOfWork;
|
||||
|
||||
private ArchiveRecipe archiveRecipe;
|
||||
private ActorId performedBy;
|
||||
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
archiveRecipe = new ArchiveRecipe(recipeRepository, authPort);
|
||||
archiveRecipe = new ArchiveRecipe(recipeRepository, authPort, unitOfWork);
|
||||
performedBy = ActorId.of("admin-user");
|
||||
lenient().when(unitOfWork.executeAtomically(any())).thenAnswer(inv -> ((Supplier<?>) inv.getArgument(0)).get());
|
||||
}
|
||||
|
||||
private Recipe activeRecipe() {
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ import de.effigenix.shared.common.Result;
|
|||
import de.effigenix.shared.common.UnitOfMeasure;
|
||||
import de.effigenix.shared.security.ActorId;
|
||||
import de.effigenix.shared.security.AuthorizationPort;
|
||||
import de.effigenix.shared.persistence.UnitOfWork;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
|
@ -21,6 +22,7 @@ import java.time.OffsetDateTime;
|
|||
import java.time.ZoneOffset;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
|
@ -31,14 +33,16 @@ class CancelBatchTest {
|
|||
|
||||
@Mock private BatchRepository batchRepository;
|
||||
@Mock private AuthorizationPort authPort;
|
||||
@Mock private UnitOfWork unitOfWork;
|
||||
|
||||
private CancelBatch cancelBatch;
|
||||
private ActorId performedBy;
|
||||
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
cancelBatch = new CancelBatch(batchRepository, authPort);
|
||||
cancelBatch = new CancelBatch(batchRepository, authPort, unitOfWork);
|
||||
performedBy = ActorId.of("admin-user");
|
||||
lenient().when(unitOfWork.executeAtomically(any())).thenAnswer(inv -> ((Supplier<?>) inv.getArgument(0)).get());
|
||||
}
|
||||
|
||||
private Batch plannedBatch(String id) {
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ import de.effigenix.shared.common.Result;
|
|||
import de.effigenix.shared.common.UnitOfMeasure;
|
||||
import de.effigenix.shared.security.ActorId;
|
||||
import de.effigenix.shared.security.AuthorizationPort;
|
||||
import de.effigenix.shared.persistence.UnitOfWork;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
|
@ -21,6 +22,7 @@ import java.time.OffsetDateTime;
|
|||
import java.time.ZoneOffset;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
|
@ -31,14 +33,16 @@ class CompleteBatchTest {
|
|||
|
||||
@Mock private BatchRepository batchRepository;
|
||||
@Mock private AuthorizationPort authPort;
|
||||
@Mock private UnitOfWork unitOfWork;
|
||||
|
||||
private CompleteBatch completeBatch;
|
||||
private ActorId performedBy;
|
||||
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
completeBatch = new CompleteBatch(batchRepository, authPort);
|
||||
completeBatch = new CompleteBatch(batchRepository, authPort, unitOfWork);
|
||||
performedBy = ActorId.of("admin-user");
|
||||
lenient().when(unitOfWork.executeAtomically(any())).thenAnswer(inv -> ((Supplier<?>) inv.getArgument(0)).get());
|
||||
}
|
||||
|
||||
private Batch inProductionBatchWithConsumption(String id) {
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ import de.effigenix.shared.common.Result;
|
|||
import de.effigenix.shared.common.UnitOfMeasure;
|
||||
import de.effigenix.shared.security.ActorId;
|
||||
import de.effigenix.shared.security.AuthorizationPort;
|
||||
import de.effigenix.shared.persistence.UnitOfWork;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
|
@ -21,6 +22,7 @@ import java.time.OffsetDateTime;
|
|||
import java.time.ZoneOffset;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
|
|
@ -33,6 +35,7 @@ class CreateProductionOrderTest {
|
|||
@Mock private ProductionOrderRepository productionOrderRepository;
|
||||
@Mock private RecipeRepository recipeRepository;
|
||||
@Mock private AuthorizationPort authPort;
|
||||
@Mock private UnitOfWork unitOfWork;
|
||||
|
||||
private CreateProductionOrder createProductionOrder;
|
||||
private ActorId performedBy;
|
||||
|
|
@ -41,8 +44,9 @@ class CreateProductionOrderTest {
|
|||
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
createProductionOrder = new CreateProductionOrder(productionOrderRepository, recipeRepository, authPort);
|
||||
createProductionOrder = new CreateProductionOrder(productionOrderRepository, recipeRepository, authPort, unitOfWork);
|
||||
performedBy = ActorId.of("admin-user");
|
||||
lenient().when(unitOfWork.executeAtomically(any())).thenAnswer(inv -> ((Supplier<?>) inv.getArgument(0)).get());
|
||||
}
|
||||
|
||||
private CreateProductionOrderCommand validCommand() {
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ import de.effigenix.shared.common.Result;
|
|||
import de.effigenix.shared.common.UnitOfMeasure;
|
||||
import de.effigenix.shared.security.ActorId;
|
||||
import de.effigenix.shared.security.AuthorizationPort;
|
||||
import de.effigenix.shared.persistence.UnitOfWork;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
|
@ -21,6 +22,7 @@ import java.time.OffsetDateTime;
|
|||
import java.time.ZoneOffset;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
|
|
@ -34,6 +36,7 @@ class PlanBatchTest {
|
|||
@Mock private RecipeRepository recipeRepository;
|
||||
@Mock private BatchNumberGenerator batchNumberGenerator;
|
||||
@Mock private AuthorizationPort authPort;
|
||||
@Mock private UnitOfWork unitOfWork;
|
||||
|
||||
private PlanBatch planBatch;
|
||||
private ActorId performedBy;
|
||||
|
|
@ -44,8 +47,9 @@ class PlanBatchTest {
|
|||
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
planBatch = new PlanBatch(batchRepository, recipeRepository, batchNumberGenerator, authPort);
|
||||
planBatch = new PlanBatch(batchRepository, recipeRepository, batchNumberGenerator, authPort, unitOfWork);
|
||||
performedBy = ActorId.of("admin-user");
|
||||
lenient().when(unitOfWork.executeAtomically(any())).thenAnswer(inv -> ((Supplier<?>) inv.getArgument(0)).get());
|
||||
}
|
||||
|
||||
private PlanBatchCommand validCommand() {
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ import de.effigenix.shared.common.Result;
|
|||
import de.effigenix.shared.common.UnitOfMeasure;
|
||||
import de.effigenix.shared.security.ActorId;
|
||||
import de.effigenix.shared.security.AuthorizationPort;
|
||||
import de.effigenix.shared.persistence.UnitOfWork;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
|
@ -21,6 +22,7 @@ import java.time.OffsetDateTime;
|
|||
import java.time.ZoneOffset;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
|
@ -31,14 +33,16 @@ class RecordConsumptionTest {
|
|||
|
||||
@Mock private BatchRepository batchRepository;
|
||||
@Mock private AuthorizationPort authPort;
|
||||
@Mock private UnitOfWork unitOfWork;
|
||||
|
||||
private RecordConsumption recordConsumption;
|
||||
private ActorId performedBy;
|
||||
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
recordConsumption = new RecordConsumption(batchRepository, authPort);
|
||||
recordConsumption = new RecordConsumption(batchRepository, authPort, unitOfWork);
|
||||
performedBy = ActorId.of("admin-user");
|
||||
lenient().when(unitOfWork.executeAtomically(any())).thenAnswer(inv -> ((Supplier<?>) inv.getArgument(0)).get());
|
||||
}
|
||||
|
||||
private Batch inProductionBatch(String id) {
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ import de.effigenix.shared.common.Result;
|
|||
import de.effigenix.shared.common.UnitOfMeasure;
|
||||
import de.effigenix.shared.security.ActorId;
|
||||
import de.effigenix.shared.security.AuthorizationPort;
|
||||
import de.effigenix.shared.persistence.UnitOfWork;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
|
@ -21,6 +22,7 @@ import java.time.OffsetDateTime;
|
|||
import java.time.ZoneOffset;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
|
|
@ -33,6 +35,7 @@ class ReleaseProductionOrderTest {
|
|||
@Mock private ProductionOrderRepository productionOrderRepository;
|
||||
@Mock private RecipeRepository recipeRepository;
|
||||
@Mock private AuthorizationPort authPort;
|
||||
@Mock private UnitOfWork unitOfWork;
|
||||
|
||||
private ReleaseProductionOrder releaseProductionOrder;
|
||||
private ActorId performedBy;
|
||||
|
|
@ -41,8 +44,9 @@ class ReleaseProductionOrderTest {
|
|||
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
releaseProductionOrder = new ReleaseProductionOrder(productionOrderRepository, recipeRepository, authPort);
|
||||
releaseProductionOrder = new ReleaseProductionOrder(productionOrderRepository, recipeRepository, authPort, unitOfWork);
|
||||
performedBy = ActorId.of("admin-user");
|
||||
lenient().when(unitOfWork.executeAtomically(any())).thenAnswer(inv -> ((Supplier<?>) inv.getArgument(0)).get());
|
||||
}
|
||||
|
||||
private ReleaseProductionOrderCommand validCommand() {
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ import de.effigenix.shared.common.Result;
|
|||
import de.effigenix.shared.common.UnitOfMeasure;
|
||||
import de.effigenix.shared.security.ActorId;
|
||||
import de.effigenix.shared.security.AuthorizationPort;
|
||||
import de.effigenix.shared.persistence.UnitOfWork;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
|
@ -21,6 +22,7 @@ import java.time.OffsetDateTime;
|
|||
import java.time.ZoneOffset;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
|
@ -31,14 +33,16 @@ class StartBatchTest {
|
|||
|
||||
@Mock private BatchRepository batchRepository;
|
||||
@Mock private AuthorizationPort authPort;
|
||||
@Mock private UnitOfWork unitOfWork;
|
||||
|
||||
private StartBatch startBatch;
|
||||
private ActorId performedBy;
|
||||
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
startBatch = new StartBatch(batchRepository, authPort);
|
||||
startBatch = new StartBatch(batchRepository, authPort, unitOfWork);
|
||||
performedBy = ActorId.of("admin-user");
|
||||
lenient().when(unitOfWork.executeAtomically(any())).thenAnswer(inv -> ((Supplier<?>) inv.getArgument(0)).get());
|
||||
}
|
||||
|
||||
private Batch plannedBatch(String id) {
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ import de.effigenix.shared.common.Result;
|
|||
import de.effigenix.shared.common.UnitOfMeasure;
|
||||
import de.effigenix.shared.security.ActorId;
|
||||
import de.effigenix.shared.security.AuthorizationPort;
|
||||
import de.effigenix.shared.persistence.UnitOfWork;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
|
@ -21,6 +22,7 @@ import java.time.OffsetDateTime;
|
|||
import java.time.ZoneOffset;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
|
|
@ -33,6 +35,7 @@ class StartProductionOrderTest {
|
|||
@Mock private ProductionOrderRepository productionOrderRepository;
|
||||
@Mock private BatchRepository batchRepository;
|
||||
@Mock private AuthorizationPort authPort;
|
||||
@Mock private UnitOfWork unitOfWork;
|
||||
|
||||
private StartProductionOrder startProductionOrder;
|
||||
private ActorId performedBy;
|
||||
|
|
@ -41,8 +44,9 @@ class StartProductionOrderTest {
|
|||
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
startProductionOrder = new StartProductionOrder(productionOrderRepository, batchRepository, authPort);
|
||||
startProductionOrder = new StartProductionOrder(productionOrderRepository, batchRepository, authPort, unitOfWork);
|
||||
performedBy = ActorId.of("admin-user");
|
||||
lenient().when(unitOfWork.executeAtomically(any())).thenAnswer(inv -> ((Supplier<?>) inv.getArgument(0)).get());
|
||||
}
|
||||
|
||||
private StartProductionOrderCommand validCommand() {
|
||||
|
|
|
|||
|
|
@ -3,6 +3,10 @@ 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;
|
||||
|
|
@ -45,6 +49,12 @@ public abstract class AbstractIntegrationTest {
|
|||
@Autowired
|
||||
protected RoleJpaRepository roleRepository;
|
||||
|
||||
@Autowired
|
||||
protected ArticleJpaRepository articleRepository;
|
||||
|
||||
@Autowired
|
||||
protected ProductCategoryJpaRepository productCategoryRepository;
|
||||
|
||||
@Value("${jwt.secret}")
|
||||
protected String jwtSecret;
|
||||
|
||||
|
|
@ -94,9 +104,11 @@ public abstract class AbstractIntegrationTest {
|
|||
}
|
||||
|
||||
protected RoleEntity createRole(RoleName roleName, String description) {
|
||||
RoleEntity role = new RoleEntity(
|
||||
UUID.randomUUID().toString(), roleName, Set.of(), description);
|
||||
return roleRepository.save(role);
|
||||
return roleRepository.findByName(roleName).orElseGet(() -> {
|
||||
RoleEntity role = new RoleEntity(
|
||||
UUID.randomUUID().toString(), roleName, Set.of(), description);
|
||||
return roleRepository.save(role);
|
||||
});
|
||||
}
|
||||
|
||||
protected UserEntity createUser(String username, String email, Set<RoleEntity> roles, String branchId) {
|
||||
|
|
@ -106,4 +118,14 @@ public abstract class AbstractIntegrationTest {
|
|||
branchId, UserStatus.ACTIVE, OffsetDateTime.now(ZoneOffset.UTC), null);
|
||||
return userRepository.save(user);
|
||||
}
|
||||
|
||||
protected String createArticleId() {
|
||||
String categoryId = UUID.randomUUID().toString();
|
||||
productCategoryRepository.save(new ProductCategoryEntity(categoryId, "TestCat-" + categoryId.substring(0, 8), null));
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -52,13 +52,17 @@ class StockControllerIntegrationTest extends AbstractIntegrationTest {
|
|||
storageLocationId = createStorageLocation();
|
||||
}
|
||||
|
||||
private String newArticleId() {
|
||||
return createArticleId();
|
||||
}
|
||||
|
||||
// ==================== Bestandsposition anlegen – Pflichtfelder ====================
|
||||
|
||||
@Test
|
||||
@DisplayName("Bestandsposition mit Pflichtfeldern erstellen → 201")
|
||||
void createStock_withRequiredFields_returns201() throws Exception {
|
||||
var request = new CreateStockRequest(
|
||||
UUID.randomUUID().toString(), storageLocationId, null, null, null);
|
||||
newArticleId(), storageLocationId, null, null, null);
|
||||
|
||||
mockMvc.perform(post("/api/inventory/stocks")
|
||||
.header("Authorization", "Bearer " + adminToken)
|
||||
|
|
@ -78,7 +82,7 @@ class StockControllerIntegrationTest extends AbstractIntegrationTest {
|
|||
@DisplayName("Bestandsposition mit allen Feldern erstellen → 201")
|
||||
void createStock_withAllFields_returns201() throws Exception {
|
||||
var request = new CreateStockRequest(
|
||||
UUID.randomUUID().toString(), storageLocationId, "10.5", "KILOGRAM", 30);
|
||||
newArticleId(), storageLocationId, "10.5", "KILOGRAM", 30);
|
||||
|
||||
mockMvc.perform(post("/api/inventory/stocks")
|
||||
.header("Authorization", "Bearer " + adminToken)
|
||||
|
|
@ -97,7 +101,7 @@ class StockControllerIntegrationTest extends AbstractIntegrationTest {
|
|||
@Test
|
||||
@DisplayName("Bestandsposition Duplikat (gleiche articleId+storageLocationId) → 409")
|
||||
void createStock_duplicate_returns409() throws Exception {
|
||||
String articleId = UUID.randomUUID().toString();
|
||||
String articleId = newArticleId();
|
||||
var request = new CreateStockRequest(articleId, storageLocationId, null, null, null);
|
||||
|
||||
mockMvc.perform(post("/api/inventory/stocks")
|
||||
|
|
@ -942,7 +946,7 @@ class StockControllerIntegrationTest extends AbstractIntegrationTest {
|
|||
@Test
|
||||
@DisplayName("Bestandspositionen nach articleId filtern → 200")
|
||||
void listStocks_filterByArticleId() throws Exception {
|
||||
String articleId = UUID.randomUUID().toString();
|
||||
String articleId = newArticleId();
|
||||
createStockForArticle(articleId);
|
||||
|
||||
mockMvc.perform(get("/api/inventory/stocks")
|
||||
|
|
@ -1512,7 +1516,7 @@ class StockControllerIntegrationTest extends AbstractIntegrationTest {
|
|||
|
||||
private String createStock() throws Exception {
|
||||
var request = new CreateStockRequest(
|
||||
UUID.randomUUID().toString(), storageLocationId, null, null, null);
|
||||
newArticleId(), storageLocationId, null, null, null);
|
||||
|
||||
var result = mockMvc.perform(post("/api/inventory/stocks")
|
||||
.header("Authorization", "Bearer " + adminToken)
|
||||
|
|
@ -1526,7 +1530,7 @@ class StockControllerIntegrationTest extends AbstractIntegrationTest {
|
|||
|
||||
private String createStockForLocation(String locationId) throws Exception {
|
||||
var request = new CreateStockRequest(
|
||||
UUID.randomUUID().toString(), locationId, null, null, null);
|
||||
newArticleId(), locationId, null, null, null);
|
||||
|
||||
var result = mockMvc.perform(post("/api/inventory/stocks")
|
||||
.header("Authorization", "Bearer " + adminToken)
|
||||
|
|
@ -1540,7 +1544,7 @@ class StockControllerIntegrationTest extends AbstractIntegrationTest {
|
|||
|
||||
private String createStockWithMinimumLevel(String minimumAmount, String unit) throws Exception {
|
||||
var request = new CreateStockRequest(
|
||||
UUID.randomUUID().toString(), storageLocationId, minimumAmount, unit, null);
|
||||
newArticleId(), storageLocationId, minimumAmount, unit, null);
|
||||
|
||||
var result = mockMvc.perform(post("/api/inventory/stocks")
|
||||
.header("Authorization", "Bearer " + adminToken)
|
||||
|
|
|
|||
|
|
@ -408,7 +408,7 @@ class StorageLocationControllerIntegrationTest extends AbstractIntegrationTest {
|
|||
|
||||
// Stock an diesem Lagerort anlegen
|
||||
var stockRequest = new CreateStockRequest(
|
||||
UUID.randomUUID().toString(), id, null, null, null);
|
||||
createArticleId(), id, null, null, null);
|
||||
mockMvc.perform(post("/api/inventory/stocks")
|
||||
.header("Authorization", "Bearer " + adminToken)
|
||||
.contentType(MediaType.APPLICATION_JSON)
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@ package de.effigenix.infrastructure.production.web;
|
|||
|
||||
import de.effigenix.domain.usermanagement.RoleName;
|
||||
import de.effigenix.infrastructure.AbstractIntegrationTest;
|
||||
import de.effigenix.infrastructure.production.persistence.entity.RecipeEntity;
|
||||
import de.effigenix.infrastructure.production.web.dto.PlanBatchRequest;
|
||||
import de.effigenix.infrastructure.usermanagement.persistence.entity.RoleEntity;
|
||||
import de.effigenix.infrastructure.usermanagement.persistence.entity.UserEntity;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue