mirror of
https://github.com/sinanyuntu/trade-message-center.git
synced 2026-09-17 13:22:11 +08:00
118 lines
4.0 KiB
TypeScript
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"]);
|
|
});
|