task-204: /items 分页语义契约回放(env-gated,真实服务:造 COLLECT_DATA 任务+5 行 item → page/pageSize/count/total/totalPages/items、越界空页、缺省 50、rowIndex 升序)+ 已本地真跑
This commit is contained in:
+93
@@ -0,0 +1,93 @@
|
||||
package com.nanri.aiimage.modules.collectdata.service;
|
||||
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import org.junit.jupiter.api.Assumptions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.net.URI;
|
||||
import java.net.http.HttpClient;
|
||||
import java.net.http.HttpRequest;
|
||||
import java.net.http.HttpResponse;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.sql.Connection;
|
||||
import java.sql.DriverManager;
|
||||
import java.sql.Statement;
|
||||
import java.time.Duration;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
/**
|
||||
* task-204:/items 分页语义契约回放(真实服务,env-gated)。
|
||||
*
|
||||
* 依赖运行应用与可写副本库:CONTRACT_BASE_URL + CONTRACT_DB_*。未设则跳过(CI 绿)。
|
||||
* 流程:造 COLLECT_DATA RUNNING 任务 + 5 行 biz_collect_data_item → GET items 各分页参数,
|
||||
* 断言 page/pageSize/count/total/totalPages/items 与缺省/越界/空页语义(与 Python Worker 拉取约定一致)。
|
||||
*/
|
||||
class CollectDataItemsContractReplayTest {
|
||||
|
||||
private static final long TASK_ID = 9000002L;
|
||||
private static final ObjectMapper MAPPER = new ObjectMapper();
|
||||
|
||||
@Test
|
||||
void itemsPaginationSemantics() throws Exception {
|
||||
String base = System.getenv("CONTRACT_BASE_URL");
|
||||
String dbUrl = System.getenv("CONTRACT_DB_URL");
|
||||
String dbUser = System.getenv("CONTRACT_DB_USER");
|
||||
String dbPass = System.getenv("CONTRACT_DB_PASSWORD");
|
||||
Assumptions.assumeTrue(base != null && dbUrl != null && dbUser != null, "未设 CONTRACT_* 跳过");
|
||||
|
||||
seed(dbUrl, dbUser, dbPass, 5);
|
||||
HttpClient client = HttpClient.newBuilder().connectTimeout(Duration.ofSeconds(10)).build();
|
||||
|
||||
JsonNode page1 = getPage(client, base, 1, 2);
|
||||
assertTrue(page1.path("success").asBoolean(), page1.toString());
|
||||
JsonNode data = page1.path("data");
|
||||
assertEquals(1, data.path("page").asInt());
|
||||
assertEquals(2, data.path("pageSize").asInt());
|
||||
assertEquals(5, data.path("total").asLong());
|
||||
assertEquals(3, data.path("totalPages").asInt());
|
||||
assertEquals(2, data.path("count").asInt());
|
||||
assertEquals(2, data.path("items").size());
|
||||
assertEquals(1, data.path("items").get(0).path("rowIndex").asInt(), "应按 rowIndex 升序");
|
||||
|
||||
JsonNode page3 = getPage(client, base, 3, 2);
|
||||
assertEquals(1, page3.path("data").path("items").size(), "page3 应剩 1 行");
|
||||
assertEquals(5, page3.path("data").path("items").get(0).path("rowIndex").asInt());
|
||||
|
||||
JsonNode beyond = getPage(client, base, 99, 2);
|
||||
assertEquals(0, beyond.path("data").path("items").size(), "越界页应空且成功");
|
||||
assertEquals(5, beyond.path("data").path("total").asLong());
|
||||
|
||||
JsonNode defaults = getPage(client, base, 1, 50);
|
||||
JsonNode d = defaults.path("data");
|
||||
assertEquals(1, d.path("page").asInt());
|
||||
assertEquals(50, d.path("pageSize").asInt());
|
||||
assertEquals(1, d.path("totalPages").asInt(), "5 行 50 一页应 1 页");
|
||||
assertEquals(5, d.path("count").asInt());
|
||||
}
|
||||
|
||||
private static JsonNode getPage(HttpClient client, String base, int page, int size) throws Exception {
|
||||
String url = base + "/api/collect-data/tasks/" + TASK_ID + "/items?user_id=1&page=" + page + "&page_size=" + size;
|
||||
HttpResponse<String> resp = client.send(HttpRequest.newBuilder(URI.create(url)).GET()
|
||||
.timeout(Duration.ofSeconds(15)).build(),
|
||||
HttpResponse.BodyHandlers.ofString(StandardCharsets.UTF_8));
|
||||
assertEquals(200, resp.statusCode(), url);
|
||||
return MAPPER.readTree(resp.body());
|
||||
}
|
||||
|
||||
private static void seed(String dbUrl, String user, String pass, int rows) throws Exception {
|
||||
try (Connection c = DriverManager.getConnection(dbUrl, user, pass);
|
||||
Statement s = c.createStatement()) {
|
||||
s.executeUpdate("INSERT INTO biz_file_task (id,task_no,module_type,task_mode,status,created_at,updated_at,user_id,owner_instance_id) "
|
||||
+ "VALUES (" + TASK_ID + ",'CD-REPLAY-" + TASK_ID + "','COLLECT_DATA','collect','RUNNING',NOW(),NOW(),1,'local-smoke') "
|
||||
+ "ON DUPLICATE KEY UPDATE module_type='COLLECT_DATA',status='RUNNING',user_id=1");
|
||||
s.executeUpdate("DELETE FROM biz_collect_data_item WHERE task_id=" + TASK_ID);
|
||||
for (int i = 1; i <= rows; i++) {
|
||||
s.executeUpdate("INSERT INTO biz_collect_data_item (task_id,row_index,keyword,status_value,created_at) VALUES ("
|
||||
+ TASK_ID + "," + i + ",'keyword-" + i + "','PENDING',NOW())");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user