195 行
7.2 KiB
JavaScript
195 行
7.2 KiB
JavaScript
const {
|
|
maskEmail,
|
|
maskExternalUserId,
|
|
maskPhone,
|
|
fetchWecomHrProfiles,
|
|
normalizeWecomHrProfile,
|
|
__testables,
|
|
} = require("../../src/services/integrations/wecomHrMaster");
|
|
|
|
describe("wecom HR master sync helpers", () => {
|
|
function jsonResponse(payload, status = 200) {
|
|
return {
|
|
ok: status >= 200 && status < 300,
|
|
status,
|
|
json: async () => payload,
|
|
};
|
|
}
|
|
|
|
it("normalizes contact and HR assistant data without leaking full sensitive values in summary", () => {
|
|
const departmentMap = new Map([
|
|
["1", { externalId: "1", name: "研发部" }],
|
|
]);
|
|
|
|
const profile = normalizeWecomHrProfile({
|
|
departmentMap,
|
|
contact: {
|
|
userid: "oa_smoke002",
|
|
name: "测试员工",
|
|
mobile: "19912345678",
|
|
email: "[email protected]",
|
|
position: "测试工程师",
|
|
department: [1],
|
|
direct_leader: ["manager001"],
|
|
enable: 1,
|
|
},
|
|
staff: {
|
|
staff_info: [
|
|
{ fieldid: "入职日期", value: "2026-05-01" },
|
|
{ fieldid: "在职状态", value: "在职" },
|
|
],
|
|
},
|
|
});
|
|
|
|
expect(profile.externalUserId).toBe("oa_smoke002");
|
|
expect(profile.departmentName).toBe("研发部");
|
|
expect(profile.managerExternalUserId).toBe("manager001");
|
|
expect(profile.hireDate).toBe("2026-05-01");
|
|
expect(profile.sourceStatus).toBe("active");
|
|
expect(profile.missingRequiredFields).toEqual([]);
|
|
expect(JSON.stringify(profile.sourceSummary)).not.toContain("19912345678");
|
|
expect(JSON.stringify(profile.sourceSummary)).not.toContain("[email protected]");
|
|
expect(JSON.stringify(profile.sourceSummary)).not.toContain("oa_smoke002");
|
|
});
|
|
|
|
it("skips profiles missing OA-required source fields", () => {
|
|
const profile = normalizeWecomHrProfile({
|
|
contact: {
|
|
userid: "missing-email",
|
|
name: "缺邮箱",
|
|
mobile: "19900000001",
|
|
department: [1],
|
|
},
|
|
staff: {},
|
|
departmentMap: new Map([["1", { externalId: "1", name: "行政部" }]]),
|
|
});
|
|
|
|
expect(profile.missingRequiredFields).toContain("email");
|
|
});
|
|
|
|
it("marks inactive WeCom members as confirmation-required instead of active", () => {
|
|
const profile = normalizeWecomHrProfile({
|
|
contact: {
|
|
userid: "inactive001",
|
|
name: "离职测试",
|
|
mobile: "19900000002",
|
|
email: "[email protected]",
|
|
department: [1],
|
|
enable: 0,
|
|
},
|
|
staff: {},
|
|
departmentMap: new Map([["1", { externalId: "1", name: "行政部" }]]),
|
|
});
|
|
|
|
expect(profile.sourceStatus).toBe("inactive");
|
|
});
|
|
|
|
it("builds masked field changes for contact fields", () => {
|
|
const changes = __testables.buildEmployeeChanges(
|
|
{
|
|
id: "employee-1",
|
|
name: "旧员工",
|
|
phone: "19911112222",
|
|
email: "[email protected]",
|
|
department_id: "dept-old",
|
|
title: "旧岗位",
|
|
wecom_identity_binding: null,
|
|
},
|
|
{
|
|
externalUserId: "oa_smoke002",
|
|
name: "新员工",
|
|
phone: "19933334444",
|
|
email: "[email protected]",
|
|
title: "新岗位",
|
|
},
|
|
{ id: "dept-new", name: "研发部" },
|
|
);
|
|
|
|
expect(changes.phone.before).toBe(maskPhone("19911112222"));
|
|
expect(changes.phone.after).toBe(maskPhone("19933334444"));
|
|
expect(changes.email.before).toBe(maskEmail("[email protected]"));
|
|
expect(changes.externalUserId.after).toBe(maskExternalUserId("oa_smoke002"));
|
|
});
|
|
|
|
it("uses fixed contact and agent secrets with list_id for full contact inventory", async () => {
|
|
const calls = [];
|
|
const fetchImpl = async (url, init = {}) => {
|
|
const parsed = new URL(String(url));
|
|
calls.push({
|
|
path: parsed.pathname,
|
|
token: parsed.searchParams.get("access_token"),
|
|
method: init.method ?? "GET",
|
|
body: init.body ? JSON.parse(init.body) : null,
|
|
secret: parsed.searchParams.get("corpsecret"),
|
|
});
|
|
if (parsed.pathname === "/cgi-bin/gettoken") {
|
|
const secret = parsed.searchParams.get("corpsecret");
|
|
if (secret === "contact-secret-wapi") {
|
|
return jsonResponse({ errcode: 0, access_token: "contact-token", expires_in: 7200 });
|
|
}
|
|
if (secret === "agent-secret-wapi") {
|
|
return jsonResponse({ errcode: 0, access_token: "agent-token", expires_in: 7200 });
|
|
}
|
|
}
|
|
if (parsed.pathname === "/cgi-bin/department/list" && parsed.searchParams.get("access_token") === "contact-token") {
|
|
return jsonResponse({ errcode: 48009, errmsg: "department list not visible to contact app" });
|
|
}
|
|
if (parsed.pathname === "/cgi-bin/user/list_id" && parsed.searchParams.get("access_token") === "contact-token") {
|
|
expect(init.method).toBe("POST");
|
|
expect(JSON.parse(init.body)).toEqual({ cursor: "", limit: 2 });
|
|
return jsonResponse({
|
|
errcode: 0,
|
|
dept_user: [
|
|
{ userid: "oa_smoke002", department: 1 },
|
|
{ userid: "oa_smoke002", department: 2 },
|
|
],
|
|
next_cursor: "",
|
|
});
|
|
}
|
|
if (parsed.pathname === "/cgi-bin/user/get" && parsed.searchParams.get("access_token") === "contact-token") {
|
|
return jsonResponse({ errcode: 48009, errmsg: "api forbidden for contact assistant" });
|
|
}
|
|
if (parsed.pathname === "/cgi-bin/hr/get_staff_info" && parsed.searchParams.get("access_token") === "agent-token") {
|
|
expect(init.method).toBe("POST");
|
|
return jsonResponse({
|
|
errcode: 0,
|
|
staff_info: [
|
|
{ fieldid: "name", value: "测试员工" },
|
|
{ fieldid: "mobile", value: "19912345678" },
|
|
{ fieldid: "email", value: "[email protected]" },
|
|
{ fieldid: "department", value: "研发部" },
|
|
{ fieldid: "在职状态", value: "在职" },
|
|
],
|
|
});
|
|
}
|
|
return jsonResponse({ errcode: 40001, errmsg: "unexpected mock request" });
|
|
};
|
|
|
|
const result = await fetchWecomHrProfiles({
|
|
config: {
|
|
wecomCorpId: "corp-wapi",
|
|
wecomAgentId: "1000002",
|
|
wecomContactSecret: "contact-secret-wapi",
|
|
wecomAgentSecret: "agent-secret-wapi",
|
|
wecomHrAssistantSecret: "deprecated-hr-secret-should-not-be-used",
|
|
wecomContactDefaultDepartmentId: "1",
|
|
},
|
|
userids: [],
|
|
limit: 2,
|
|
fetchImpl,
|
|
});
|
|
|
|
expect(result.tokenSource.contact).toBe("WECOM_CONTACT_SECRET");
|
|
expect(result.tokenSource.hr).toBe("WECOM_AGENT_SECRET");
|
|
expect(result.profiles).toHaveLength(1);
|
|
expect(result.profiles[0].externalUserId).toBe("oa_smoke002");
|
|
expect(result.profiles[0].name).toBe("测试员工");
|
|
expect(result.profiles[0].missingRequiredFields).toEqual([]);
|
|
expect(calls.some((call) => call.path === "/cgi-bin/department/list" && call.token === "contact-token")).toBe(true);
|
|
expect(calls.some((call) => call.path === "/cgi-bin/user/list_id" && call.token === "contact-token")).toBe(true);
|
|
expect(calls.some((call) => call.path === "/cgi-bin/user/get" && call.token === "contact-token")).toBe(true);
|
|
expect(calls.some((call) => call.path === "/cgi-bin/hr/get_staff_info" && call.token === "agent-token")).toBe(true);
|
|
expect(calls.some((call) => call.secret === "deprecated-hr-secret-should-not-be-used")).toBe(false);
|
|
});
|
|
});
|