Files
crawler-plugin/backend-java/src/test/java/com/nanri/aiimage/config/PythonContractFixtureTest.java
T

116 lines
4.8 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package com.nanri.aiimage.config;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.junit.jupiter.api.Test;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
/**
* task-202Python-contract 夹具准备契约。
* 校验 python-contract/*.json 存在、为合法 JSON、顶层字段与真实 DTO 对齐、已脱敏(无真实凭据)、
* 可复现;字段来源与脱敏口径见同目录 README.md。
*/
class PythonContractFixtureTest {
private static final Path DIR = Path.of(System.getProperty("user.dir"),
"src/test/resources/python-contract");
private static final ObjectMapper MAPPER = new ObjectMapper();
private JsonNode json(String name) throws IOException {
return MAPPER.readTree(Files.readAllBytes(DIR.resolve(name)));
}
private static Set<String> keys(JsonNode node) {
List<String> names = new ArrayList<>();
node.fieldNames().forEachRemaining(names::add);
return Set.copyOf(names);
}
@Test
void fixtureResultRequestExists() throws IOException {
JsonNode n = json("result.request.json");
assertEquals("sim-20260905-0001", n.path("submissionId").asText());
}
@Test
void fixtureItemsExists() throws IOException {
JsonNode n = json("items.response.json");
assertTrue(n.path("items").isArray() && n.path("items").size() >= 1);
}
@Test
void fixtureParsedPayloadExists() throws IOException {
JsonNode n = json("parsed_payload.response.json");
assertTrue(n.has("allItems") && n.has("groups") && n.has("items"));
}
@Test
void fixtureHeartbeatExists() throws IOException {
JsonNode req = json("heartbeat.request.json");
JsonNode resp = json("heartbeat.response.json");
assertTrue(req.has("moduleType") && req.has("phase"));
assertTrue(resp.has("alive") && resp.has("status"));
}
@Test
void fixtureSanitizedNoRealCredentials() throws IOException {
String all = String.join("\n", List.of(
Files.readString(DIR.resolve("parsed_payload.response.json")),
Files.readString(DIR.resolve("result.request.json"))));
assertFalse(all.contains("WTFrb"), "不得出现真实 DB/内部凭据");
assertFalse(all.toLowerCase().contains("bearer "), "不得出现真实 token");
JsonNode parsed = json("parsed_payload.response.json");
assertEquals("<redacted>", parsed.path("apiKey").asText(), "apiKey 必须占位");
assertFalse(parsed.path("aiPrompt").asText().toLowerCase().contains("真实"),
"aiPrompt 不得含真实内容");
}
@Test
void fixtureShapeValidJson() throws IOException {
for (String name : List.of("heartbeat.request.json", "heartbeat.response.json",
"items.response.json", "result.request.json", "parsed_payload.response.json")) {
JsonNode n = json(name);
assertTrue(n.isContainerNode(), name + " 应为 JSON 对象/数组");
}
}
@Test
void fixtureFieldsDocumentedByReadme() throws IOException {
String readme = Files.readString(DIR.resolve("README.md"));
assertTrue(readme.contains("TaskHeartbeatRequest") && readme.contains("CollectDataItemsPageVo")
&& readme.contains("SimilarAsinSubmitResultRequest")
&& readme.contains("SimilarAsinParsedPayloadDto"), "README 应说明字段来源");
assertTrue(readme.contains("脱敏"), "README 应说明脱敏");
}
@Test
void fixtureHeartbeatTopKeysMatchDto() throws IOException {
assertEquals(Set.of("moduleType", "phase", "current", "total", "collectStage",
"currentKeyword", "searchCurrentPage", "searchTotalPages",
"detailProcessedAsins", "detailTotalAsins"),
keys(json("heartbeat.request.json")), "心跳请求顶层字段应与 TaskHeartbeatRequest 对齐");
assertEquals(Set.of("alive", "status", "moduleType", "message"),
keys(json("heartbeat.response.json")), "心跳响应应与 TaskHeartbeatVo 对齐");
}
@Test
void fixtureReproducibleStable() throws IOException {
for (String name : List.of("heartbeat.request.json", "items.response.json",
"result.request.json", "parsed_payload.response.json")) {
String a = Files.readString(DIR.resolve(name));
String b = Files.readString(DIR.resolve(name));
assertEquals(a, b, name + " 应可复现");
}
}
}