import { describe, it, expect } from "vitest"; import { MMSendPart, MMSendPartOperation, MMSendWorkOrder, MMSendWorkOrderOperation, } from "./send-types.js"; import { HashedCacheManager } from "../../caching-service/hashed-cache-manager.js"; describe("MMSendPartOperation partName", () => { const baseArgs: [string, string, string, string, string, number, number, string, number] = [ "P-100", "A", "Standard", "10", "RES1", 60000, 120000, "Milling", 1, ]; it("includes partName in the REST payload when provided", () => { const op = new MMSendPartOperation(...baseArgs, undefined, undefined, "Widget Housing"); expect(op.toRESTApiObject().partName).toBe("Widget Housing"); expect(op.toFullApiObject().partName).toBe("Widget Housing"); }); it("omits partName from the REST payload when not provided", () => { const op = new MMSendPartOperation(...baseArgs); expect(op.toRESTApiObject()).not.toHaveProperty("partName"); }); it("omits partName from the REST payload when empty", () => { const op = new MMSendPartOperation(...baseArgs, undefined, undefined, ""); expect(op.toRESTApiObject()).not.toHaveProperty("partName"); }); it("round-trips partName through fromPlainObject", () => { const original = new MMSendPartOperation(...baseArgs, undefined, undefined, "Widget Housing"); const restored = MMSendPartOperation.fromPlainObject(original.toRESTApiObject()); expect(restored.partName).toBe("Widget Housing"); expect(restored.toRESTApiObject()).toEqual(original.toRESTApiObject()); }); }); describe("send types without custom fields keep their pre-custom-fields dedupe hash", () => { // The flattened driver now passes the row's (possibly undefined) custom fields into every // constructor. Undefined must serialize identically to "not passed", or every entity in every // existing connector's local cache would look changed on the first sync after upgrading. // MMSendPartOperation is not covered here: it already took explicit `undefined, undefined`. const partArgs: [string, string, string] = ["P1", "A", "Standard"]; const workOrderArgs: [ string, string, string, string, string, string | null, string, string | null, string | null, string | null, number, string, string, string, ] = ["WO-1", "0", "0", "0", "RELEASED", null, "", null, null, null, 5, "P1", "A", "Standard"]; const operationArgs: [ string, string, string, string, string, string, number, number, number, string | null, string | null, string | null, number, number, number, number, string, number, string, ] = ["WO-1", "0", "0", "0", "10", "R1", 0, 0, 0, null, null, null, 0, 0, 0, 0, "Production", 1, "RELEASED"]; it("hashes a part the same whether the trailing custom-field args are omitted or undefined", () => { const omitted = new MMSendPart(...partArgs); const explicit = new MMSendPart(...partArgs, undefined, undefined); expect(HashedCacheManager.hashRecord(explicit)).toBe(HashedCacheManager.hashRecord(omitted)); expect(explicit.toFullApiObject()).toEqual(omitted.toFullApiObject()); }); it("hashes a work order the same whether the trailing custom-field args are omitted or undefined", () => { const omitted = new MMSendWorkOrder(...workOrderArgs); const explicit = new MMSendWorkOrder(...workOrderArgs, undefined, undefined); expect(HashedCacheManager.hashRecord(explicit)).toBe(HashedCacheManager.hashRecord(omitted)); expect(explicit.toFullApiObject()).toEqual(omitted.toFullApiObject()); }); it("hashes a work order operation the same whether the trailing custom-field args are omitted or undefined", () => { const omitted = new MMSendWorkOrderOperation(...operationArgs); const explicit = new MMSendWorkOrderOperation(...operationArgs, undefined, undefined); expect(HashedCacheManager.hashRecord(explicit)).toBe(HashedCacheManager.hashRecord(omitted)); expect(explicit.toFullApiObject()).toEqual(omitted.toFullApiObject()); }); });