import { describe, it, expect } from "@jest/globals"; import { validatePlan } from "../../src/services/planValidation"; import type { InstrumentTerms, Plan } from "../../src/types/plan"; const goodTerms: InstrumentTerms = { applicant: "Solace Bank Group PLC", issuingBankBIC: "SOLBAE22", beneficiaryBankBIC: "MEBLAEAD", // Emirates Islamic BIC prefix example beneficiaryName: "Acme Trading LLC", beneficiaryAccount: "AE070331234567890123456", amount: 1_000_000, currency: "USD", tenor: "90D", expiryDate: "2026-06-30", placeOfPresentation: "Dubai, UAE", governingLaw: "URDG 758", templateRef: "EIB-SBLC-v3.2", templateHash: "a".repeat(64), // dummy sha256 }; function planWith(terms: Partial | null): Plan { return { creator: "solace-ops-01", steps: [ { type: "issueInstrument", amount: terms?.amount ?? 1_000_000, instrument: terms === null ? undefined : ({ ...goodTerms, ...terms } as InstrumentTerms), }, ], }; } describe("validatePlan — issueInstrument step", () => { it("accepts a well-formed SBLC step", () => { const result = validatePlan(planWith({})); expect(result.valid).toBe(true); expect(result.errors).toHaveLength(0); }); it("rejects a step missing the instrument object", () => { const result = validatePlan(planWith(null)); expect(result.valid).toBe(false); expect(result.errors[0]).toMatch(/missing instrument terms/); }); it("rejects an invalid BIC", () => { const result = validatePlan(planWith({ issuingBankBIC: "NOTABIC" })); expect(result.valid).toBe(false); expect(result.errors.join("\n")).toMatch(/issuingBankBIC is not a valid BIC/); }); it("rejects a non-ISO-4217 currency", () => { const result = validatePlan(planWith({ currency: "usd" })); expect(result.valid).toBe(false); expect(result.errors.join("\n")).toMatch(/currency must be ISO 4217/); }); it("rejects a non-ISO-8601 expiry date", () => { const result = validatePlan(planWith({ expiryDate: "30-06-2026" })); expect(result.valid).toBe(false); expect(result.errors.join("\n")).toMatch(/expiryDate must be YYYY-MM-DD/); }); it("rejects a non-sha256 template hash", () => { const result = validatePlan(planWith({ templateHash: "deadbeef" })); expect(result.valid).toBe(false); expect(result.errors.join("\n")).toMatch(/templateHash must be 64 hex chars/); }); it("rejects an instrument with non-positive amount", () => { const result = validatePlan(planWith({ amount: 0 })); expect(result.valid).toBe(false); expect(result.errors.join("\n")).toMatch(/instrument.amount must be > 0/); }); it("accepts 11-char branched BIC", () => { const result = validatePlan(planWith({ issuingBankBIC: "SOLBAE22XXX" })); expect(result.valid).toBe(true); }); });