Files
trade-message-center/apps/server/test/onetalk-rendered-card-repository.test.ts
T

118 lines
4.0 KiB
TypeScript

// 验证 rendered-card supplement 可独立于基础消息提交。
import assert from "node:assert/strict";
import test from "node:test";
import { createOneTalkRenderedCardContentFingerprint } from "@trade-message-center/onetalk-contract";
import { createOneTalkRenderedCardRepository } from "../src/onetalk/rendered-card-repository.ts";
const content = {
version: 1 as const,
status: "Paid",
total: "US $10.00",
image: "https://img.alicdn.com/card.jpg",
};
test("stores a rendered-card supplement when its base message is absent", async () => {
const inserted: unknown[] = [];
const selectResults = [[], []];
const transaction = {
select: () => ({
from: () => ({
where: () => ({
limit: () => {
const result = selectResults.shift();
return Object.assign(Promise.resolve(result), { for: () => result });
},
}),
}),
}),
insert: () => ({
values: async (value: unknown) => inserted.push(value),
}),
update: () => assert.fail("unexpected update"),
};
const database = {
transaction: async (run: (value: typeof transaction) => Promise<unknown>) =>
run(transaction),
};
const repository = createOneTalkRenderedCardRepository(database as never);
const result = await repository.store({
channelAccountId: "account-1",
observation: {
conversationId: "conversation-1",
messageId: "message-1",
content,
contentFingerprint: createOneTalkRenderedCardContentFingerprint(content),
observedAtMs: 100,
},
});
assert.deepEqual(result, { status: "accepted", renderedCardContent: content, message: null });
assert.deepEqual(inserted, [
{
channelAccountId: "account-1",
conversationId: "conversation-1",
messageId: "message-1",
renderedCardContent: content,
renderedCardContentFingerprint: createOneTalkRenderedCardContentFingerprint(content),
renderedCardObservedAtMs: 100,
},
]);
});
test("keeps the first supplement snapshot and only increments conflictCount for different content", async () => {
const updates: unknown[] = [];
const conflictingContent = { ...content, status: "Cancelled" };
const selectResults = [
[
{
channelAccountId: "account-1",
conversationId: "conversation-1",
messageId: "message-1",
renderedCardContent: content,
},
],
[],
];
const transaction = {
select: () => ({
from: () => ({
where: () => ({
limit: () => {
const result = selectResults.shift();
return Object.assign(Promise.resolve(result), { for: () => result });
},
}),
}),
}),
insert: () => assert.fail("unexpected insert"),
update: () => ({
set: (value: unknown) => ({
where: async () => updates.push(value),
}),
}),
};
const database = {
transaction: async (run: (value: typeof transaction) => Promise<unknown>) =>
run(transaction),
};
const repository = createOneTalkRenderedCardRepository(database as never);
const result = await repository.store({
channelAccountId: "account-1",
observation: {
conversationId: "conversation-1",
messageId: "message-1",
content: conflictingContent,
contentFingerprint: createOneTalkRenderedCardContentFingerprint(conflictingContent),
observedAtMs: 101,
},
});
assert.deepEqual(result, { status: "conflict", renderedCardContent: content, message: null });
assert.equal(updates.length, 1);
assert.deepEqual(Object.keys(updates[0] as object), ["conflictCount"]);
});