96 lines
2.8 KiB
TypeScript
96 lines
2.8 KiB
TypeScript
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);
|
|
});
|
|
});
|