mirror of
https://github.com/s-frick/effigenix.git
synced 2026-03-28 12:09:35 +01:00
fix(inventory): Instant.MIN/MAX, performed_at-Index, batchReference-Naming und -Validierung, Lasttest-Zeiträume
- Instant.MIN/MAX durch separate Repository-Methoden ersetzt (findAllByPerformedAtAfter/Before) - DB-Index auf performed_at für Zeitraum-Abfragen - Naming-Konsistenz: findAllByBatchId → findAllByBatchReference im Domain-Repository - batchReference-Validierung (Blank-Check) mit InvalidBatchReference-Error - Lasttest: variierende Zeiträume (7–90 Tage) statt statischem 10-Jahres-Fenster
This commit is contained in:
parent
0e5d8f7025
commit
a8bbe3a951
9 changed files with 114 additions and 25 deletions
|
|
@ -22,7 +22,9 @@ import java.util.List;
|
|||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.*;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
@DisplayName("ListStockMovements Use Case")
|
||||
|
|
@ -155,20 +157,20 @@ class ListStockMovementsTest {
|
|||
@Test
|
||||
@DisplayName("should filter by batchReference")
|
||||
void shouldFilterByBatchReference() {
|
||||
when(repository.findAllByBatchId("CHARGE-001"))
|
||||
when(repository.findAllByBatchReference("CHARGE-001"))
|
||||
.thenReturn(Result.success(List.of(sampleMovement)));
|
||||
|
||||
var result = useCase.execute(null, null, null, "CHARGE-001", null, null, actor);
|
||||
|
||||
assertThat(result.isSuccess()).isTrue();
|
||||
assertThat(result.unsafeGetValue()).hasSize(1);
|
||||
verify(repository).findAllByBatchId("CHARGE-001");
|
||||
verify(repository).findAllByBatchReference("CHARGE-001");
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("should return empty list when no movements for batch")
|
||||
void shouldReturnEmptyForUnknownBatch() {
|
||||
when(repository.findAllByBatchId("UNKNOWN"))
|
||||
when(repository.findAllByBatchReference("UNKNOWN"))
|
||||
.thenReturn(Result.success(List.of()));
|
||||
|
||||
var result = useCase.execute(null, null, null, "UNKNOWN", null, null, actor);
|
||||
|
|
@ -177,10 +179,19 @@ class ListStockMovementsTest {
|
|||
assertThat(result.unsafeGetValue()).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("should fail with InvalidBatchReference when blank")
|
||||
void shouldFailWhenBatchReferenceBlank() {
|
||||
var result = useCase.execute(null, null, null, " ", null, null, actor);
|
||||
|
||||
assertThat(result.isFailure()).isTrue();
|
||||
assertThat(result.unsafeGetError()).isInstanceOf(StockMovementError.InvalidBatchReference.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("should fail when repository fails for batchReference")
|
||||
void shouldFailWhenRepositoryFailsForBatch() {
|
||||
when(repository.findAllByBatchId("CHARGE-001"))
|
||||
when(repository.findAllByBatchReference("CHARGE-001"))
|
||||
.thenReturn(Result.failure(new RepositoryError.DatabaseError("connection lost")));
|
||||
|
||||
var result = useCase.execute(null, null, null, "CHARGE-001", null, null, actor);
|
||||
|
|
@ -240,25 +251,25 @@ class ListStockMovementsTest {
|
|||
@Test
|
||||
@DisplayName("should filter with only from (open-ended)")
|
||||
void shouldFilterByFromOnly() {
|
||||
when(repository.findAllByPerformedAtBetween(eq(from), any()))
|
||||
when(repository.findAllByPerformedAtAfter(from))
|
||||
.thenReturn(Result.success(List.of(sampleMovement)));
|
||||
|
||||
var result = useCase.execute(null, null, null, null, from, null, actor);
|
||||
|
||||
assertThat(result.isSuccess()).isTrue();
|
||||
verify(repository).findAllByPerformedAtBetween(eq(from), eq(Instant.MAX));
|
||||
verify(repository).findAllByPerformedAtAfter(from);
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("should filter with only to (open-ended)")
|
||||
void shouldFilterByToOnly() {
|
||||
when(repository.findAllByPerformedAtBetween(any(), eq(to)))
|
||||
when(repository.findAllByPerformedAtBefore(to))
|
||||
.thenReturn(Result.success(List.of(sampleMovement)));
|
||||
|
||||
var result = useCase.execute(null, null, null, null, null, to, actor);
|
||||
|
||||
assertThat(result.isSuccess()).isTrue();
|
||||
verify(repository).findAllByPerformedAtBetween(eq(Instant.MIN), eq(to));
|
||||
verify(repository).findAllByPerformedAtBefore(to);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
@ -311,7 +322,7 @@ class ListStockMovementsTest {
|
|||
assertThat(result.isSuccess()).isTrue();
|
||||
verify(repository).findAllByStockId(StockId.of("stock-1"));
|
||||
verify(repository, never()).findAllByArticleId(any());
|
||||
verify(repository, never()).findAllByBatchId(any());
|
||||
verify(repository, never()).findAllByBatchReference(any());
|
||||
verify(repository, never()).findAllByMovementType(any());
|
||||
}
|
||||
|
||||
|
|
@ -325,20 +336,20 @@ class ListStockMovementsTest {
|
|||
|
||||
assertThat(result.isSuccess()).isTrue();
|
||||
verify(repository).findAllByArticleId(ArticleId.of("article-1"));
|
||||
verify(repository, never()).findAllByBatchId(any());
|
||||
verify(repository, never()).findAllByBatchReference(any());
|
||||
verify(repository, never()).findAllByMovementType(any());
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("batchReference takes priority over movementType")
|
||||
void batchReferenceTakesPriorityOverMovementType() {
|
||||
when(repository.findAllByBatchId("CHARGE-001"))
|
||||
when(repository.findAllByBatchReference("CHARGE-001"))
|
||||
.thenReturn(Result.success(List.of()));
|
||||
|
||||
var result = useCase.execute(null, null, "GOODS_RECEIPT", "CHARGE-001", null, null, actor);
|
||||
|
||||
assertThat(result.isSuccess()).isTrue();
|
||||
verify(repository).findAllByBatchId("CHARGE-001");
|
||||
verify(repository).findAllByBatchReference("CHARGE-001");
|
||||
verify(repository, never()).findAllByMovementType(any());
|
||||
}
|
||||
|
||||
|
|
@ -375,7 +386,7 @@ class ListStockMovementsTest {
|
|||
@Test
|
||||
@DisplayName("batchReference takes priority over from/to")
|
||||
void batchReferenceTakesPriorityOverDateRange() {
|
||||
when(repository.findAllByBatchId("CHARGE-001"))
|
||||
when(repository.findAllByBatchReference("CHARGE-001"))
|
||||
.thenReturn(Result.success(List.of()));
|
||||
|
||||
Instant from = Instant.parse("2026-01-01T00:00:00Z");
|
||||
|
|
@ -383,7 +394,7 @@ class ListStockMovementsTest {
|
|||
var result = useCase.execute(null, null, null, "CHARGE-001", from, to, actor);
|
||||
|
||||
assertThat(result.isSuccess()).isTrue();
|
||||
verify(repository).findAllByBatchId("CHARGE-001");
|
||||
verify(repository).findAllByBatchReference("CHARGE-001");
|
||||
verify(repository, never()).findAllByPerformedAtBetween(any(), any());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -555,6 +555,16 @@ class StockMovementControllerIntegrationTest extends AbstractIntegrationTest {
|
|||
.andExpect(jsonPath("$").isArray());
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Leere batchReference → 400")
|
||||
void filterByBlankBatchReference_returns400() throws Exception {
|
||||
mockMvc.perform(get("/api/inventory/stock-movements")
|
||||
.param("batchReference", " ")
|
||||
.header("Authorization", "Bearer " + adminToken))
|
||||
.andExpect(status().isBadRequest())
|
||||
.andExpect(jsonPath("$.code").value("INVALID_BATCH_REFERENCE"));
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("Unbekannte batchReference → 200 mit []")
|
||||
void filterByUnknownBatchReference_returns200Empty() throws Exception {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue