174 行
5.8 KiB
JavaScript
174 行
5.8 KiB
JavaScript
const {
|
|
buildConsistencyReport,
|
|
} = require("../../../src/scripts/audit-wecom-oa-user-consistency");
|
|
|
|
function employee(overrides = {}) {
|
|
return {
|
|
id: overrides.id ?? "employee-1",
|
|
employeeNo: overrides.employeeNo ?? "E001",
|
|
name: overrides.name ?? "员工一",
|
|
phone: overrides.phone ?? "13800000001",
|
|
email: overrides.email ?? "[email protected]",
|
|
status: overrides.status ?? "active",
|
|
archived: overrides.archived ?? false,
|
|
roles: overrides.roles ?? ["employee"],
|
|
wecomExternalUserId: overrides.wecomExternalUserId ?? "wecom_user_001_very_long",
|
|
};
|
|
}
|
|
|
|
function profile(overrides = {}) {
|
|
return {
|
|
externalUserId: overrides.externalUserId ?? "wecom_user_001_very_long",
|
|
name: overrides.name ?? "员工一",
|
|
phone: overrides.phone ?? "13800000001",
|
|
email: overrides.email ?? "[email protected]",
|
|
title: overrides.title ?? "工程师",
|
|
departmentExternalId: overrides.departmentExternalId ?? "1",
|
|
departmentName: overrides.departmentName ?? "研发部",
|
|
sourceStatus: overrides.sourceStatus ?? "active",
|
|
missingRequiredFields: overrides.missingRequiredFields ?? [],
|
|
};
|
|
}
|
|
|
|
function count(report, key) {
|
|
return report.findingCounts[key];
|
|
}
|
|
|
|
describe("audit-wecom-oa-user-consistency", () => {
|
|
it("reports no drift when OA active employee matches WeCom active profile by binding", () => {
|
|
const report = buildConsistencyReport({
|
|
oaEmployees: [employee()],
|
|
wecomProfiles: [profile()],
|
|
generatedAt: "2026-05-18T00:00:00.000Z",
|
|
limit: 200,
|
|
});
|
|
|
|
expect(report.status).toBe("PASS_NO_DRIFT");
|
|
expect(count(report, "matchedActive")).toBe(1);
|
|
expect(count(report, "oaActiveMissingInWecom")).toBe(0);
|
|
expect(count(report, "wecomActiveMissingInOa")).toBe(0);
|
|
expect(count(report, "matchConflict")).toBe(0);
|
|
});
|
|
|
|
it("classifies OA active employees missing from WeCom", () => {
|
|
const report = buildConsistencyReport({
|
|
oaEmployees: [employee({ employeeNo: "E002", wecomExternalUserId: "" })],
|
|
wecomProfiles: [],
|
|
});
|
|
|
|
expect(report.status).toBe("PASS_WITH_FINDINGS");
|
|
expect(count(report, "oaActiveMissingInWecom")).toBe(1);
|
|
expect(report.findings.oaActiveMissingInWecom[0]).toMatchObject({
|
|
employeeNo: "E002",
|
|
status: "active",
|
|
});
|
|
});
|
|
|
|
it("exempts default OA-only smoke accounts from WeCom-missing findings", () => {
|
|
const report = buildConsistencyReport({
|
|
oaEmployees: [
|
|
employee({
|
|
employeeNo: "T0001",
|
|
name: "OA smoke admin",
|
|
email: "[email protected]",
|
|
wecomExternalUserId: "",
|
|
}),
|
|
],
|
|
wecomProfiles: [],
|
|
});
|
|
|
|
expect(report.status).toBe("PASS_NO_DRIFT");
|
|
expect(count(report, "oaOnlySmokeExempted")).toBe(1);
|
|
expect(count(report, "oaActiveMissingInWecom")).toBe(0);
|
|
expect(report.findings.oaOnlySmokeExempted[0]).toMatchObject({
|
|
employeeNo: "T0001",
|
|
reason: "oa_only_smoke_no_wecom_account_required",
|
|
});
|
|
});
|
|
|
|
it("classifies WeCom active profiles missing from OA", () => {
|
|
const report = buildConsistencyReport({
|
|
oaEmployees: [],
|
|
wecomProfiles: [profile({ externalUserId: "wecom_user_new_very_long" })],
|
|
});
|
|
|
|
expect(report.status).toBe("PASS_WITH_FINDINGS");
|
|
expect(count(report, "wecomActiveMissingInOa")).toBe(1);
|
|
expect(report.findings.wecomActiveMissingInOa[0].wecom.externalUserIdPrefix).toBe("wecom_us***");
|
|
});
|
|
|
|
it("classifies missing required WeCom fields without exposing phone or email", () => {
|
|
const report = buildConsistencyReport({
|
|
oaEmployees: [employee()],
|
|
wecomProfiles: [
|
|
profile({
|
|
phone: "",
|
|
email: "",
|
|
departmentExternalId: "",
|
|
departmentName: "",
|
|
missingRequiredFields: ["phone", "email", "department"],
|
|
}),
|
|
],
|
|
});
|
|
const serialized = JSON.stringify(report);
|
|
|
|
expect(report.status).toBe("PASS_WITH_FINDINGS");
|
|
expect(count(report, "missingRequiredFields")).toBe(1);
|
|
expect(report.findings.missingRequiredFields[0].fields).toEqual(["department", "email", "phone"]);
|
|
expect(serialized).not.toContain("13800000001");
|
|
expect(serialized).not.toContain("[email protected]");
|
|
expect(serialized).not.toContain("wecom_user_001_very_long");
|
|
});
|
|
|
|
it("classifies inactive OA employees that still keep a WeCom binding", () => {
|
|
const report = buildConsistencyReport({
|
|
oaEmployees: [
|
|
employee({
|
|
employeeNo: "HRWDTEST-20260517214548",
|
|
status: "archived",
|
|
archived: true,
|
|
wecomExternalUserId: "HRWDTEST-20260517214548",
|
|
}),
|
|
],
|
|
wecomProfiles: [],
|
|
});
|
|
|
|
expect(report.status).toBe("PASS_WITH_FINDINGS");
|
|
expect(count(report, "inactiveWithBinding")).toBe(1);
|
|
expect(report.findings.inactiveWithBinding[0].employeeNo).toBe("HRWDTEST-20260517214548");
|
|
});
|
|
|
|
it("detects match conflicts across priority keys", () => {
|
|
const report = buildConsistencyReport({
|
|
oaEmployees: [
|
|
employee({
|
|
id: "employee-by-no",
|
|
employeeNo: "wecom_user_conflict_very_long",
|
|
phone: "13800000001",
|
|
email: "[email protected]",
|
|
wecomExternalUserId: "",
|
|
}),
|
|
employee({
|
|
id: "employee-by-phone",
|
|
employeeNo: "E003",
|
|
phone: "13900000002",
|
|
email: "[email protected]",
|
|
wecomExternalUserId: "",
|
|
}),
|
|
],
|
|
wecomProfiles: [
|
|
profile({
|
|
externalUserId: "wecom_user_conflict_very_long",
|
|
phone: "13900000002",
|
|
email: "[email protected]",
|
|
}),
|
|
],
|
|
});
|
|
|
|
expect(report.status).toBe("PASS_WITH_FINDINGS");
|
|
expect(count(report, "matchConflict")).toBe(1);
|
|
expect(report.findings.matchConflict[0]).toMatchObject({ reason: "multiple_oa_candidates" });
|
|
expect(report.findings.matchConflict[0].candidates).toHaveLength(2);
|
|
});
|
|
});
|