1
0
forked from baron/baron-sso
Files
baron-sso/adminfront/src/features/users/utils/csvParser.test.ts
Lectom 75f192fb24 merge: integrate origin dev into dev
Includes Worksmobile SSOT sync comparison updates, UUID import conflict resolution, and Playwright route mock stabilization.
2026-06-01 17:48:39 +09:00

191 lines
6.7 KiB
TypeScript

import { describe, expect, it } from "vitest";
import { parseUserCSV } from "./csvParser";
describe("parseUserCSV", () => {
it("should parse valid CSV correctly", () => {
const csv = `email,name,phone,role,tenant,department,emp_id
user1@test.com,Hong Gil Dong,010-1111-2222,user,baron,HR,E001
user2@test.com,Kim Cheol Su,,admin,baron,IT,E002`;
const result = parseUserCSV(csv);
expect(result).toHaveLength(2);
expect(result[0]).toEqual({
email: "user1@test.com",
name: "Hong Gil Dong",
phone: "010-1111-2222",
role: "user",
tenantSlug: "baron",
department: "HR",
metadata: {
emp_id: "E001",
},
});
expect(result[1].email).toBe("user2@test.com");
expect(result[1].metadata.emp_id).toBe("E002");
});
it("should return empty array for empty input", () => {
expect(parseUserCSV("")).toEqual([]);
});
it("should skip rows without email or name", () => {
const csv = `email,name
,Only Name
no-name@test.com,`;
expect(parseUserCSV(csv)).toHaveLength(0);
});
it("should handle mixed case headers", () => {
const csv = `EMAIL,Name,Tenant
test@test.com,Test,baron`;
const result = parseUserCSV(csv);
expect(result[0].email).toBe("test@test.com");
expect(result[0].tenantSlug).toBe("baron");
});
it("should parse NAVERWORKS member CSV sample into Baron bulk user fields", () => {
const csv = `"LastName","FirstName","ID","Personal email","Sub email","Nickname","User type","Level","Organization","Position","CompanyMainPhone","Mobile/Country code","Mobile/Numbers","Language","Responsibilities","Workplace","SNS","SNS_ID","Birthday (solar, lunar)","Birthday","Entry Date","Employee number","Account activation time"
"Doe","John","john.doe","john@naver.com","john1@company.com; john2@company.com","John","Permanent Employee","Manager","org.1|org.2|org.3|myteam","Manager","02-0000-0000","+1","9144812222","English","Sales management","New York","Facebook","john","solar","19830415","20230415","AB001","20230415 08:00"`;
const result = parseUserCSV(csv);
expect(result).toHaveLength(1);
expect(result[0]).toMatchObject({
email: "john1@company.com",
loginId: "john.doe",
name: "John Doe",
phone: "+19144812222",
department: "myteam",
grade: "Manager",
position: "Manager",
jobTitle: "Sales management",
tenantImport: {
name: "myteam",
parentTenantName: "org.3",
},
metadata: {
personal_email: "john@naver.com",
employee_id: "AB001",
naverworks_user_type: "Permanent Employee",
naverworks_level: "Manager",
naverworks_organization_path: "org.1|org.2|org.3|myteam",
naverworks_workplace: "New York",
},
});
});
it("should parse tenant conflict metadata for import resolution", () => {
const csv = `email,name,tenant_id,tenant_slug,tenant_name,tenant_type,parent_tenant_slug,tenant_memo,email_domain
test@test.com,Test,local-tenant-id,missing-slug,Missing Tenant,COMPANY,parent-slug,Imported memo,missing.example.com`;
const result = parseUserCSV(csv);
expect(result[0]).toMatchObject({
tenantId: "local-tenant-id",
tenantSlug: "missing-slug",
emailDomain: "missing.example.com",
tenantImport: {
sourceTenantId: "local-tenant-id",
slug: "missing-slug",
name: "Missing Tenant",
type: "COMPANY",
parentTenantSlug: "parent-slug",
memo: "Imported memo",
emailDomain: "missing.example.com",
},
});
});
it("should ignore exported user_id during user CSV import", () => {
const csv = `user_id,email,name,tenant_id,tenant_slug
9f8cc1b1-af8d-45d4-946c-924a529c2556,restore@test.com,Restore User,tenant-id,restore-tenant`;
const result = parseUserCSV(csv);
expect(result).toHaveLength(1);
expect(result[0]).toMatchObject({
email: "restore@test.com",
name: "Restore User",
tenantId: "tenant-id",
tenantSlug: "restore-tenant",
});
expect(result[0]).not.toHaveProperty("id");
expect(result[0]).not.toHaveProperty("uuid");
});
it("should parse one nullable additional appointment from numbered columns", () => {
const csv = `email,name,phone,role,tenant_slug,department,grade,position,jobTitle,employee_id,tenant_slug1,department1,grade1,position1,jobTitle1,employee_id1
dual@test.com,Dual User,010-0000-0000,user,primary-tenant,개발팀,책임,팀장,Backend,EMP001,second-tenant,센터,수석,,Architecture,EMP002
nullable@test.com,Nullable User,010-1111-1111,user,primary-tenant,개발팀,책임,팀장,Backend,EMP003,,,,,,`;
const result = parseUserCSV(csv);
expect(result).toHaveLength(2);
expect(result[0]).toMatchObject({
tenantSlug: "primary-tenant",
department: "개발팀",
grade: "책임",
position: "팀장",
jobTitle: "Backend",
metadata: {
employee_id: "EMP001",
},
additionalAppointments: [
{
tenantSlug: "second-tenant",
department: "센터",
grade: "수석",
jobTitle: "Architecture",
metadata: {
employee_id: "EMP002",
},
},
],
});
expect(result[1].additionalAppointments).toBeUndefined();
});
it("should preserve sub_email as secondary email metadata without replacing primary email", () => {
const csv = `email,name,tenant_slug,employee_id,sub_email
primary@samaneng.com,Primary User,rnd-saman,EMP001,secondary@hanmaceng.co.kr`;
const result = parseUserCSV(csv);
expect(result).toHaveLength(1);
expect(result[0]).toMatchObject({
email: "primary@samaneng.com",
tenantSlug: "rnd-saman",
metadata: {
employee_id: "EMP001",
sub_email: ["secondary@hanmaceng.co.kr"],
aliasEmails: ["secondary@hanmaceng.co.kr"],
},
});
});
it("should mark duplicate bulk alias emails as blocking import errors", () => {
const csv = `email,name,tenant_slug,sub_email
user1@samaneng.com,User One,rnd-saman,shared@hanmaceng.co.kr
user2@samaneng.com,User Two,rnd-saman,shared@hanmaceng.co.kr`;
const result = parseUserCSV(csv);
expect(result).toHaveLength(2);
expect(result[0].importErrors).toContain("duplicateEmail");
expect(result[1].importErrors).toContain("duplicateEmail");
});
it("should mark a primary email reused as a sub email as a blocking import error", () => {
const csv = `email,name,tenant_slug,sub_email
user1@samaneng.com,User One,rnd-saman,user2@samaneng.com
user2@samaneng.com,User Two,rnd-saman,alias@hanmaceng.co.kr`;
const result = parseUserCSV(csv);
expect(result).toHaveLength(2);
expect(result[0].importErrors).toContain("duplicateEmail");
expect(result[1].importErrors).toContain("duplicateEmail");
});
});