import { beforeEach, describe, expect, it, vi } from 'vitest'; import * as PDFFunctions from '../../../shared/PDF-functions'; import FormatTyp from '../../../shared/enums/common.enum'; import { TRodzajFaktury } from '../../../shared/consts/const'; import { Fa } from '../../types/fa3.types'; import { generateWiersze } from './Wiersze'; vi.mock('../../../shared/PDF-functions', () => ({ createHeader: vi.fn(), createLabelTextArray: vi.fn(), createSection: vi.fn(), formatText: vi.fn(), getContentTable: vi.fn(), getTable: vi.fn(), getValue: vi.fn((v) => v?._text || v), getTStawkaPodatku: vi.fn(), getDifferentColumnsValue: vi.fn(), })); describe(generateWiersze.name, () => { beforeEach(() => { vi.clearAllMocks(); }); const mockFaVat: Fa = { FaWiersz: [ { NrWierszaFa: { _text: '1' }, P_7: { _text: 'Product 1' }, P_9A: { _text: '100' }, P_8B: { _text: '2' }, P_12: { _text: '23' }, }, ], KodWaluty: { _text: 'PLN' }, P_15: { _text: '200' }, RodzajFaktury: { _text: TRodzajFaktury.VAT }, } as any; const setupBasicMocks = (p15Value: string, rodzajFakturyValue: string, currencyValue: string = 'PLN') => { vi.mocked(PDFFunctions.getTable).mockReturnValue([ { NrWierszaFa: { _text: '1' }, P_7: { _text: 'Product 1' }, P_9A: { _text: '100' }, }, ] as any); vi.mocked(PDFFunctions.getContentTable).mockReturnValue({ content: { table: {} } as any, fieldsWithValue: ['P_11', 'P_7'], }); vi.mocked(PDFFunctions.getValue).mockImplementation((field: any) => { if (field === mockFaVat.P_15 || field?._text === p15Value) return p15Value; if (field === mockFaVat.RodzajFaktury || field?._text === rodzajFakturyValue) return rodzajFakturyValue; if (field === mockFaVat.KodWaluty || field?._text === currencyValue) return currencyValue; return undefined; }); vi.mocked(PDFFunctions.formatText).mockReturnValue('formatted text' as any); vi.mocked(PDFFunctions.createHeader).mockReturnValue(['Header'] as any); vi.mocked(PDFFunctions.createSection).mockReturnValue({ section: 'content' } as any); vi.mocked(PDFFunctions.createLabelTextArray).mockReturnValue(['Label', 'Value'] as any); vi.mocked(PDFFunctions.getTStawkaPodatku).mockReturnValue('0' as any); vi.mocked(PDFFunctions.getDifferentColumnsValue).mockReturnValue([]); }; describe('when no invoice lines exist', () => { it('should return empty array when table is empty', () => { vi.mocked(PDFFunctions.getTable).mockReturnValue([]); vi.mocked(PDFFunctions.getContentTable).mockReturnValue({ content: null, fieldsWithValue: [], }); vi.mocked(PDFFunctions.getValue).mockReturnValue('0'); vi.mocked(PDFFunctions.getDifferentColumnsValue).mockReturnValue([]); const result = generateWiersze(mockFaVat); expect(result).toEqual([]); }); }); describe('when invoice lines exist', () => { it('should call getTable with FaWiersz', () => { setupBasicMocks('200', TRodzajFaktury.VAT); generateWiersze(mockFaVat); expect(PDFFunctions.getTable).toHaveBeenCalledWith(mockFaVat.FaWiersz); }); it('should call createHeader with "Pozycje"', () => { setupBasicMocks('200', TRodzajFaktury.VAT); generateWiersze(mockFaVat); expect(PDFFunctions.createHeader).toHaveBeenCalledWith('Pozycje'); }); describe('price text formatting', () => { it('should display "netto" when P_11 is in fieldsWithValue', () => { setupBasicMocks('200', TRodzajFaktury.VAT); generateWiersze(mockFaVat); expect(PDFFunctions.formatText).toHaveBeenCalledWith(expect.stringContaining('netto'), [ FormatTyp.Label, FormatTyp.MarginBottom8, ]); }); it('should display "brutto" when P_11 is not in fieldsWithValue', () => { vi.mocked(PDFFunctions.getTable).mockReturnValue([ { NrWierszaFa: { _text: '1' }, P_12: { _text: '23' } }, ] as any); vi.mocked(PDFFunctions.getContentTable).mockReturnValue({ content: { table: {} } as any, fieldsWithValue: ['P_11A', 'P_7', 'P12'], }); vi.mocked(PDFFunctions.getValue).mockReturnValue('0'); vi.mocked(PDFFunctions.formatText).mockReturnValue('formatted text' as any); vi.mocked(PDFFunctions.createHeader).mockReturnValue(['Header'] as any); vi.mocked(PDFFunctions.createSection).mockReturnValue({ section: 'content' } as any); generateWiersze(mockFaVat); expect(PDFFunctions.formatText).toHaveBeenCalledWith(expect.stringContaining('brutto'), [ FormatTyp.Label, FormatTyp.MarginBottom8, ]); }); it('should include currency code in price text', () => { setupBasicMocks('200', TRodzajFaktury.VAT); generateWiersze(mockFaVat); expect(PDFFunctions.formatText).toHaveBeenCalledWith(expect.stringContaining('PLN'), [ FormatTyp.Label, FormatTyp.MarginBottom8, ]); }); }); describe('table generation', () => { it('should generate single table when fieldsWithValue.length <= 8', () => { setupBasicMocks('200', TRodzajFaktury.VAT); generateWiersze(mockFaVat); expect(PDFFunctions.getContentTable).toHaveBeenCalledTimes(1); }); it('should generate two tables when fieldsWithValue.length > 8', () => { vi.mocked(PDFFunctions.getTable).mockReturnValue([ { NrWierszaFa: { _text: '1' }, P_12: { _text: '23' } }, ] as any); vi.mocked(PDFFunctions.getContentTable) .mockReturnValueOnce({ content: null, fieldsWithValue: Array(9).fill('field'), }) .mockReturnValueOnce({ content: { table: 'table1' } as any, fieldsWithValue: ['field1', 'field2'], }) .mockReturnValueOnce({ content: { table: 'table2' } as any, fieldsWithValue: ['field3', 'field4'], }); vi.mocked(PDFFunctions.getValue).mockReturnValue('0'); vi.mocked(PDFFunctions.formatText).mockReturnValue('formatted text' as any); vi.mocked(PDFFunctions.createHeader).mockReturnValue(['Header'] as any); vi.mocked(PDFFunctions.createSection).mockReturnValue({ section: 'content' } as any); generateWiersze(mockFaVat); expect(PDFFunctions.getContentTable).toHaveBeenCalledTimes(3); }); it('should not add second table if it has only 1 field with value', () => { vi.mocked(PDFFunctions.getTable).mockReturnValue([ { NrWierszaFa: { _text: '1' }, P_12: { _text: '23' } }, ] as any); vi.mocked(PDFFunctions.getContentTable) .mockReturnValueOnce({ content: null, fieldsWithValue: Array(9).fill('field'), }) .mockReturnValueOnce({ content: { table: 'table1' } as any, fieldsWithValue: ['field1', 'field2'], }) .mockReturnValueOnce({ content: { table: 'table2' } as any, fieldsWithValue: ['field1'], }); vi.mocked(PDFFunctions.getValue).mockReturnValue('0'); vi.mocked(PDFFunctions.formatText).mockReturnValue('formatted text' as any); vi.mocked(PDFFunctions.createHeader).mockReturnValue(['Header'] as any); vi.mocked(PDFFunctions.createSection).mockReturnValue({ section: 'content' } as any); generateWiersze(mockFaVat); const sectionCall = vi.mocked(PDFFunctions.createSection).mock.calls[0][0]; expect(sectionCall).not.toContain('\n'); expect(sectionCall.filter((item: any) => item?.table === 'table2')).toHaveLength(0); }); }); describe('payment amount description', () => { it('should add "Kwota pozostała do zapłaty" for ROZ invoice type when P_15 > 0', () => { setupBasicMocks('150', TRodzajFaktury.ROZ, 'EUR'); generateWiersze(mockFaVat); expect(PDFFunctions.createLabelTextArray).toHaveBeenCalledWith([ { value: 'Kwota pozostała do zapłaty: ', formatTyp: FormatTyp.LabelGreater }, { value: '150', formatTyp: FormatTyp.CurrencyGreater, currency: 'EUR', }, ]); }); it('should not add description for ROZ invoice when P_15 = 0', () => { setupBasicMocks('0', TRodzajFaktury.ROZ, 'EUR'); vi.mocked(PDFFunctions.createLabelTextArray).mockClear(); generateWiersze(mockFaVat); expect(PDFFunctions.createLabelTextArray).not.toHaveBeenCalled(); }); it('should add "Kwota należności ogółem" for VAT invoice when P_15 > 0', () => { setupBasicMocks('200', TRodzajFaktury.VAT, 'PLN'); generateWiersze(mockFaVat); expect(PDFFunctions.createLabelTextArray).toHaveBeenCalledWith([ { value: 'Kwota należności ogółem: ', formatTyp: FormatTyp.LabelGreater }, { value: '200', formatTyp: [FormatTyp.CurrencyGreater, FormatTyp.HeaderContent, FormatTyp.Value], currency: 'PLN', }, ]); }); it('should add description for KOR invoice when P_15 > 0', () => { setupBasicMocks('300', TRodzajFaktury.KOR, 'USD'); generateWiersze(mockFaVat); expect(PDFFunctions.createLabelTextArray).toHaveBeenCalledWith([ { value: 'Kwota należności ogółem: ', formatTyp: FormatTyp.LabelGreater }, { value: '300', formatTyp: [FormatTyp.CurrencyGreater, FormatTyp.HeaderContent, FormatTyp.Value], currency: 'USD', }, ]); }); it('should add description for KOR_ROZ invoice when P_15 > 0', () => { setupBasicMocks('250', TRodzajFaktury.KOR_ROZ, 'PLN'); generateWiersze(mockFaVat); expect(PDFFunctions.createLabelTextArray).toHaveBeenCalled(); }); it('should add description for UPR invoice when P_15 > 0', () => { setupBasicMocks('180', TRodzajFaktury.UPR, 'PLN'); generateWiersze(mockFaVat); expect(PDFFunctions.createLabelTextArray).toHaveBeenCalled(); }); it('should not add description for VAT invoice when P_15 = 0', () => { setupBasicMocks('0', TRodzajFaktury.VAT, 'PLN'); vi.mocked(PDFFunctions.createLabelTextArray).mockClear(); generateWiersze(mockFaVat); expect(PDFFunctions.createLabelTextArray).not.toHaveBeenCalled(); }); it('should use empty string for currency if KodWaluty is undefined', () => { vi.mocked(PDFFunctions.getTable).mockReturnValue([{ NrWierszaFa: { _text: '1' } }] as any); vi.mocked(PDFFunctions.getContentTable).mockReturnValue({ content: { table: {} } as any, fieldsWithValue: ['P_11', 'P_7'], }); vi.mocked(PDFFunctions.getValue).mockImplementation((field: any) => { if (field === mockFaVat.P_15) return '200'; if (field === mockFaVat.RodzajFaktury) return TRodzajFaktury.VAT; if (field === mockFaVat.KodWaluty) return undefined; return undefined; }); vi.mocked(PDFFunctions.formatText).mockReturnValue('formatted text' as any); vi.mocked(PDFFunctions.createHeader).mockReturnValue(['Header'] as any); vi.mocked(PDFFunctions.createSection).mockReturnValue({ section: 'content' } as any); vi.mocked(PDFFunctions.createLabelTextArray).mockReturnValue(['Label', 'Value'] as any); const faVatNoCurrency = { ...mockFaVat, KodWaluty: undefined } as any; generateWiersze(faVatNoCurrency); expect(PDFFunctions.createLabelTextArray).toHaveBeenCalledWith( expect.arrayContaining([ expect.objectContaining({ currency: '', }), ]) ); }); }); describe('createSection call', () => { it('should call createSection with correct parameters', () => { setupBasicMocks('200', TRodzajFaktury.VAT); generateWiersze(mockFaVat); expect(PDFFunctions.createSection).toHaveBeenCalledWith( expect.arrayContaining(['Header', 'formatted text']), true ); }); it('should return the result of createSection', () => { const mockSection = { section: 'test' }; setupBasicMocks('200', TRodzajFaktury.VAT); vi.mocked(PDFFunctions.createSection).mockReturnValue(mockSection as any); const result = generateWiersze(mockFaVat); expect(result).toEqual(mockSection); }); }); describe('header definitions', () => { it('should include all required headers in first table', () => { setupBasicMocks('200', TRodzajFaktury.VAT); generateWiersze(mockFaVat); const firstCall = vi.mocked(PDFFunctions.getContentTable).mock.calls[0]; const headers = firstCall[0]; expect(headers).toEqual( expect.arrayContaining([ expect.objectContaining({ name: 'NrWierszaFa', title: 'Lp.' }), expect.objectContaining({ name: 'P_7', title: 'Nazwa towaru lub usługi' }), expect.objectContaining({ name: 'P_9A', title: 'Cena jedn. netto' }), expect.objectContaining({ name: 'P_11', title: 'Wartość sprzedaży netto' }), ]) ); }); it('should use correct format types for currency fields', () => { setupBasicMocks('200', TRodzajFaktury.VAT); generateWiersze(mockFaVat); const firstCall = vi.mocked(PDFFunctions.getContentTable).mock.calls[0]; const headers = firstCall[0]; const currencyHeaders = headers.filter( (h: any) => h.format === FormatTyp.Currency || h.format === FormatTyp.Currency6 ); expect(currencyHeaders.length).toBeGreaterThan(0); }); }); }); });