实现 V4 复核解阻接口
This commit is contained in:
@@ -73,6 +73,7 @@ class AuthControllerTest {
|
||||
"RESERVATION_TASK_READ",
|
||||
"RESERVATION_TASK_EDIT",
|
||||
"RESERVATION_TASK_CONFIRM",
|
||||
"RESERVATION_MANUAL_REVIEW_RESOLVE",
|
||||
"RESERVATION_OPERA_SIM_EXECUTE",
|
||||
"RESERVATION_AUDIT_READ",
|
||||
"RESERVATION_INVOICE_GENERATE",
|
||||
|
||||
@@ -28,6 +28,7 @@ import cn.nianxx.thhotel.workflows.reservation.common.enums.ReservationV4CardTyp
|
||||
import cn.nianxx.thhotel.workflows.reservation.common.enums.ReservationV4NotificationStatus;
|
||||
import cn.nianxx.thhotel.workflows.reservation.common.enums.ReservationV4OrderTaskStatus;
|
||||
import cn.nianxx.thhotel.workflows.reservation.common.enums.ReservationV4TargetResolutionStatus;
|
||||
import cn.nianxx.thhotel.workflows.reservation.common.enums.ReservationReviewStatus;
|
||||
import cn.nianxx.thhotel.workflows.reservation.repository.ReservationV4SourceNotificationRepository;
|
||||
import cn.nianxx.thhotel.workflows.reservation.repository.ReservationV4WorkflowRepository;
|
||||
import java.time.Instant;
|
||||
@@ -206,6 +207,286 @@ class ReservationV4CommandControllerTest {
|
||||
.andExpect(jsonPath("$.error_code").value("V4_CARD_ALREADY_CONFIRMED"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldResolveBasicInformationReviewAndConfirmOrderOwnership() throws Exception {
|
||||
Long confirmedOrderId = 990000000000070002L;
|
||||
seedReservationOrder(HOTEL_ID, confirmedOrderId);
|
||||
SeededOrderTask seeded = seedReviewOrderTask(
|
||||
HOTEL_ID,
|
||||
"mail-v4-command-review-basic-001",
|
||||
Instant.parse("2026-07-19T01:21:00Z"),
|
||||
null,
|
||||
ReservationV4CardStatus.REVIEW_REQUIRED.name(),
|
||||
ReservationV4CardStatus.PENDING_CONFIRM.name());
|
||||
|
||||
performAuthorized(mockMvc, adminToken(), post(
|
||||
"/api/reservation/order-tasks/{orderTaskId}/cards/{cardId}/review-resolution",
|
||||
seeded.orderTask().id(),
|
||||
seeded.basicCard().id())
|
||||
.contentType(MediaType.APPLICATION_JSON)
|
||||
.content("""
|
||||
{
|
||||
"version": 0,
|
||||
"reason": "确认订单归属并补齐旅行社代码",
|
||||
"confirmed_order_id": "990000000000070002",
|
||||
"field_overrides": [
|
||||
{
|
||||
"field_pointer": "/basic_information/account_code",
|
||||
"value": "QBD_TRAVEL"
|
||||
}
|
||||
]
|
||||
}
|
||||
"""))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.order_task.order_id").value(confirmedOrderId.toString()))
|
||||
.andExpect(jsonPath("$.order_task.target_resolution_status").value("RESOLVED"))
|
||||
.andExpect(jsonPath("$.basic_information_card.card_status").value("CONFIRMED"))
|
||||
.andExpect(jsonPath("$.basic_information_card.review_status").value("RESOLVED"))
|
||||
.andExpect(jsonPath("$.basic_information_card.confirmed_by").value("v4-command-admin"))
|
||||
.andExpect(jsonPath("$.basic_information_card.confirmed_payload.basic_information.account_code").value("QBD_TRAVEL"))
|
||||
.andExpect(jsonPath("$.basic_information_card.review_resolution.field_overrides[0].field_pointer")
|
||||
.value("/basic_information/account_code"))
|
||||
.andExpect(jsonPath("$.business_cards[0].availability.confirmable").value(true));
|
||||
assertAuditCount("V4_CARD_REVIEW_RESOLVE", "v4-command-admin", seeded.orderTask().id().toString(), 1);
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldResolveOrderOwnershipStatusWhenConfirmedOrderIdAlreadyBound() throws Exception {
|
||||
Long confirmedOrderId = 990000000000070009L;
|
||||
seedReservationOrder(HOTEL_ID, confirmedOrderId);
|
||||
SeededOrderTask seeded = seedReviewOrderTask(
|
||||
HOTEL_ID,
|
||||
"mail-v4-command-review-same-order-001",
|
||||
Instant.parse("2026-07-19T01:21:30Z"),
|
||||
confirmedOrderId,
|
||||
ReservationV4TargetResolutionStatus.UNRESOLVED.name(),
|
||||
ReservationV4CardStatus.REVIEW_REQUIRED.name(),
|
||||
ReservationV4CardStatus.PENDING_CONFIRM.name());
|
||||
|
||||
performAuthorized(mockMvc, adminToken(), post(
|
||||
"/api/reservation/order-tasks/{orderTaskId}/cards/{cardId}/review-resolution",
|
||||
seeded.orderTask().id(),
|
||||
seeded.basicCard().id())
|
||||
.contentType(MediaType.APPLICATION_JSON)
|
||||
.content("""
|
||||
{
|
||||
"version": 0,
|
||||
"confirmed_order_id": "990000000000070009",
|
||||
"field_overrides": [
|
||||
{"field_pointer": "/basic_information/account_code", "value": "QBD_TRAVEL"}
|
||||
]
|
||||
}
|
||||
"""))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.order_task.order_id").value(confirmedOrderId.toString()))
|
||||
.andExpect(jsonPath("$.order_task.target_resolution_status").value("RESOLVED"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldResolveBusinessCardReviewAfterBasicInformationConfirmed() throws Exception {
|
||||
SeededOrderTask seeded = seedReviewOrderTask(
|
||||
HOTEL_ID,
|
||||
"mail-v4-command-review-business-001",
|
||||
Instant.parse("2026-07-19T01:22:00Z"),
|
||||
990000000000070003L,
|
||||
ReservationV4CardStatus.PENDING_CONFIRM.name(),
|
||||
ReservationV4CardStatus.REVIEW_REQUIRED.name());
|
||||
confirmBasicCard(seeded);
|
||||
|
||||
performAuthorized(mockMvc, adminToken(), post(
|
||||
"/api/reservation/order-tasks/{orderTaskId}/cards/{cardId}/review-resolution",
|
||||
seeded.orderTask().id(),
|
||||
seeded.businessCard().id())
|
||||
.contentType(MediaType.APPLICATION_JSON)
|
||||
.content("""
|
||||
{
|
||||
"version": 0,
|
||||
"reason": "确认房型映射",
|
||||
"field_overrides": [
|
||||
{
|
||||
"field_pointer": "/business_fields/room_items/0/pms_room_type_code",
|
||||
"value": "RM2"
|
||||
}
|
||||
]
|
||||
}
|
||||
"""))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.order_task.order_task_status").value("COMPLETED"))
|
||||
.andExpect(jsonPath("$.business_cards[0].card_status").value("CONFIRMED"))
|
||||
.andExpect(jsonPath("$.business_cards[0].review_status").value("RESOLVED"))
|
||||
.andExpect(jsonPath("$.business_cards[0].confirmed_payload.business_fields.room_items[0].pms_room_type_code")
|
||||
.value("RM2"))
|
||||
.andExpect(jsonPath("$.business_cards[0].review_resolution.reason").value("确认房型映射"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldRejectReviewResolutionWhenOrderOwnershipUnresolvedAndConfirmedOrderMissing() throws Exception {
|
||||
SeededOrderTask seeded = seedReviewOrderTask(
|
||||
HOTEL_ID,
|
||||
"mail-v4-command-review-order-required-001",
|
||||
Instant.parse("2026-07-19T01:22:30Z"),
|
||||
null,
|
||||
ReservationV4CardStatus.REVIEW_REQUIRED.name(),
|
||||
ReservationV4CardStatus.PENDING_CONFIRM.name());
|
||||
|
||||
performAuthorized(mockMvc, adminToken(), post(
|
||||
"/api/reservation/order-tasks/{orderTaskId}/cards/{cardId}/review-resolution",
|
||||
seeded.orderTask().id(),
|
||||
seeded.basicCard().id())
|
||||
.contentType(MediaType.APPLICATION_JSON)
|
||||
.content("""
|
||||
{
|
||||
"version": 0,
|
||||
"field_overrides": [
|
||||
{"field_pointer": "/basic_information/account_code", "value": "QBD_TRAVEL"}
|
||||
]
|
||||
}
|
||||
"""))
|
||||
.andExpect(status().isBadRequest())
|
||||
.andExpect(jsonPath("$.error_code").value("V4_CONFIRMED_ORDER_ID_REQUIRED"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldRejectReviewResolutionForUnknownConfirmedOrder() throws Exception {
|
||||
SeededOrderTask seeded = seedReviewOrderTask(
|
||||
HOTEL_ID,
|
||||
"mail-v4-command-review-unknown-order-001",
|
||||
Instant.parse("2026-07-19T01:22:40Z"),
|
||||
null,
|
||||
ReservationV4CardStatus.REVIEW_REQUIRED.name(),
|
||||
ReservationV4CardStatus.PENDING_CONFIRM.name());
|
||||
|
||||
performAuthorized(mockMvc, adminToken(), post(
|
||||
"/api/reservation/order-tasks/{orderTaskId}/cards/{cardId}/review-resolution",
|
||||
seeded.orderTask().id(),
|
||||
seeded.basicCard().id())
|
||||
.contentType(MediaType.APPLICATION_JSON)
|
||||
.content("""
|
||||
{
|
||||
"version": 0,
|
||||
"confirmed_order_id": "990000000000070199",
|
||||
"field_overrides": [
|
||||
{"field_pointer": "/basic_information/account_code", "value": "QBD_TRAVEL"}
|
||||
]
|
||||
}
|
||||
"""))
|
||||
.andExpect(status().isNotFound())
|
||||
.andExpect(jsonPath("$.error_code").value("V4_CONFIRMED_ORDER_NOT_FOUND"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldRejectReviewResolutionForIllegalPointer() throws Exception {
|
||||
SeededOrderTask seeded = seedReviewOrderTask(
|
||||
HOTEL_ID,
|
||||
"mail-v4-command-review-illegal-pointer-001",
|
||||
Instant.parse("2026-07-19T01:23:00Z"),
|
||||
990000000000070004L,
|
||||
ReservationV4CardStatus.PENDING_CONFIRM.name(),
|
||||
ReservationV4CardStatus.REVIEW_REQUIRED.name());
|
||||
confirmBasicCard(seeded);
|
||||
|
||||
performAuthorized(mockMvc, adminToken(), post(
|
||||
"/api/reservation/order-tasks/{orderTaskId}/cards/{cardId}/review-resolution",
|
||||
seeded.orderTask().id(),
|
||||
seeded.businessCard().id())
|
||||
.contentType(MediaType.APPLICATION_JSON)
|
||||
.content("""
|
||||
{
|
||||
"version": 0,
|
||||
"field_overrides": [
|
||||
{"field_pointer": "business_fields/room_items/0/pms_room_type_code", "value": "RM2"}
|
||||
]
|
||||
}
|
||||
"""))
|
||||
.andExpect(status().isBadRequest())
|
||||
.andExpect(jsonPath("$.error_code").value("V4_REVIEW_POINTER_INVALID"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldRejectReviewResolutionForReadonlyPointer() throws Exception {
|
||||
SeededOrderTask seeded = seedReviewOrderTask(
|
||||
HOTEL_ID,
|
||||
"mail-v4-command-review-readonly-pointer-001",
|
||||
Instant.parse("2026-07-19T01:24:00Z"),
|
||||
990000000000070005L,
|
||||
ReservationV4CardStatus.PENDING_CONFIRM.name(),
|
||||
ReservationV4CardStatus.REVIEW_REQUIRED.name());
|
||||
confirmBasicCard(seeded);
|
||||
|
||||
performAuthorized(mockMvc, adminToken(), post(
|
||||
"/api/reservation/order-tasks/{orderTaskId}/cards/{cardId}/review-resolution",
|
||||
seeded.orderTask().id(),
|
||||
seeded.businessCard().id())
|
||||
.contentType(MediaType.APPLICATION_JSON)
|
||||
.content("""
|
||||
{
|
||||
"version": 0,
|
||||
"field_overrides": [
|
||||
{"field_pointer": "/card_type", "value": "PAYMENT"}
|
||||
]
|
||||
}
|
||||
"""))
|
||||
.andExpect(status().isBadRequest())
|
||||
.andExpect(jsonPath("$.error_code").value("V4_REVIEW_POINTER_READONLY"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldRejectReviewResolutionForContainerPointer() throws Exception {
|
||||
SeededOrderTask seeded = seedReviewOrderTask(
|
||||
HOTEL_ID,
|
||||
"mail-v4-command-review-container-pointer-001",
|
||||
Instant.parse("2026-07-19T01:24:15Z"),
|
||||
990000000000070010L,
|
||||
ReservationV4CardStatus.PENDING_CONFIRM.name(),
|
||||
ReservationV4CardStatus.REVIEW_REQUIRED.name());
|
||||
confirmBasicCard(seeded);
|
||||
|
||||
performAuthorized(mockMvc, adminToken(), post(
|
||||
"/api/reservation/order-tasks/{orderTaskId}/cards/{cardId}/review-resolution",
|
||||
seeded.orderTask().id(),
|
||||
seeded.businessCard().id())
|
||||
.contentType(MediaType.APPLICATION_JSON)
|
||||
.content("""
|
||||
{
|
||||
"version": 0,
|
||||
"field_overrides": [
|
||||
{"field_pointer": "/business_fields/room_items", "value": []}
|
||||
]
|
||||
}
|
||||
"""))
|
||||
.andExpect(status().isBadRequest())
|
||||
.andExpect(jsonPath("$.error_code").value("V4_REVIEW_VALUE_INVALID"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldRejectRepeatedReviewResolution() throws Exception {
|
||||
SeededOrderTask seeded = seedReviewOrderTask(
|
||||
HOTEL_ID,
|
||||
"mail-v4-command-review-repeat-001",
|
||||
Instant.parse("2026-07-19T01:24:30Z"),
|
||||
990000000000070006L,
|
||||
ReservationV4CardStatus.PENDING_CONFIRM.name(),
|
||||
ReservationV4CardStatus.REVIEW_REQUIRED.name());
|
||||
confirmBasicCard(seeded);
|
||||
resolveBusinessReviewCard(seeded);
|
||||
|
||||
performAuthorized(mockMvc, adminToken(), post(
|
||||
"/api/reservation/order-tasks/{orderTaskId}/cards/{cardId}/review-resolution",
|
||||
seeded.orderTask().id(),
|
||||
seeded.businessCard().id())
|
||||
.contentType(MediaType.APPLICATION_JSON)
|
||||
.content("""
|
||||
{
|
||||
"version": 1,
|
||||
"field_overrides": [
|
||||
{"field_pointer": "/business_fields/room_items/0/pms_room_type_code", "value": "RM3"}
|
||||
]
|
||||
}
|
||||
"""))
|
||||
.andExpect(status().isConflict())
|
||||
.andExpect(jsonPath("$.error_code").value("V4_CARD_ALREADY_CONFIRMED"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldRejectCardConfirmWhenPriorOrderTaskIsOpen() throws Exception {
|
||||
Long sharedOrderId = 990000000000040001L;
|
||||
@@ -360,6 +641,24 @@ class ReservationV4CommandControllerTest {
|
||||
"""))
|
||||
.andExpect(status().isForbidden())
|
||||
.andExpect(jsonPath("$.error_code").value("FRONTEND_PERMISSION_DENIED"));
|
||||
|
||||
SeededOrderTask reviewSeeded = seedReviewOrderTask(
|
||||
HOTEL_ID,
|
||||
"mail-v4-command-no-permission-review-001",
|
||||
Instant.parse("2026-07-19T01:42:00Z"),
|
||||
990000000000070007L,
|
||||
ReservationV4CardStatus.REVIEW_REQUIRED.name(),
|
||||
ReservationV4CardStatus.PENDING_CONFIRM.name());
|
||||
performAuthorized(mockMvc, noPermissionToken(), post(
|
||||
"/api/reservation/order-tasks/{orderTaskId}/cards/{cardId}/review-resolution",
|
||||
reviewSeeded.orderTask().id(),
|
||||
reviewSeeded.basicCard().id())
|
||||
.contentType(MediaType.APPLICATION_JSON)
|
||||
.content("""
|
||||
{"version": 0, "field_overrides": [{"field_pointer": "/basic_information/account_code", "value": "QBD_TRAVEL"}]}
|
||||
"""))
|
||||
.andExpect(status().isForbidden())
|
||||
.andExpect(jsonPath("$.error_code").value("FRONTEND_PERMISSION_DENIED"));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -391,6 +690,24 @@ class ReservationV4CommandControllerTest {
|
||||
"""))
|
||||
.andExpect(status().isForbidden())
|
||||
.andExpect(jsonPath("$.error_code").value("HOTEL_ACCESS_DENIED"));
|
||||
|
||||
SeededOrderTask reviewSeeded = seedReviewOrderTask(
|
||||
OTHER_HOTEL_ID,
|
||||
"mail-v4-command-cross-hotel-review-001",
|
||||
Instant.parse("2026-07-19T01:52:00Z"),
|
||||
990000000000070008L,
|
||||
ReservationV4CardStatus.REVIEW_REQUIRED.name(),
|
||||
ReservationV4CardStatus.PENDING_CONFIRM.name());
|
||||
performAuthorized(mockMvc, adminToken(), post(
|
||||
"/api/reservation/order-tasks/{orderTaskId}/cards/{cardId}/review-resolution",
|
||||
reviewSeeded.orderTask().id(),
|
||||
reviewSeeded.basicCard().id())
|
||||
.contentType(MediaType.APPLICATION_JSON)
|
||||
.content("""
|
||||
{"version": 0, "field_overrides": [{"field_pointer": "/basic_information/account_code", "value": "QBD_TRAVEL"}]}
|
||||
"""))
|
||||
.andExpect(status().isForbidden())
|
||||
.andExpect(jsonPath("$.error_code").value("HOTEL_ACCESS_DENIED"));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -427,6 +744,23 @@ class ReservationV4CommandControllerTest {
|
||||
.andExpect(status().isOk());
|
||||
}
|
||||
|
||||
private void resolveBusinessReviewCard(SeededOrderTask seeded) throws Exception {
|
||||
performAuthorized(mockMvc, adminToken(), post(
|
||||
"/api/reservation/order-tasks/{orderTaskId}/cards/{cardId}/review-resolution",
|
||||
seeded.orderTask().id(),
|
||||
seeded.businessCard().id())
|
||||
.contentType(MediaType.APPLICATION_JSON)
|
||||
.content("""
|
||||
{
|
||||
"version": 0,
|
||||
"field_overrides": [
|
||||
{"field_pointer": "/business_fields/room_items/0/pms_room_type_code", "value": "RM2"}
|
||||
]
|
||||
}
|
||||
"""))
|
||||
.andExpect(status().isOk());
|
||||
}
|
||||
|
||||
private SeededOrderTask seedOrderTask(String hotelId, String externalMessageId, Instant receivedAt) {
|
||||
return seedOrderTask(hotelId, externalMessageId, receivedAt, null);
|
||||
}
|
||||
@@ -474,6 +808,77 @@ class ReservationV4CommandControllerTest {
|
||||
return new SeededOrderTask(orderTask, sourceCard, basicCard, businessCard);
|
||||
}
|
||||
|
||||
private SeededOrderTask seedReviewOrderTask(
|
||||
String hotelId,
|
||||
String externalMessageId,
|
||||
Instant receivedAt,
|
||||
Long orderId,
|
||||
String basicStatus,
|
||||
String businessStatus) {
|
||||
return seedReviewOrderTask(
|
||||
hotelId,
|
||||
externalMessageId,
|
||||
receivedAt,
|
||||
orderId,
|
||||
orderId == null
|
||||
? ReservationV4TargetResolutionStatus.UNRESOLVED.name()
|
||||
: ReservationV4TargetResolutionStatus.RESOLVED.name(),
|
||||
basicStatus,
|
||||
businessStatus);
|
||||
}
|
||||
|
||||
private SeededOrderTask seedReviewOrderTask(
|
||||
String hotelId,
|
||||
String externalMessageId,
|
||||
Instant receivedAt,
|
||||
Long orderId,
|
||||
String targetResolutionStatus,
|
||||
String basicStatus,
|
||||
String businessStatus) {
|
||||
SourceMessageCaptureResult source = captureSourceMessage(
|
||||
hotelId,
|
||||
externalMessageId,
|
||||
"V4 Command Review",
|
||||
receivedAt);
|
||||
LocalDateTime now = LocalDateTime.ofInstant(receivedAt.plusSeconds(10), ZoneOffset.UTC);
|
||||
ReservationV4OrderTaskSnapshot orderTask = workflowRepository.findOrCreateOrderTask(new ReservationV4OrderTaskDraft(
|
||||
hotelId,
|
||||
source.inboxId(),
|
||||
990000000000060001L + Math.abs(externalMessageId.hashCode()),
|
||||
"order-review-" + externalMessageId,
|
||||
1,
|
||||
orderId,
|
||||
"GROUP",
|
||||
"GROUP_CODE",
|
||||
"GRP-V4-REVIEW-001",
|
||||
targetResolutionStatus,
|
||||
ReservationV4OrderTaskStatus.OPEN.name(),
|
||||
LocalDateTime.ofInstant(receivedAt, ZoneOffset.UTC),
|
||||
now));
|
||||
ReservationV4TaskCardSnapshot sourceCard = insertCard(orderTask, hotelId,
|
||||
ReservationV4CardType.SOURCE_MESSAGE_DISPLAY.name(), null, 0, 10,
|
||||
ReservationV4CardStatus.READONLY.name(), null, """
|
||||
{"card_type":"SOURCE_MESSAGE_DISPLAY","source_message":{"subject":"V4 Command Review"}}
|
||||
""");
|
||||
ReservationV4TaskCardSnapshot basicCard = insertCard(orderTask, hotelId,
|
||||
ReservationV4CardType.BASIC_INFORMATION.name(), null, 0, 20,
|
||||
basicStatus, reviewStatusFor(basicStatus), """
|
||||
{"card_type":"BASIC_INFORMATION","order_ref":"ORDER-REVIEW","basic_information":{"account_code":null,"manual_review":true,"missing_fields":["/basic_information/account_code"]}}
|
||||
""");
|
||||
ReservationV4TaskCardSnapshot businessCard = insertCard(orderTask, hotelId,
|
||||
ReservationV4CardType.ROOM_INFORMATION.name(), "NEW_BOOKING", 1, 30,
|
||||
businessStatus, reviewStatusFor(businessStatus), """
|
||||
{"event_type":"NEW_BOOKING","route_code":"S01","business_fields":{"order_ref":"ORDER-REVIEW","event_type":"NEW_BOOKING","manual_review":true,"room_items":[{"room_type_code":"TWN","room_count":2,"pms_room_type_code":null}]}}
|
||||
""");
|
||||
return new SeededOrderTask(orderTask, sourceCard, basicCard, businessCard);
|
||||
}
|
||||
|
||||
private String reviewStatusFor(String cardStatus) {
|
||||
return ReservationV4CardStatus.REVIEW_REQUIRED.name().equals(cardStatus)
|
||||
? ReservationReviewStatus.PENDING.name()
|
||||
: null;
|
||||
}
|
||||
|
||||
private ReservationV4SourceNotificationSnapshot seedSourceNotification(
|
||||
String hotelId,
|
||||
String externalMessageId,
|
||||
@@ -570,6 +975,29 @@ class ReservationV4CommandControllerTest {
|
||||
org.assertj.core.api.Assertions.assertThat(count).isEqualTo(expectedCount);
|
||||
}
|
||||
|
||||
private void seedReservationOrder(String hotelId, Long orderId) {
|
||||
LocalDateTime now = LocalDateTime.now(ZoneOffset.UTC);
|
||||
jdbcTemplate.update(
|
||||
"""
|
||||
INSERT INTO workflow_reservation_order
|
||||
(id, hotel_id, order_key_type, order_business_key, active_business_key,
|
||||
temporary_order_code, order_status, order_visibility, business_key_source,
|
||||
display_name, source_message_id, latest_activity_at, version, created_at, updated_at)
|
||||
VALUES
|
||||
(?, ?, 'GROUP_CODE', ?, ?, ?, 'ACTIVE', 'VISIBLE', 'USER_CONFIRMED',
|
||||
?, 0, ?, 0, ?, ?)
|
||||
""",
|
||||
orderId,
|
||||
hotelId,
|
||||
"GRP-ORDER-" + orderId,
|
||||
"GRP-ORDER-" + orderId,
|
||||
"TMP-ORDER-" + orderId,
|
||||
"订单 " + orderId,
|
||||
now,
|
||||
now,
|
||||
now);
|
||||
}
|
||||
|
||||
private record SeededOrderTask(
|
||||
ReservationV4OrderTaskSnapshot orderTask,
|
||||
ReservationV4TaskCardSnapshot sourceCard,
|
||||
|
||||
@@ -251,7 +251,7 @@ class ReservationV4QueryControllerTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldNotExposeOrderTaskAsConfirmableWhenOnlyReviewCardsRemain() throws Exception {
|
||||
void shouldExposeReviewCardsAsReviewableButNotConfirmable() throws Exception {
|
||||
ReservationV4OrderTaskSnapshot orderTask = seedReviewRequiredOrderTask(
|
||||
"mail-v4-query-review-only-001",
|
||||
Instant.parse("2026-07-18T03:05:00Z"));
|
||||
@@ -259,12 +259,14 @@ class ReservationV4QueryControllerTest {
|
||||
performAuthorized(mockMvc, adminToken(), get("/api/reservation/order-tasks/{orderTaskId}", orderTask.id())
|
||||
.param("hotel_id", HOTEL_ID))
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(jsonPath("$.availability.read_only").value(true))
|
||||
.andExpect(jsonPath("$.availability.read_only").value(false))
|
||||
.andExpect(jsonPath("$.availability.confirmable").value(false))
|
||||
.andExpect(jsonPath("$.availability.readonly_reason_code").value("REVIEW_API_PENDING"))
|
||||
.andExpect(jsonPath("$.availability.reviewable").value(true))
|
||||
.andExpect(jsonPath("$.availability.readonly_reason_code").value("PROCESSABLE"))
|
||||
.andExpect(jsonPath("$.basic_information_card.availability.confirmable").value(false))
|
||||
.andExpect(jsonPath("$.basic_information_card.availability.reviewable").value(true))
|
||||
.andExpect(jsonPath("$.basic_information_card.availability.readonly_reason_code")
|
||||
.value("REVIEW_API_PENDING"));
|
||||
.value("PROCESSABLE"));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
Reference in New Issue
Block a user