完成50%

This commit is contained in:
2026-07-23 08:23:59 +08:00
parent 9b0ad62df4
commit f1edc6b533
218 changed files with 24318 additions and 5514 deletions
+187
View File
@@ -0,0 +1,187 @@
"use strict";
const assert = require("assert");
const fs = require("fs");
const path = require("path");
const run = async () => {
const source = fs.readFileSync(
path.join(__dirname, "../data/mock.js"),
"utf8",
);
const contractSource = fs.readFileSync(
path.join(__dirname, "../utils/genealogy-contracts.js"),
"utf8",
);
const contractUrl = `data:text/javascript;base64,${Buffer.from(contractSource).toString("base64")}`;
const {
GENEALOGY_ACCESS_PRESET,
isGenealogyAccessPreset,
toApiGenealogyAccess,
fromApiGenealogyAccess,
} = await import(contractUrl);
assert.strictEqual(isGenealogyAccessPreset(GENEALOGY_ACCESS_PRESET.MEMBER_ONLY), true);
assert.strictEqual(isGenealogyAccessPreset(GENEALOGY_ACCESS_PRESET.PUBLIC_APPLY), true);
assert.strictEqual(isGenealogyAccessPreset("UNKNOWN"), false);
assert.strictEqual(isGenealogyAccessPreset(null), false);
assert.deepStrictEqual(toApiGenealogyAccess(GENEALOGY_ACCESS_PRESET.MEMBER_ONLY), {
visibility: "2",
joinMode: "0",
});
assert.deepStrictEqual(toApiGenealogyAccess(GENEALOGY_ACCESS_PRESET.PUBLIC_APPLY), {
visibility: "1",
joinMode: "1",
});
assert.strictEqual(fromApiGenealogyAccess({ visibility: "2", joinMode: "0" }), "MEMBER_ONLY");
assert.strictEqual(fromApiGenealogyAccess({ visibility: "1", joinMode: "1" }), "PUBLIC_APPLY");
assert.strictEqual(fromApiGenealogyAccess({ visibility: "1", joinMode: "2" }), null);
const moduleUrl = `data:text/javascript;base64,${Buffer.from(source.replace("../utils/genealogy-contracts.js", contractUrl)).toString("base64")}`;
const {
genealogies,
publicGenealogies,
createLocalGenealogyPreview,
updateLocalGenealogyPreview,
updateLocalGenealogyPreviewAncestor,
removeLocalGenealogyPreview,
findGenealogyFixture,
getGenealogyFixtureAccess,
isGenealogySearchVisible,
} = await import(moduleUrl);
assert(genealogies.every((item) => typeof item.id === "string"));
assert(publicGenealogies.every((item) => typeof item.id === "string"));
assert(
publicGenealogies.every((item) => !Object.hasOwn(item, "membership")),
"公开搜索投影不得携带成员权限字段",
);
for (const publicItem of publicGenealogies.filter((item) =>
["joined", "owned"].includes(item.relation),
)) {
const memberItem = genealogies.find((item) => item.id === publicItem.id);
assert(memberItem, `${publicItem.relation} 搜索结果必须对应真实成员家谱`);
assert.strictEqual(publicItem.name, memberItem.name, "同一 ID 的家谱名称必须一致");
assert.strictEqual(
getGenealogyFixtureAccess(publicItem.id).accessRole,
publicItem.relation === "owned" ? "owner" : "member",
);
}
assert.strictEqual(findGenealogyFixture("2003")?.name, "汤氏济宁宗谱");
assert.strictEqual(findGenealogyFixture("2001")?.accessPreset, "PUBLIC_APPLY");
for (const id of ["2003", "2004", "2005"]) {
assert.strictEqual(
findGenealogyFixture(id)?.accessPreset,
"PUBLIC_APPLY",
`${id} 只有公开可申请家谱才能暴露关系动作`,
);
}
for (const [id, relation, canApply] of [
["1001", "owned", false],
["1002", "joined", false],
["2001", "available", true],
["2003", "pending", false],
["2004", "rejected", true],
["2005", "removed", true],
["local-created-genealogy", "preview", false],
["unknown", "unknown", false],
]) {
const access = getGenealogyFixtureAccess(id);
assert.strictEqual(access.relation, relation, `${id} 关系必须来自共享夹具 owner`);
assert.strictEqual(access.canApply, canApply, `${id} 申请资格必须失败关闭`);
}
assert.strictEqual(getGenealogyFixtureAccess("local-created-genealogy").viewMode, "preview");
assert.strictEqual(getGenealogyFixtureAccess("unknown").accessRole, "guest");
const publicFixture = findGenealogyFixture("2001");
const originalAccessPreset = publicFixture.accessPreset;
publicFixture.accessPreset = "MEMBER_ONLY";
assert.strictEqual(
getGenealogyFixtureAccess("2001").canView,
false,
"陌生账号不得直接打开仅成员可见家谱的总览",
);
assert.strictEqual(
getGenealogyFixtureAccess("2001").canApply,
false,
"仅成员可见家谱即使关系标签陈旧也必须失败关闭",
);
assert.strictEqual(
isGenealogySearchVisible("2001"),
false,
"陌生账号不得搜索到仅成员可见的家谱",
);
publicFixture.accessPreset = originalAccessPreset;
assert.strictEqual(getGenealogyFixtureAccess("2001").canView, true);
assert.strictEqual(isGenealogySearchVisible("2001"), true);
assert.strictEqual(getGenealogyFixtureAccess("1001").canView, true, "所有者可查看自己的私密家谱");
assert.strictEqual(getGenealogyFixtureAccess("local-created-genealogy").canView, true, "本轮本地预览必须可回看");
assert.strictEqual(getGenealogyFixtureAccess("unknown").canView, false);
assert.strictEqual(isGenealogySearchVisible("1001"), true, "所有者仍可定位自己的私密家谱");
const firstPreviewId = createLocalGenealogyPreview({
surname: "欧阳",
name: "欧阳氏测试谱",
hall: "敦本堂",
location: "江西·吉安",
accessPreset: "PUBLIC_APPLY",
});
const secondPreviewId = createLocalGenealogyPreview({
surname: "汤",
name: "第二部测试谱",
hall: "",
location: "河南·洛阳",
accessPreset: "MEMBER_ONLY",
});
assert.notStrictEqual(firstPreviewId, secondPreviewId, "重复创建不得复用本地预览 ID");
assert.strictEqual(typeof firstPreviewId, "string");
assert.deepStrictEqual(
{
surname: findGenealogyFixture(firstPreviewId)?.surname,
name: findGenealogyFixture(firstPreviewId)?.name,
hall: findGenealogyFixture(firstPreviewId)?.hall,
location: findGenealogyFixture(firstPreviewId)?.location,
accessPreset: findGenealogyFixture(firstPreviewId)?.accessPreset,
},
{
surname: "欧阳",
name: "欧阳氏测试谱",
hall: "敦本堂",
location: "江西·吉安",
accessPreset: "PUBLIC_APPLY",
},
);
updateLocalGenealogyPreviewAncestor(firstPreviewId, { personName: "欧阳修" });
assert.strictEqual(findGenealogyFixture(firstPreviewId)?.ancestorName, "欧阳修");
assert.strictEqual(
updateLocalGenealogyPreview(firstPreviewId, {
surname: "欧阳",
name: "欧阳氏修订谱",
hall: "敦本堂",
location: "江西·庐陵",
accessPreset: "MEMBER_ONLY",
}),
firstPreviewId,
);
assert.strictEqual(findGenealogyFixture(firstPreviewId)?.name, "欧阳氏修订谱");
assert.strictEqual(findGenealogyFixture(firstPreviewId)?.ancestorName, "欧阳修");
assert.deepStrictEqual(
{
viewMode: getGenealogyFixtureAccess(firstPreviewId).viewMode,
accessRole: getGenealogyFixtureAccess(firstPreviewId).accessRole,
relation: getGenealogyFixtureAccess(firstPreviewId).relation,
canView: getGenealogyFixtureAccess(firstPreviewId).canView,
canApply: getGenealogyFixtureAccess(firstPreviewId).canApply,
},
{ viewMode: "preview", accessRole: "guest", relation: "preview", canView: true, canApply: false },
);
assert.strictEqual(removeLocalGenealogyPreview(secondPreviewId), true);
assert.strictEqual(findGenealogyFixture(secondPreviewId), null);
process.stdout.write("GENEALOGY-FIXTURE-RUNTIME-SMOKE PASS\n");
};
run().catch((error) => {
process.stderr.write(`${error.stack || error.message}\n`);
process.exit(1);
});