ken_nogi/NodeSrv/apps/org-master-sync/test/keycloakColumnSync.test.js
Kenichiro NOGI ce58cb4be4 初回コミット: dev配下(NodeSrv/Pleasanter等)をGitea管理下に統合
GitHub(nextgroup2706/ken_nogi)は今後使わず自社Gitea運用に切替え。
NodeSrvは旧リポジトリの履歴を破棄しファイルのみ統合(Dokploy用サービスアカウントは
別途mygit-admin/NodeSrv.gitに履歴あり)。notepmエクスポート(12GB)とPleasanter
インストーラzip(208MB)はサイズが大きいため.gitignoreで除外。

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-04 15:37:06 +09:00

90 lines
5.1 KiB
JavaScript

const { test } = require("node:test");
const assert = require("node:assert");
const { buildAttributeDefs } = require("../src/lib/keycloakColumnSync");
test("buildAttributeDefs maps Pleasanter Columns (ColumnName/LabelText) onto Keycloak attribute defs (name/displayName)", () => {
const columns = [
{ ColumnName: "ClassA", LabelText: "社員ID" },
{ ColumnName: "Class001", LabelText: "姓" },
];
assert.deepStrictEqual(buildAttributeDefs(columns), [
{ name: "ClassA", displayName: "社員ID" },
{ name: "Class001", displayName: "姓" },
]);
});
test("planProfileAttributeSync detects additions and, on first run (lastSyncedNamesOrNull=null), only removes the legacy fullName/pleasanterLoginId/lineworksUserId attributes", () => {
const { planProfileAttributeSync } = require("../src/lib/keycloakColumnSync");
const currentProfile = { attributes: [{ name: "username" }, { name: "email" }, { name: "fullName" }, { name: "pleasanterLoginId" }, { name: "lineworksUserId" }, { name: "someOtherAppAttr" }] };
const attributeDefs = [{ name: "ClassA", displayName: "社員ID" }];
const plan = planProfileAttributeSync(currentProfile, attributeDefs, null);
assert.deepStrictEqual(plan.toAdd, [{ name: "ClassA", displayName: "社員ID" }]);
assert.deepStrictEqual(plan.toRemove.sort(), ["fullName", "lineworksUserId", "pleasanterLoginId"]);
});
test("planProfileAttributeSync on a later run removes only attributes that were synced before but are absent today, keeping unrelated and protected attributes", () => {
const { planProfileAttributeSync } = require("../src/lib/keycloakColumnSync");
const currentProfile = { attributes: [{ name: "username" }, { name: "email" }, { name: "ClassA" }, { name: "Class999" }, { name: "someOtherAppAttr" }] };
const attributeDefs = [{ name: "ClassA", displayName: "社員ID" }]; // Class999は今回のColumnsから消えた想定
const lastSyncedNames = ["ClassA", "Class999"];
const plan = planProfileAttributeSync(currentProfile, attributeDefs, lastSyncedNames);
assert.deepStrictEqual(plan.toAdd, []);
assert.deepStrictEqual(plan.toRemove, ["Class999"]);
});
test("planProfileAttributeSync never removes protected attributes (Keycloak standard fields + pleasanterResultId) even if listed in lastSyncedNames", () => {
const { planProfileAttributeSync, RESULT_ID_ATTR } = require("../src/lib/keycloakColumnSync");
const currentProfile = { attributes: [{ name: "username" }, { name: "email" }, { name: "firstName" }, { name: "lastName" }, { name: RESULT_ID_ATTR }] };
const plan = planProfileAttributeSync(currentProfile, [], ["username", "email", "firstName", "lastName", RESULT_ID_ATTR]);
assert.deepStrictEqual(plan.toRemove, []);
});
test("applyProfileAttributePlan adds new attribute defs and removes the ones marked for removal, returning null when there is nothing to change", () => {
const { planProfileAttributeSync, applyProfileAttributePlan } = require("../src/lib/keycloakColumnSync");
const currentProfile = { attributes: [{ name: "username" }, { name: "Class999" }] };
const attributeDefs = [{ name: "ClassA", displayName: "社員ID" }];
const plan = planProfileAttributeSync(currentProfile, attributeDefs, ["Class999"]);
const newProfile = applyProfileAttributePlan(currentProfile, plan);
assert.deepStrictEqual(newProfile.attributes.map((a) => a.name), ["username", "ClassA"]);
assert.strictEqual(applyProfileAttributePlan(currentProfile, { toAdd: [], toRemove: [] }), null);
});
test("planResultIdDeletions returns ResultIds present last time but absent today; returns [] on first run", () => {
const { planResultIdDeletions } = require("../src/lib/keycloakColumnSync");
assert.deepStrictEqual(planResultIdDeletions(["1", "2"], null), []); // 初回実行
assert.deepStrictEqual(planResultIdDeletions(["1"], ["1", "2"]), ["2"]); // 2が消えた
assert.deepStrictEqual(planResultIdDeletions(["1", "2"], ["1", "2"]), []); // 変化なし
});
test("saveLastSyncedColumnNames/loadLastSyncedColumnNames round-trip via a temp file; missing file returns null", () => {
const fs = require("fs");
const os = require("os");
const path = require("path");
const { saveLastSyncedColumnNames, loadLastSyncedColumnNames } = require("../src/lib/keycloakColumnSync");
const tmpFile = path.join(fs.mkdtempSync(path.join(os.tmpdir(), "kc-col-sync-test-")), "last-synced-columns.json");
assert.strictEqual(loadLastSyncedColumnNames(tmpFile), null);
saveLastSyncedColumnNames(["ClassA", "Class001"], tmpFile);
assert.deepStrictEqual(loadLastSyncedColumnNames(tmpFile), ["ClassA", "Class001"]);
});
test("saveLastSyncedResultIds/loadLastSyncedResultIds round-trip via a temp file; missing file returns null", () => {
const fs = require("fs");
const os = require("os");
const path = require("path");
const { saveLastSyncedResultIds, loadLastSyncedResultIds } = require("../src/lib/keycloakColumnSync");
const tmpFile = path.join(fs.mkdtempSync(path.join(os.tmpdir(), "kc-resultid-sync-test-")), "last-synced-result-ids.json");
assert.strictEqual(loadLastSyncedResultIds(tmpFile), null);
saveLastSyncedResultIds([1350, 831], tmpFile);
assert.deepStrictEqual(loadLastSyncedResultIds(tmpFile), [1350, 831]);
});