test(api): 补齐天猫恢复审计与指标回归

This commit is contained in:
2026-04-03 14:07:16 +08:00
parent f8085888c1
commit 8c4d057202
2 changed files with 112 additions and 3 deletions
@@ -903,6 +903,115 @@ describe("Dual-platform live loop", () => {
await app.close();
});
it("records recovery audit entries and retry metrics when a SearchBlocked Tmall platform recovers", async () => {
let allowTmallSearch = false;
const tmallLiveService = createTmallLiveServiceStub({
async previewSearch(query) {
if (!allowTmallSearch) {
const error = new Error("Tmall search session appears invalid.") as Error & {
statusCode: number;
};
error.statusCode = 409;
throw error;
}
return {
query,
source: "html",
candidateCount: 1,
candidates: [
{
candidateId: "tmall-934454505228",
platform: "tmall",
title: "Apple iPhone 15",
price: 4399,
priceLabel: "CNY 4399",
storeName: "Apple 官方旗舰店",
productUrl: "https://detail.tmall.com/item.htm?id=934454505228",
imageUrl: "https://img.alicdn.com/example.jpg",
salesHint: "已售 70万+",
specLabel: "128GB",
highlights: ["天猫", "官方旗舰店"]
}
]
};
}
});
const app = createServer({
jdLiveService: createJdLiveServiceStub(),
tmallLiveService
});
await app.ready();
await importDualLiveSessions(app);
const createdTask = await createTask(app, "iPhone 15");
expect(
createdTask.platformRuns.find((run: { platform: string }) => run.platform === "tmall")
).toMatchObject({
platform: "tmall",
status: "SearchBlocked"
});
allowTmallSearch = true;
const retryResponse = await app.inject({
method: "POST",
url: `/api/tasks/${createdTask.taskId}/platforms/tmall/retry`
});
expect(retryResponse.statusCode).toBe(200);
expect(
retryResponse
.json()
.task.platformRuns.find((run: { platform: string }) => run.platform === "tmall")
).toMatchObject({
platform: "tmall",
status: "AwaitingSelection"
});
const auditResponse = await app.inject({
method: "GET",
url: `/api/tasks/${createdTask.taskId}/audit`
});
expect(auditResponse.statusCode).toBe(200);
expect(auditResponse.json().audit).toEqual(
expect.arrayContaining([
expect.objectContaining({
action: "platform.retry_started",
platform: "tmall"
}),
expect.objectContaining({
action: "task.recovery_completed",
platform: "tmall"
}),
expect.objectContaining({
action: "platform.retry_completed",
platform: "tmall"
})
])
);
const overviewResponse = await app.inject({
method: "GET",
url: "/api/observability/overview"
});
expect(overviewResponse.statusCode).toBe(200);
expect(
overviewResponse
.json()
.overview.platformRuns.find((metric: { platform: string }) => metric.platform === "tmall")
).toMatchObject({
platform: "tmall",
retryCount: 1,
recoveryCount: 1
});
expect(overviewResponse.json().overview.audits.recoveryActions).toBe(3);
await app.close();
});
it("keeps the current report version when a blocked Tmall retry does not recover", async () => {
const tmallLiveService = createTmallLiveServiceStub({
async previewProduct() {