Files
mnote/wolai-frontend/src/lib/documents/document-record.test.ts
T

214 lines
6.1 KiB
TypeScript
Raw Normal View History

2026-04-14 13:22:29 +08:00
import { describe, expect, it } from "vitest";
import {
compareDocumentCanonicalOrder,
getCanonicalDocumentByBusinessId,
getCanonicalParentDocumentId,
2026-04-26 04:29:23 +08:00
pickCanonicalDocumentRecordsByBusinessId,
2026-04-14 13:22:29 +08:00
pickCanonicalDocumentRecord,
} from "../../../convex/_utils/documentRecord";
describe("pickCanonicalDocumentRecord", () => {
it("同一 business id 出现重复记录时优先选择最新未删除记录", () => {
const selected = pickCanonicalDocumentRecord([
{
_id: "doc_old",
deleted_at: null,
created_at: "2026-04-14T00:00:00.000Z",
updated_at: "2026-04-14T00:00:01.000Z",
},
{
_id: "doc_deleted",
deleted_at: "2026-04-14T00:00:03.000Z",
created_at: "2026-04-14T00:00:02.000Z",
updated_at: "2026-04-14T00:00:03.000Z",
},
{
_id: "doc_new",
deleted_at: null,
created_at: "2026-04-14T00:00:02.000Z",
updated_at: "2026-04-14T00:00:04.000Z",
},
]);
expect(selected?._id).toBe("doc_new");
});
it("全部已删除时仍稳定选择最新记录,避免 first() 命中漂移", () => {
const selected = pickCanonicalDocumentRecord([
{
_id: "doc_deleted_old",
deleted_at: "2026-04-14T00:00:01.000Z",
created_at: "2026-04-14T00:00:00.000Z",
updated_at: "2026-04-14T00:00:01.000Z",
},
{
_id: "doc_deleted_new",
deleted_at: "2026-04-14T00:00:03.000Z",
created_at: "2026-04-14T00:00:02.000Z",
updated_at: "2026-04-14T00:00:03.000Z",
},
]);
expect(selected?._id).toBe("doc_deleted_new");
});
it("时间戳相同时用 _id 稳定打破平手,避免 collect 后结果不稳定", () => {
const selected = pickCanonicalDocumentRecord([
{
_id: "doc_b",
deleted_at: null,
created_at: "2026-04-14T00:00:00.000Z",
updated_at: "2026-04-14T00:00:00.000Z",
},
{
_id: "doc_a",
deleted_at: null,
created_at: "2026-04-14T00:00:00.000Z",
updated_at: "2026-04-14T00:00:00.000Z",
},
]);
expect(selected?._id).toBe("doc_a");
});
});
describe("compareDocumentCanonicalOrder", () => {
it("未删除记录始终排在已删除记录前面,供页面权限/内容读链复用", () => {
const records = [
{
_id: "deleted",
deleted_at: "2026-04-14T00:00:03.000Z",
created_at: "2026-04-14T00:00:02.000Z",
updated_at: "2026-04-14T00:00:03.000Z",
},
{
_id: "alive",
deleted_at: null,
created_at: "2026-04-14T00:00:01.000Z",
updated_at: "2026-04-14T00:00:01.000Z",
},
];
const sorted = [...records].sort(compareDocumentCanonicalOrder);
expect(sorted.map((record) => record._id)).toEqual(["alive", "deleted"]);
});
});
describe("canonical document helper", () => {
const createCtx = (records: Array<Record<string, unknown>>) => ({
db: {
query: () => ({
withIndex: () => ({
collect: async () => records,
}),
}),
},
});
it("按 business id 查询时返回 canonical 记录,避免高风险读链命中旧记录", async () => {
const ctx = createCtx([
{
_id: "doc_old",
id: "doc_1",
parent_id: "parent_old",
deleted_at: null,
created_at: "2026-04-14T00:00:00.000Z",
updated_at: "2026-04-14T00:00:01.000Z",
},
{
_id: "doc_new",
id: "doc_1",
parent_id: "parent_new",
deleted_at: null,
created_at: "2026-04-14T00:00:02.000Z",
updated_at: "2026-04-14T00:00:03.000Z",
},
]);
const doc = await getCanonicalDocumentByBusinessId<any>(ctx, "doc_1");
expect(doc?._id).toBe("doc_new");
});
it("父链辅助函数返回 canonical 父页面 id,供共享/评论祖先扫描复用", async () => {
const ctx = createCtx([
{
_id: "doc_old",
id: "doc_1",
parent_id: "parent_old",
deleted_at: null,
created_at: "2026-04-14T00:00:00.000Z",
updated_at: "2026-04-14T00:00:01.000Z",
},
{
_id: "doc_new",
id: "doc_1",
parent_id: "parent_new",
deleted_at: null,
created_at: "2026-04-14T00:00:02.000Z",
updated_at: "2026-04-14T00:00:03.000Z",
},
]);
const parentId = await getCanonicalParentDocumentId(ctx, "doc_1");
expect(parentId).toBe("parent_new");
});
it("父链辅助函数命中已删除旧记录时仍回退到最新未删除父级,供收藏祖先权限复用", async () => {
const ctx = createCtx([
{
_id: "doc_deleted",
id: "doc_2",
parent_id: "parent_deleted",
deleted_at: "2026-04-14T00:00:04.000Z",
created_at: "2026-04-14T00:00:00.000Z",
updated_at: "2026-04-14T00:00:04.000Z",
},
{
_id: "doc_alive",
id: "doc_2",
parent_id: "parent_alive",
deleted_at: null,
created_at: "2026-04-14T00:00:01.000Z",
updated_at: "2026-04-14T00:00:03.000Z",
},
]);
const parentId = await getCanonicalParentDocumentId(ctx, "doc_2");
expect(parentId).toBe("parent_alive");
});
});
2026-04-26 04:29:23 +08:00
describe("pickCanonicalDocumentRecordsByBusinessId", () => {
it("同一 workspace 扫描结果里 business id 重复时应先折叠成 canonical 记录,供树命令写链复用", () => {
const records = pickCanonicalDocumentRecordsByBusinessId([
{
_id: "doc_old",
id: "doc_1",
parent_id: "parent_old",
deleted_at: null,
created_at: "2026-04-14T00:00:00.000Z",
updated_at: "2026-04-14T00:00:01.000Z",
},
{
_id: "doc_new",
id: "doc_1",
parent_id: "parent_new",
deleted_at: null,
created_at: "2026-04-14T00:00:02.000Z",
updated_at: "2026-04-14T00:00:03.000Z",
},
{
_id: "doc_2",
id: "doc_2",
parent_id: null,
deleted_at: null,
created_at: "2026-04-14T00:00:04.000Z",
updated_at: "2026-04-14T00:00:05.000Z",
},
]);
expect(records).toHaveLength(2);
expect(records.map((record) => record._id)).toEqual(["doc_new", "doc_2"]);
});
});