UNPKG

@accounter/server

Version:
170 lines (146 loc) 5.94 kB
import { describe, expect, it } from 'vitest'; import type { BusinessMatchData, OwnerMatchInfo } from './business-matcher.helper.js'; import { applyForeignCounterpartyVatDefault, matchBusiness } from './business-matcher.helper.js'; const OWNER_ID = '00000000-0000-0000-0000-000000000001'; const LOCAL_BIZ_ID = '00000000-0000-0000-0000-000000000002'; const FOREIGN_BIZ_ID = '00000000-0000-0000-0000-000000000003'; const NO_LOCALITY_BIZ_ID = '00000000-0000-0000-0000-000000000004'; const owner: OwnerMatchInfo = { id: OWNER_ID, locality: 'Israel' }; function business(id: string, locality: string | null): BusinessMatchData { return { id, name: `business-${id}`, hebrew_name: null, vat_number: null, suggestion_data: null, locality, }; } const businesses: BusinessMatchData[] = [ business(OWNER_ID, 'Israel'), business(LOCAL_BIZ_ID, 'Israel'), business(FOREIGN_BIZ_ID, 'United States'), business(NO_LOCALITY_BIZ_ID, null), ]; describe('applyForeignCounterpartyVatDefault', () => { it('keeps an extracted VAT amount untouched, even for a foreign counterparty', () => { expect( applyForeignCounterpartyVatDefault(17, owner, OWNER_ID, FOREIGN_BIZ_ID, businesses), ).toBe(17); }); it('keeps an extracted VAT amount of 0 untouched', () => { expect(applyForeignCounterpartyVatDefault(0, owner, OWNER_ID, FOREIGN_BIZ_ID, businesses)).toBe( 0, ); }); it('sets VAT to 0 when the recipient counterparty is foreign', () => { expect( applyForeignCounterpartyVatDefault(null, owner, OWNER_ID, FOREIGN_BIZ_ID, businesses), ).toBe(0); }); it('sets VAT to 0 when the issuer counterparty is foreign', () => { expect( applyForeignCounterpartyVatDefault(null, owner, FOREIGN_BIZ_ID, OWNER_ID, businesses), ).toBe(0); }); it('sets VAT to 0 when only a foreign non-owner side matched', () => { expect(applyForeignCounterpartyVatDefault(null, owner, FOREIGN_BIZ_ID, null, businesses)).toBe( 0, ); expect(applyForeignCounterpartyVatDefault(null, owner, null, FOREIGN_BIZ_ID, businesses)).toBe( 0, ); }); it('keeps NULL when the counterparty shares the owner locality', () => { expect( applyForeignCounterpartyVatDefault(null, owner, LOCAL_BIZ_ID, OWNER_ID, businesses), ).toBeNull(); }); it('keeps NULL when the counterparty has no locality', () => { expect( applyForeignCounterpartyVatDefault(null, owner, NO_LOCALITY_BIZ_ID, OWNER_ID, businesses), ).toBeNull(); }); it('keeps NULL when no side matched', () => { expect(applyForeignCounterpartyVatDefault(null, owner, null, null, businesses)).toBeNull(); }); it('keeps NULL when the only match is the owner itself', () => { expect(applyForeignCounterpartyVatDefault(null, owner, OWNER_ID, null, businesses)).toBeNull(); expect( applyForeignCounterpartyVatDefault(null, owner, OWNER_ID, OWNER_ID, businesses), ).toBeNull(); }); it('keeps NULL when both sides matched non-owner businesses (ambiguous counterparty)', () => { expect( applyForeignCounterpartyVatDefault(null, owner, LOCAL_BIZ_ID, FOREIGN_BIZ_ID, businesses), ).toBeNull(); }); it('keeps NULL when the counterparty is unknown to the businesses list', () => { expect( applyForeignCounterpartyVatDefault( null, owner, OWNER_ID, '00000000-0000-0000-0000-00000000dead', businesses, ), ).toBeNull(); }); it('treats localities differing only by case/whitespace as equal', () => { const casedOwner: OwnerMatchInfo = { id: OWNER_ID, locality: ' ISRAEL ' }; expect( applyForeignCounterpartyVatDefault(null, casedOwner, LOCAL_BIZ_ID, OWNER_ID, businesses), ).toBeNull(); expect( applyForeignCounterpartyVatDefault(null, casedOwner, FOREIGN_BIZ_ID, OWNER_ID, businesses), ).toBe(0); }); it('treats a whitespace-only locality as missing', () => { const blankOwner: OwnerMatchInfo = { id: OWNER_ID, locality: ' ' }; expect( applyForeignCounterpartyVatDefault(null, blankOwner, FOREIGN_BIZ_ID, OWNER_ID, businesses), ).toBeNull(); const blankLocalityBiz = business('00000000-0000-0000-0000-000000000005', ' '); expect( applyForeignCounterpartyVatDefault(null, owner, blankLocalityBiz.id, OWNER_ID, [ ...businesses, blankLocalityBiz, ]), ).toBeNull(); }); it('keeps NULL when owner info is missing or has no locality', () => { expect( applyForeignCounterpartyVatDefault(null, undefined, OWNER_ID, FOREIGN_BIZ_ID, businesses), ).toBeNull(); expect( applyForeignCounterpartyVatDefault( null, { id: OWNER_ID, locality: null }, OWNER_ID, FOREIGN_BIZ_ID, businesses, ), ).toBeNull(); }); }); describe('matchBusiness — extracted issuer names', () => { const named = (id: string, name: string, hebrewName: string | null = null) => ({ ...business(id, 'Israel'), name, hebrew_name: hebrewName, }); it('matches a name whose only difference from the stored one is punctuation', () => { // The reported email-ingestion case: OCR extracts "Anthropic, PBC" and a business // stored under exactly that name must match — `normalizeText` strips the comma. const list = [named(LOCAL_BIZ_ID, 'Anthropic, PBC')]; expect(matchBusiness('Anthropic, PBC', '', list)).toBe(LOCAL_BIZ_ID); expect(matchBusiness('Anthropic PBC', '', list)).toBe(LOCAL_BIZ_ID); expect(matchBusiness('anthropic, pbc.', '', list)).toBe(LOCAL_BIZ_ID); }); it('does not match an unrelated single-word name', () => { expect(matchBusiness('Stripe', '', [named(LOCAL_BIZ_ID, 'Anthropic, PBC')])).toBeNull(); }); it('returns null on an empty business list (no matching possible)', () => { expect(matchBusiness('Anthropic, PBC', '123456789', [])).toBeNull(); }); });