实现前端演示数据受控生成接口

This commit is contained in:
andy
2026-07-08 19:09:17 +08:00
parent 3c1649a567
commit c83935a26c
17 changed files with 1271 additions and 16 deletions

View File

@@ -0,0 +1,125 @@
package cn.nianxx.thhotel.workflows.reservation.control;
import static org.hamcrest.Matchers.greaterThanOrEqualTo;
import static org.hamcrest.Matchers.hasSize;
import static org.hamcrest.Matchers.not;
import static org.hamcrest.Matchers.blankOrNullString;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import cn.nianxx.thhotel.ThHotelApplication;
import com.jayway.jsonpath.JsonPath;
import java.util.List;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.http.MediaType;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.MvcResult;
@SpringBootTest(
classes = ThHotelApplication.class,
properties = {
"reservation.demo-data.enabled=true",
"reservation.demo-data.access-key=test-demo-data-key"
})
@AutoConfigureMockMvc
@ActiveProfiles("test")
class ReservationDemoDataControllerTest {
private static final String HOTEL_ID = "HOTEL-TEST";
private static final String ACCESS_KEY = "test-demo-data-key";
@Autowired
private MockMvc mockMvc;
@Test
void shouldRejectDemoDataSeedWhenAccessKeyMissing() throws Exception {
mockMvc.perform(post("/api/system/reservation/demo-data")
.contentType(MediaType.APPLICATION_JSON)
.content("""
{
"hotel_id": "HOTEL-TEST"
}
"""))
.andExpect(status().isForbidden());
}
@Test
void shouldSeedFrontendDemoDataAndMakeItQueryable() throws Exception {
MvcResult seedResult = mockMvc.perform(post("/api/system/reservation/demo-data")
.header("X-TH-Hotel-Demo-Data-Key", ACCESS_KEY)
.contentType(MediaType.APPLICATION_JSON)
.content("""
{
"hotel_id": "HOTEL-TEST",
"run_label": "controller-test"
}
"""))
.andExpect(status().isCreated())
.andExpect(jsonPath("$.demo_run_id", not(blankOrNullString())))
.andExpect(jsonPath("$.hotel_id").value(HOTEL_ID))
.andExpect(jsonPath("$.source_messages", hasSize(greaterThanOrEqualTo(5))))
.andExpect(jsonPath("$.orders", hasSize(greaterThanOrEqualTo(5))))
.andExpect(jsonPath("$.tasks", hasSize(greaterThanOrEqualTo(6))))
.andExpect(jsonPath("$.entrypoints.task_list_url", not(blankOrNullString())))
.andReturn();
String response = seedResult.getResponse().getContentAsString();
String demoRunId = JsonPath.read(response, "$.demo_run_id");
String queueSourceMessageId = first(response, "$.source_messages[?(@.scenario_code=='QUEUE_BLOCKED')].source_message_id");
String queueOrderId = first(response, "$.orders[?(@.scenario_code=='QUEUE_BLOCKED')].order_id");
String blockedTaskId = first(response, "$.tasks[?(@.scenario_code=='QUEUE_BLOCKED')].task_id");
String failedTaskId = first(response, "$.tasks[?(@.scenario_code=='OPERA_FAILED')].task_id");
mockMvc.perform(get("/api/reservation/tasks")
.param("hotel_id", HOTEL_ID)
.param("keyword", demoRunId)
.param("page_num", "1")
.param("page_size", "20"))
.andExpect(status().isOk())
.andExpect(jsonPath("$.items", hasSize(greaterThanOrEqualTo(5))));
mockMvc.perform(get("/api/reservation/orders")
.param("hotel_id", HOTEL_ID)
.param("keyword", demoRunId)
.param("page_num", "1")
.param("page_size", "20"))
.andExpect(status().isOk())
.andExpect(jsonPath("$.items", hasSize(greaterThanOrEqualTo(5))));
mockMvc.perform(get("/api/reservation/orders/{orderId}", queueOrderId)
.param("hotel_id", HOTEL_ID)
.param("include_tasks", "true")
.param("include_source_summary", "true"))
.andExpect(status().isOk())
.andExpect(jsonPath("$.tasks", hasSize(greaterThanOrEqualTo(2))))
.andExpect(jsonPath("$.tasks[1].readonly_reason_code").value("PREVIOUS_TASK_NOT_FINISHED"));
mockMvc.perform(get("/api/reservation/tasks/{taskId}", blockedTaskId))
.andExpect(status().isOk())
.andExpect(jsonPath("$.availability.blocked").value(true))
.andExpect(jsonPath("$.availability.read_only").value(true))
.andExpect(jsonPath("$.availability.blocked_by_task_id", not(blankOrNullString())));
mockMvc.perform(get("/api/reservation/tasks/{taskId}", failedTaskId))
.andExpect(status().isOk())
.andExpect(jsonPath("$.opera_operations[0].operation_status").value("FAILED"))
.andExpect(jsonPath("$.opera_operations[0].attempt_count").value(1));
mockMvc.perform(get("/api/source-messages/{sourceMessageId}/conversation", queueSourceMessageId))
.andExpect(status().isOk())
.andExpect(jsonPath("$.messages", hasSize(greaterThanOrEqualTo(2))))
.andExpect(jsonPath("$.messages[0].html_sanitize_required").value(true))
.andExpect(jsonPath("$.messages[0].attachments", hasSize(greaterThanOrEqualTo(1))));
}
private String first(String json, String path) {
List<String> values = JsonPath.read(json, path);
return values.get(0);
}
}