dreame-action/test/idempotency.test.ts

96 lines
2.8 KiB
TypeScript
Raw Permalink Normal View History

2026-06-19 00:53:13 +08:00
import { describe, expect, test } from "vitest";
import { runActivityCheck } from "../app/services/activity.server";
import type { ActivityDeps } from "../app/services/activity.server";
function makeDeps(overrides: Partial<ActivityDeps> = {}): ActivityDeps {
let pushed = false;
return {
nowMs: () => 1776901800000,
uuid: () => "00000000-0000-4000-8000-000000000000",
getOrder: async () => ({
id: "gid://shopify/Order/123",
legacyId: "123",
orderNumber: "#1001",
email: "customer@example.com",
customerId: "99999",
currency: "USD",
shopDomain: "demo.myshopify.com",
}),
getConfig: async () => ({
activityId: 12,
apiAppId: "app-id",
apiSecret: "secret",
statusApiUrl: "https://third.example/status",
pushApiUrl: "https://third.example/push",
redirectUrl: "https://activity.example.com",
buttonText: { en: "Claim Your Reward", "zh-CN": "领取奖励" },
shop: "configured-shop",
}),
findSuccess: async () =>
pushed
? {
eventId: "00000000-0000-4000-8000-000000000000",
redirectUrl: "https://activity.example.com",
}
: null,
recordSuccess: async () => {
pushed = true;
},
log: async () => undefined,
callStatus: async () => ({
httpOk: true,
status: 200,
body: { code: 0, data: { status: true, trigger: ["card_add"] } },
requestBody: '{"activity_id":12}',
responseBody: '{"code":0,"data":{"status":true}}',
}),
callPush: async () => ({
httpOk: true,
status: 200,
body: { code: 0 },
requestBody: "{}",
responseBody: '{"code":0}',
}),
...overrides,
};
}
describe("activity idempotency", () => {
test("does not call push twice for the same order and still returns button data", async () => {
let pushCalls = 0;
const deps = makeDeps({
callPush: async () => {
pushCalls += 1;
return {
httpOk: true,
status: 200,
body: { code: 0 },
requestBody: "{}",
responseBody: '{"code":0}',
};
},
});
const first = await runActivityCheck(
{ shop: "demo.myshopify.com", orderId: "gid://shopify/Order/123", orderNumber: "#1001", locale: "zh-CN" },
deps,
);
const second = await runActivityCheck(
{ shop: "demo.myshopify.com", orderId: "gid://shopify/Order/123", orderNumber: "#1001", locale: "zh-CN" },
deps,
);
expect(first).toEqual({
success: true,
redirectUrl: "https://activity.example.com",
buttonText: "领取奖励",
});
expect(second).toEqual({
success: true,
redirectUrl: "https://activity.example.com",
buttonText: "领取奖励",
});
expect(pushCalls).toBe(1);
});
});