fix: replay preload confirmation idempotently
This commit is contained in:
@@ -541,8 +541,9 @@ class LoadingListServiceTest {
|
||||
10L, 30L, "CONFIRMED", 4, readiness("CONFIRMED", false, true, 80L));
|
||||
String requestHash = sha256("CONFIRM_PRELOAD|10|3");
|
||||
HistoryRow replay = new HistoryRow();
|
||||
replay.setAfterSnapshot(new ObjectMapper().writeValueAsString(
|
||||
java.util.Map.of("requestHash", requestHash, "response", expected)));
|
||||
ObjectMapper mapper = new ObjectMapper();
|
||||
replay.setAfterSnapshot(mapper.writerWithDefaultPrettyPrinter().writeValueAsString(
|
||||
java.util.Map.of("response", expected, "requestHash", requestHash)));
|
||||
when(repository.history(anyString())).thenReturn(replay);
|
||||
|
||||
PreloadConfirmationResponse actual = service.confirmPreload(
|
||||
@@ -552,6 +553,53 @@ class LoadingListServiceTest {
|
||||
verify(loadingPickService, never()).requirePreloadConfirmationReady(anyLong());
|
||||
verify(repository, never()).touchForPreloadConfirmation(anyLong(),
|
||||
org.mockito.ArgumentMatchers.anyInt(), anyLong(), anyString());
|
||||
verify(repository, never()).appendHistory(anyLong(), anyString(), anyString(),
|
||||
anyString(), anyString(), anyString(), anyString(), anyLong(), anyString(),
|
||||
org.mockito.ArgumentMatchers.isNull());
|
||||
verify(loadingPickService, never()).beginIfReady(anyLong(), anyLong(), anyString());
|
||||
}
|
||||
|
||||
@Test
|
||||
void rejectsConfirmationReplayWhenExpectedVersionDiffers() throws Exception {
|
||||
PreloadConfirmationResponse expected = new PreloadConfirmationResponse(
|
||||
10L, 30L, "CONFIRMED", 4, readiness("CONFIRMED", false, true, 80L));
|
||||
String originalHash = sha256("CONFIRM_PRELOAD|10|3");
|
||||
HistoryRow replay = new HistoryRow();
|
||||
replay.setAfterSnapshot(new ObjectMapper().writeValueAsString(
|
||||
java.util.Map.of("requestHash", originalHash, "response", expected)));
|
||||
when(repository.history(anyString())).thenReturn(replay);
|
||||
|
||||
assertThatThrownBy(() -> service.confirmPreload(
|
||||
10L, 9L, "operator", "confirm-key", new ConfirmPreloadRequest(4)))
|
||||
.isInstanceOf(BizException.class)
|
||||
.extracting(error -> ((BizException) error).getResultCode())
|
||||
.isEqualTo(ResultCode.CONFLICT);
|
||||
|
||||
verify(repository, never()).touchForPreloadConfirmation(anyLong(),
|
||||
org.mockito.ArgumentMatchers.anyInt(), anyLong(), anyString());
|
||||
verify(loadingPickService, never()).requirePreloadConfirmationReady(anyLong());
|
||||
}
|
||||
|
||||
@Test
|
||||
void rejectsNewConfirmationKeyAfterPlanWasAlreadyConfirmed() {
|
||||
AggregateRow confirmed = row("EDITING", 4);
|
||||
confirmed.setPreloadPushedAt(java.time.LocalDateTime.now());
|
||||
when(repository.history(anyString())).thenReturn(null);
|
||||
when(repository.aggregate(10L)).thenReturn(confirmed);
|
||||
when(loadingPickService.requirePreloadConfirmationReady(10L))
|
||||
.thenThrow(new BizException(ResultCode.CONFLICT, "预装计划已确认"));
|
||||
|
||||
assertThatThrownBy(() -> service.confirmPreload(
|
||||
10L, 9L, "operator", "new-confirm-key", new ConfirmPreloadRequest(4)))
|
||||
.isInstanceOf(BizException.class)
|
||||
.extracting(error -> ((BizException) error).getResultCode())
|
||||
.isEqualTo(ResultCode.CONFLICT);
|
||||
|
||||
verify(repository, never()).touchForPreloadConfirmation(anyLong(),
|
||||
org.mockito.ArgumentMatchers.anyInt(), anyLong(), anyString());
|
||||
verify(repository, never()).appendHistory(anyLong(), anyString(), anyString(),
|
||||
anyString(), anyString(), anyString(), anyString(), anyLong(), anyString(),
|
||||
org.mockito.ArgumentMatchers.isNull());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
Reference in New Issue
Block a user