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>
99 lines
5.3 KiB
JavaScript
99 lines
5.3 KiB
JavaScript
const { test } = require("node:test");
|
|
const assert = require("node:assert");
|
|
const { getSite, getSiteItems, createSiteItem, updateSiteItem, getAllGroups, createGroup, getAllUsers, toHashPayload } = require("../src/lib/pleasanterClient");
|
|
|
|
test("getSite posts to /api/items/{siteId}/getsite and returns Response.Data", async () => {
|
|
let capturedUrl;
|
|
const fetchImpl = async (url) => { capturedUrl = url; return { ok: true, json: async () => ({ StatusCode: 200, Response: { Data: { Title: "テストサイト" } } }) }; };
|
|
const data = await getSite({ baseUrl: "https://example.test/", apiKey: "k", siteId: 1, fetchImpl });
|
|
assert.strictEqual(capturedUrl, "https://example.test/api/items/1/getsite");
|
|
assert.deepStrictEqual(data, { Title: "テストサイト" });
|
|
});
|
|
|
|
test("toHashPayload nests flat Class*/Num*/Date*/Description*/Check* keys under their Hash, leaves others as-is", () => {
|
|
const payload = toHashPayload({
|
|
Body: "備考",
|
|
ClassA: "u1",
|
|
Class001: "山田",
|
|
Date007: "1990-04-01",
|
|
Description022: "説明",
|
|
Check062: true,
|
|
});
|
|
assert.deepStrictEqual(payload, {
|
|
Body: "備考",
|
|
ClassHash: { ClassA: "u1", Class001: "山田" },
|
|
DateHash: { Date007: "1990-04-01" },
|
|
DescriptionHash: { Description022: "説明" },
|
|
CheckHash: { Check062: true },
|
|
});
|
|
});
|
|
|
|
test("getSiteItems pages through results using top-level Offset and flattens ClassHash/DateHash/CheckHash into top-level keys", async () => {
|
|
let call = 0;
|
|
const fetchImpl = async (url, opts) => {
|
|
const body = JSON.parse(opts.body);
|
|
call++;
|
|
if (body.Offset === 0) {
|
|
return { ok: true, json: async () => ({ StatusCode: 200, Response: { Data: [{ ResultId: 1, ClassHash: { ClassA: "a" }, CheckHash: { Check062: true } }], TotalCount: 2 } }) };
|
|
}
|
|
return { ok: true, json: async () => ({ StatusCode: 200, Response: { Data: [{ ResultId: 2, ClassHash: { ClassA: "b" }, CheckHash: { Check062: false } }], TotalCount: 2 } }) };
|
|
};
|
|
|
|
const items = await getSiteItems({ baseUrl: "https://example.test/", apiKey: "k", siteId: 1, fetchImpl });
|
|
|
|
assert.strictEqual(call, 2);
|
|
assert.deepStrictEqual(items.map((i) => i.ClassA), ["a", "b"]);
|
|
assert.deepStrictEqual(items.map((i) => i.Check062), [true, false]);
|
|
assert.strictEqual(items[0].ClassHash, undefined); // フラット化後はネストされたHashを持たない
|
|
});
|
|
|
|
test("createSiteItem sends fields nested under Hash keys and returns the new item Id (top-level, not Response.Id)", async () => {
|
|
let capturedBody;
|
|
const fetchImpl = async (url, opts) => { capturedBody = JSON.parse(opts.body); return { ok: true, json: async () => ({ Id: 42, StatusCode: 200, Message: "created" }) }; };
|
|
const id = await createSiteItem({ baseUrl: "https://example.test/", apiKey: "k", siteId: 1, fields: { ClassA: "u1", Check062: true }, fetchImpl });
|
|
assert.strictEqual(id, 42);
|
|
assert.deepStrictEqual(capturedBody.ClassHash, { ClassA: "u1" });
|
|
assert.deepStrictEqual(capturedBody.CheckHash, { Check062: true });
|
|
});
|
|
|
|
test("updateSiteItem posts Hash-nested fields to /api/items/{itemId}/update without siteId in the path", async () => {
|
|
let capturedUrl, capturedBody;
|
|
const fetchImpl = async (url, opts) => { capturedUrl = url; capturedBody = JSON.parse(opts.body); return { ok: true, json: async () => ({ Id: 7, StatusCode: 200 }) }; };
|
|
await updateSiteItem({ baseUrl: "https://example.test/", apiKey: "k", itemId: 7, fields: { Class035: "1,4" }, fetchImpl });
|
|
assert.strictEqual(capturedUrl, "https://example.test/api/items/7/update");
|
|
assert.deepStrictEqual(capturedBody.ClassHash, { Class035: "1,4" });
|
|
});
|
|
|
|
test("callApi throws when StatusCode is not 200", async () => {
|
|
const fetchImpl = async () => ({ ok: true, json: async () => ({ StatusCode: 400, Message: "bad" }) });
|
|
await assert.rejects(() => getSiteItems({ baseUrl: "https://example.test/", apiKey: "k", siteId: 1, fetchImpl }));
|
|
});
|
|
|
|
test("getAllGroups pages through /api/groups/get using top-level Offset", async () => {
|
|
let call = 0;
|
|
const fetchImpl = async () => {
|
|
call++;
|
|
return { ok: true, json: async () => ({ StatusCode: 200, Response: { Data: [{ GroupId: 1, GroupName: "組織:情報システム部" }], TotalCount: 1 } }) };
|
|
};
|
|
const groups = await getAllGroups({ baseUrl: "https://example.test/", apiKey: "k", fetchImpl });
|
|
assert.strictEqual(call, 1);
|
|
assert.strictEqual(groups[0].GroupName, "組織:情報システム部");
|
|
});
|
|
|
|
test("getAllUsers requests ApiGetMailAddresses:true and pages through /api/users/get using top-level Offset", async () => {
|
|
let capturedBody;
|
|
const fetchImpl = async (url, opts) => {
|
|
capturedBody = JSON.parse(opts.body);
|
|
return { ok: true, json: async () => ({ StatusCode: 200, Response: { Data: [{ UserId: 1, MailAddresses: ["a@example.com"] }], TotalCount: 1 } }) };
|
|
};
|
|
const users = await getAllUsers({ baseUrl: "https://example.test/", apiKey: "k", fetchImpl });
|
|
assert.strictEqual(users.length, 1);
|
|
assert.deepStrictEqual(capturedBody.View, { ApiGetMailAddresses: true });
|
|
});
|
|
|
|
test("createGroup returns the new GroupId (top-level Id)", async () => {
|
|
const fetchImpl = async () => ({ ok: true, json: async () => ({ Id: 61, StatusCode: 200 }) });
|
|
const id = await createGroup({ baseUrl: "https://example.test/", apiKey: "k", groupName: "役職:課長", fetchImpl });
|
|
assert.strictEqual(id, 61);
|
|
});
|