import { BadRequestException } from "@nestjs/common"; import { BlameRequestType } from "src/Types&Enums/blame-request-management/blameRequestType.enum"; import { InquiryParticipantRole, VehicleRegistrationState, } from "src/common/dto/inquiry-participants.dto"; import { assertPreviousPlateInquiryMatchesVin, isMappedPolicyCurrent, normalizeInquirySubmission, participantForRole, participantForStoredPartyRole, resolveInquiryParticipants, resolveInquirySubjects, resolveInquiryVehicle, runPlateInquiryWithFallback, vehiclePlateCandidates, } from "./inquiry-participant-resolver"; describe("inquiry participant resolver", () => { it("links several roles to one explicitly shared person", () => { const resolved = resolveInquiryParticipants(BlameRequestType.THIRD_PARTY, { driver: { nationalCode: "0012345678", birthday: "1370/01/01", hasDrivingLicense: true, licenseNumber: "123456789", licenseType: "1", }, vehicleOwner: { sameAs: InquiryParticipantRole.DRIVER }, thirdPartyPolicyholder: { sameAs: InquiryParticipantRole.VEHICLE_OWNER, }, }); expect(resolved.participants).toHaveLength(1); expect(resolved.roles).toEqual({ driver: "DRIVER", vehicleOwner: "DRIVER", thirdPartyPolicyholder: "DRIVER", }); }); it("requires both previous plate and VIN for a recent transfer", () => { expect(() => resolveInquiryVehicle({ registrationState: VehicleRegistrationState.RECENTLY_TRANSFERRED, currentPlate: { leftDigits: "44", centerAlphabet: "ب", centerDigits: "111", ir: "22", }, }), ).toThrow(BadRequestException); }); it("defaults an omitted registration state to CURRENT", () => { expect( resolveInquiryVehicle({ currentPlate: { leftDigits: "44", centerAlphabet: "ب", centerDigits: "111", ir: "22", }, }).registrationState, ).toBe(VehicleRegistrationState.CURRENT); }); it("rejects the removed flat inquiry contract", () => { expect(() => resolveInquiryParticipants(BlameRequestType.THIRD_PARTY, { nationalCodeOfDriver: "0012345678", driverBirthday: "1370/01/01", driverLicense: "123456789", nationalCodeOfInsurer: "0098765432", insurerBirthday: "1360/02/02", driverIsInsurer: false, } as any), ).toThrow(BadRequestException); }); it("rejects phone numbers in participant inquiry identity", () => { expect(() => resolveInquiryParticipants(BlameRequestType.THIRD_PARTY, { driver: { nationalCode: "0012345678", birthday: "1370/01/01", hasDrivingLicense: false, phoneNumber: "09120000000", }, vehicleOwner: { sameAs: InquiryParticipantRole.DRIVER }, thirdPartyPolicyholder: { sameAs: InquiryParticipantRole.DRIVER, }, } as any), ).toThrow(BadRequestException); }); it("keeps third-party and car-body policyholders distinct", () => { const resolved = resolveInquiryParticipants(BlameRequestType.CAR_BODY, { driver: { nationalCode: "0012345678", birthday: "1370/01/01", hasDrivingLicense: false, }, vehicleOwner: { sameAs: InquiryParticipantRole.DRIVER }, thirdPartyPolicyholder: { nationalCode: "0023456789", birthday: "1360/02/02", }, carBodyPolicyholder: { nationalCode: "0034567890", birthday: "1350/03/03", }, }); expect( participantForRole( resolved, InquiryParticipantRole.THIRD_PARTY_POLICYHOLDER, )?.nationalCode, ).toBe("0023456789"); expect( participantForRole(resolved, InquiryParticipantRole.CAR_BODY_POLICYHOLDER) ?.nationalCode, ).toBe("0034567890"); }); it("projects role-complete input onto the existing inquiry fields", () => { const normalized = normalizeInquirySubmission(BlameRequestType.CAR_BODY, { vehicle: { currentPlate: { leftDigits: "44", centerAlphabet: "ب", centerDigits: "111", ir: "22", }, }, driver: { nationalCode: "0012345678", birthday: "1370/01/01", hasDrivingLicense: true, licenseNumber: "D-1", licenseType: "1", }, vehicleOwner: { sameAs: InquiryParticipantRole.DRIVER }, thirdPartyPolicyholder: { nationalCode: "0023456789", birthday: "1360/02/02", }, carBodyPolicyholder: { nationalCode: "0034567890", birthday: "1350/03/03", }, }); expect(normalized.dto.nationalCodeOfInsurer).toBe("0023456789"); expect(normalized.dto.nationalCodeOfDriver).toBe("0012345678"); expect(normalized.carBodyPolicyholder?.nationalCode).toBe("0034567890"); expect(normalized.vehicleOwner?.nationalCode).toBe("0012345678"); }); it("routes each inquiry to its domain participant", () => { const normalized = normalizeInquirySubmission(BlameRequestType.CAR_BODY, { vehicle: { currentPlate: { leftDigits: "44", centerAlphabet: "ب", centerDigits: "111", ir: "22", }, }, driver: { nationalCode: "0011111111", birthday: "1370/01/01", hasDrivingLicense: false, }, vehicleOwner: { nationalCode: "0022222222", birthday: "1365/02/02", }, thirdPartyPolicyholder: { nationalCode: "0033333333", birthday: "1360/03/03", }, carBodyPolicyholder: { nationalCode: "0044444444", birthday: "1355/04/04", }, }); expect(resolveInquirySubjects(normalized)).toEqual({ thirdPartyPolicyNationalCode: "0033333333", carBodyPolicyNationalCode: "0044444444", shebaNationalCode: "0022222222", driverNationalCode: "0011111111", }); }); it("resolves a persisted vehicle owner for later Sheba validation", () => { const party = { participants: [ { participantId: "DRIVER", nationalCode: "0011111111" }, { participantId: "VEHICLE_OWNER", nationalCode: "0022222222" }, ], participantRoles: { driver: "DRIVER", vehicleOwner: "VEHICLE_OWNER", thirdPartyPolicyholder: "DRIVER", }, }; expect( participantForStoredPartyRole(party, InquiryParticipantRole.VEHICLE_OWNER) ?.nationalCode, ).toBe("0022222222"); }); it("orders the current plate before the previous-plate fallback", () => { const currentPlate = { leftDigits: "44", centerAlphabet: "ب", centerDigits: "111", ir: "22", }; const previousPlate = { leftDigits: "55", centerAlphabet: "ج", centerDigits: "222", ir: "33", }; expect( vehiclePlateCandidates({ registrationState: VehicleRegistrationState.RECENTLY_TRANSFERRED, currentPlate, previousPlate, vin: "NAAM01E15HK123456", }), ).toEqual([ { kind: "CURRENT", plate: currentPlate }, { kind: "PREVIOUS", plate: previousPlate }, ]); }); it("rejects a previous-plate result for another chassis", () => { expect(() => assertPreviousPlateInquiryMatchesVin("NAAM01E15HK123456", { VinNumberField: "DIFFERENTVIN00001", }), ).toThrow(BadRequestException); }); it("requires the driver's licence status in the new contract", () => { expect(() => resolveInquiryParticipants(BlameRequestType.THIRD_PARTY, { driver: { nationalCode: "0012345678", birthday: "1370/01/01" }, vehicleOwner: { sameAs: InquiryParticipantRole.DRIVER }, thirdPartyPolicyholder: { sameAs: InquiryParticipantRole.VEHICLE_OWNER, }, }), ).toThrow(BadRequestException); }); it("falls back to the previous plate and accepts only a matching VIN", async () => { const currentPlate = { leftDigits: "44", centerAlphabet: "ب", centerDigits: "111", ir: "22", }; const previousPlate = { leftDigits: "55", centerAlphabet: "ج", centerDigits: "222", ir: "33", }; const query = jest .fn() .mockRejectedValueOnce(new Error("not found")) .mockResolvedValueOnce({ mapped: { VinNumberField: "NAAM01E15HK123456", CompanyName: "پارسیان" }, }); const result = await runPlateInquiryWithFallback<{ mapped: { VinNumberField?: string; CompanyName?: string }; }>({ vehicle: { registrationState: VehicleRegistrationState.RECENTLY_TRANSFERRED, currentPlate, previousPlate, vin: "NAAM01E15HK123456", }, fallbackCurrentPlate: currentPlate, query, isUsable: (value) => !!value.mapped.CompanyName, mappedValue: (value) => value.mapped, }); expect(query).toHaveBeenCalledTimes(2); expect(result.plateKind).toBe("PREVIOUS"); expect(result.attempts).toMatchObject([ { plateKind: "CURRENT", succeeded: false, error: "not found" }, { plateKind: "PREVIOUS", succeeded: true, usable: true }, ]); expect(result.attempts[0]).toMatchObject({ plate: currentPlate, vin: "NAAM01E15HK123456", }); expect(result.attempts[1]).toMatchObject({ plate: previousPlate, vin: "NAAM01E15HK123456", }); }); it("rejects a car-body policyholder on a third-party case", () => { expect(() => resolveInquiryParticipants(BlameRequestType.THIRD_PARTY, { driver: { nationalCode: "0012345678", birthday: "1370/01/01", hasDrivingLicense: false, }, vehicleOwner: { sameAs: InquiryParticipantRole.DRIVER }, thirdPartyPolicyholder: { sameAs: InquiryParticipantRole.VEHICLE_OWNER, }, carBodyPolicyholder: { nationalCode: "0034567890", birthday: "1350/03/03", }, }), ).toThrow(BadRequestException); }); it("does not accept a previous plate unless recent transfer is declared", () => { expect(() => resolveInquiryVehicle({ registrationState: VehicleRegistrationState.CURRENT, currentPlate: { leftDigits: "44", centerAlphabet: "ب", centerDigits: "111", ir: "22", }, previousPlate: { leftDigits: "55", centerAlphabet: "ج", centerDigits: "222", ir: "33", }, }), ).toThrow(BadRequestException); }); it("rejects sameAs together with any person-specific fields", () => { expect(() => resolveInquiryParticipants(BlameRequestType.THIRD_PARTY, { driver: { nationalCode: "0012345678", birthday: "1370/01/01", hasDrivingLicense: false, }, vehicleOwner: { sameAs: InquiryParticipantRole.DRIVER, fullName: "Duplicate details must not be silently discarded", }, thirdPartyPolicyholder: { sameAs: InquiryParticipantRole.DRIVER, }, }), ).toThrow(BadRequestException); }); it("rejects conflicting legacy and structured current plates", () => { expect(() => normalizeInquirySubmission(BlameRequestType.THIRD_PARTY, { plate: { leftDigits: "44", centerAlphabet: "ب", centerDigits: "111", ir: "22", }, vehicle: { registrationState: VehicleRegistrationState.CURRENT, currentPlate: { leftDigits: "55", centerAlphabet: "ج", centerDigits: "222", ir: "33", }, }, driver: { nationalCode: "0012345678", birthday: "1370/01/01", hasDrivingLicense: false, }, vehicleOwner: { sameAs: InquiryParticipantRole.DRIVER }, thirdPartyPolicyholder: { sameAs: InquiryParticipantRole.DRIVER, }, }), ).toThrow(BadRequestException); }); it("treats an expired policy result as stale", () => { expect(isMappedPolicyCurrent({ EndDate: "1404/01/01" }, "2026-09-13")).toBe( false, ); expect(isMappedPolicyCurrent({ EndDate: "1406/01/01" }, "2026-09-13")).toBe( true, ); }); it("falls back from a stale current policy to a current previous-plate policy", async () => { const currentPlate = { leftDigits: "44", centerAlphabet: "ب", centerDigits: "111", ir: "22", }; const previousPlate = { leftDigits: "55", centerAlphabet: "ج", centerDigits: "222", ir: "33", }; const query = jest .fn() .mockResolvedValueOnce({ mapped: { CompanyName: "پارسیان", EndDate: "1404/01/01" }, }) .mockResolvedValueOnce({ mapped: { CompanyName: "پارسیان", EndDate: "1406/01/01", VinNumberField: "NAAM01E15HK123456", }, }); const result = await runPlateInquiryWithFallback<{ mapped: Record; }>({ vehicle: resolveInquiryVehicle({ registrationState: VehicleRegistrationState.RECENTLY_TRANSFERRED, currentPlate, previousPlate, vin: "NAAM01E15HK123456", }), fallbackCurrentPlate: currentPlate, query, isUsable: (value) => !!value.mapped.CompanyName && isMappedPolicyCurrent(value.mapped, "2026-09-13"), mappedValue: (value) => value.mapped, }); expect(result.plateKind).toBe("PREVIOUS"); expect(result.attempts[0]).toMatchObject({ plateKind: "CURRENT", succeeded: true, usable: false, }); }); it("rejects the result and retains audit attempts when every plate is unusable", async () => { const currentPlate = { leftDigits: "44", centerAlphabet: "ب", centerDigits: "111", ir: "22", }; const previousPlate = { leftDigits: "55", centerAlphabet: "ج", centerDigits: "222", ir: "33", }; await expect( runPlateInquiryWithFallback({ vehicle: resolveInquiryVehicle({ registrationState: VehicleRegistrationState.RECENTLY_TRANSFERRED, currentPlate, previousPlate, vin: "NAAM01E15HK123456", }), fallbackCurrentPlate: currentPlate, query: async () => ({ mapped: { CompanyName: "پارسیان" } }), isUsable: () => false, mappedValue: (value) => value.mapped, }), ).rejects.toMatchObject({ attempts: [ { plateKind: "CURRENT", succeeded: true, usable: false }, { plateKind: "PREVIOUS", succeeded: true, usable: false }, ], }); }); it("does not use the previous plate after a transport or provider outage", async () => { const currentPlate = { leftDigits: "44", centerAlphabet: "ب", centerDigits: "111", ir: "22", }; const query = jest.fn().mockRejectedValue( Object.assign(new Error("upstream timeout"), { code: "ETIMEDOUT", }), ); await expect( runPlateInquiryWithFallback({ vehicle: resolveInquiryVehicle({ registrationState: VehicleRegistrationState.RECENTLY_TRANSFERRED, currentPlate, previousPlate: { leftDigits: "55", centerAlphabet: "ج", centerDigits: "222", ir: "33", }, vin: "NAAM01E15HK123456", }), fallbackCurrentPlate: currentPlate, query, isUsable: () => false, mappedValue: () => ({}), }), ).rejects.toThrow("upstream timeout"); expect(query).toHaveBeenCalledTimes(1); }); it("allows an explicitly unknown policyholder only for a damaged-party submission", () => { const input = { driver: { nationalCode: "0012345678", birthday: "1370/01/01", hasDrivingLicense: false, }, vehicleOwner: { sameAs: InquiryParticipantRole.DRIVER }, thirdPartyPolicyholder: { unknown: true }, }; expect(() => resolveInquiryParticipants(BlameRequestType.THIRD_PARTY, input), ).toThrow(BadRequestException); const resolved = resolveInquiryParticipants( BlameRequestType.THIRD_PARTY, input, { allowUnknownThirdPartyPolicyholder: true }, ); expect( participantForRole( resolved, InquiryParticipantRole.THIRD_PARTY_POLICYHOLDER, ), ).toMatchObject({ unknown: true }); }); });