shoc-frontend-new/src/test/domain/vendors/mappers/vendor-roster-mapper.test.ts
Alexandre Brandizzi 7ec522e8ea
Some checks are pending
Frontend checks / Build and test (push) Waiting to run
Frontend checks / governance (push) Waiting to run
Frontend checks / Visual regression (push) Waiting to run
Deploy / deploy (push) Waiting to run
fix: complete SH-283 vendor QA paths (#148)
Co-authored-by: Codex Review Integration <codex-review@local.invalid>
2026-08-27 15:03:36 -03:00

171 lines
5.5 KiB
TypeScript

import { describe, expect, it } from "vitest";
import {
mapRosterConflict,
mapRosterTechnician,
mapVendorCompanyRoster,
mapVendorRosterToBackend,
} from "@/domain/vendors/mappers/vendor-roster-mapper";
describe("vendor roster mapper", () => {
it("maps a PascalCase aggregate payload including technicians", () => {
const roster = mapVendorCompanyRoster({
CompanyId: 101,
RowVersion: "rv-1",
Name: "Gateway Plumbing",
CompanyPhone: "314-555-0100",
Email: "dispatch@gateway.test",
Technicians: [
{
Id: 7,
ContactName: "Adam Whyte",
Phone: "314-555-0198",
Email: "adam@gateway.test",
PreferredContact: "Email",
TradeSpecialties: "Plumbing",
IsActive: true,
TotalJobs: 72,
},
],
});
expect(roster).toEqual({
companyId: 101,
rowVersion: "rv-1",
name: "Gateway Plumbing",
companyPhone: "314-555-0100",
email: "dispatch@gateway.test",
address: "",
city: "",
state: "",
zip: "",
googleMapsUrl: "",
notes: "",
technicians: [
{
id: 7,
contactName: "Adam Whyte",
phone: "314-555-0198",
email: "adam@gateway.test",
preferredContact: "Email",
tradeSpecialties: "Plumbing",
isActive: true,
totalJobs: 72,
},
],
});
});
it("maps a company-only roster with a null vendor id and zero technicians", () => {
const roster = mapVendorCompanyRoster({ companyId: 5, name: "Solo Co" });
expect(roster.companyId).toBe(5);
expect(roster.technicians).toEqual([]);
});
it("canonicalizes phones and carries rowVersion on the backend payload", () => {
const payload = mapVendorRosterToBackend({
name: "Gateway Plumbing",
companyPhone: "314-555-0100",
email: "dispatch@gateway.test",
googleMapsUrl: "https://maps.google.com/x",
tradeSpecialties: "Plumbing",
rowVersion: "rv-2",
technicians: [{ contactName: "Adam", phone: "3145550198", preferredContact: "Phone" }],
});
expect(payload).toMatchObject({
name: "Gateway Plumbing",
companyPhone: "(314) 555-0100",
email: "dispatch@gateway.test",
rowVersion: "rv-2",
});
expect(payload.technicians).toEqual([
expect.objectContaining({ contactName: "Adam", phone: "(314) 555-0198" }),
]);
expect(payload).not.toHaveProperty("tradeSpecialties");
});
it("omits rowVersion from the create payload when absent", () => {
const payload = mapVendorRosterToBackend({ name: "Solo Co", companyPhone: "314-555-0100" });
expect(payload).not.toHaveProperty("rowVersion");
});
it("maps an open-work-order conflict payload", () => {
const conflict = mapRosterConflict(
{
blockedWorkOrders: [
{
workOrderId: 501,
workOrderNumber: "WO-501",
workOrderTitle: "Boiler repair",
status: "Dispatched",
},
],
},
"fallback",
);
expect(conflict.kind).toBe("open-work-orders");
expect(conflict.blockedWorkOrders[0]?.workOrderNumber).toBe("WO-501");
});
it("classifies a body without blocked work orders as stale", () => {
const conflict = mapRosterConflict({ message: "stale rowversion" }, "fallback");
expect(conflict.kind).toBe("stale");
expect(conflict.message).toBe("stale rowversion");
});
it("classifies the stable duplicate-company response", () => {
const conflict = mapRosterConflict(
{
code: "duplicate_vendor_company_name",
message: "Another vendor company already uses that name.",
},
"fallback",
);
expect(conflict.kind).toBe("duplicate");
expect(conflict.message).toBe("Another vendor company already uses that name.");
expect(conflict.blockedWorkOrders).toEqual([]);
});
it("preserves an explicit Phone/Email/Text preferred contact on read", () => {
expect(
mapRosterTechnician({ contactName: "A", preferredContact: "Phone" }).preferredContact,
).toBe("Phone");
expect(
mapRosterTechnician({ contactName: "B", preferredContact: "Email" }).preferredContact,
).toBe("Email");
expect(
mapRosterTechnician({ contactName: "C", preferredContact: "Text" }).preferredContact,
).toBe("Text");
});
it("preserves an absent preferred contact as absent on read", () => {
const tech = mapRosterTechnician({ contactName: "Adam" });
expect(tech.preferredContact).toBeUndefined();
});
it("preserves an unknown preferred contact as absent on read", () => {
const tech = mapRosterTechnician({ contactName: "Adam", preferredContact: "Fax" });
expect(tech.preferredContact).toBeUndefined();
});
it("omits preferredContact from the backend payload when absent", () => {
const payload = mapVendorRosterToBackend({
name: "Solo Co",
companyPhone: "314-555-0100",
technicians: [{ contactName: "Adam", phone: "3145550198" }],
});
const tech = (payload.technicians as Array<Record<string, unknown>>)[0];
expect(tech).not.toHaveProperty("preferredContact");
});
it("keeps an explicit preferredContact in the backend payload", () => {
const payload = mapVendorRosterToBackend({
name: "Solo Co",
companyPhone: "314-555-0100",
technicians: [{ contactName: "Adam", phone: "3145550198", preferredContact: "Email" }],
});
const tech = (payload.technicians as Array<Record<string, unknown>>)[0];
expect(tech.preferredContact).toBe("Email");
});
});