import { describe, it, expect, vi } from 'vitest'; import { mount, flushPromises } from '@vue/test-utils'; import { createVuetify } from 'vuetify'; import InvoicesTable from '../../resources/js/components/billing/InvoicesTable.vue'; import * as billingApi from '../../resources/js/api/billing'; import type { BillingInvoice } from '../../resources/js/api/billing'; vi.mock('../../resources/js/api/billing'); const vuetify = createVuetify(); describe('InvoicesTable.vue', () => { it('показывает empty-state без счетов', async () => { vi.mocked(billingApi.getInvoices).mockResolvedValue({ data: [] }); const wrapper = mount(InvoicesTable, { global: { plugins: [vuetify] } }); await flushPromises(); expect(wrapper.text()).toContain('Счета появятся'); }); it('рендерит строки счетов из API', async () => { const inv: BillingInvoice = { id: 1, invoice_number: 'СЧ-2026-00001', amount_total: '990.00', status: 'issued', issued_at: '2026-05-07T00:00:00Z', has_pdf: true, }; vi.mocked(billingApi.getInvoices).mockResolvedValue({ data: [inv] }); const wrapper = mount(InvoicesTable, { global: { plugins: [vuetify] } }); await flushPromises(); const text = wrapper.text(); expect(text).toContain('СЧ-2026-00001'); expect(text).toContain('Выставлен'); }); it('PDF-кнопка disabled при has_pdf=false и активна при has_pdf=true', async () => { const invs: BillingInvoice[] = [ { id: 1, invoice_number: 'СЧ-2026-00010', amount_total: '990.00', status: 'issued', issued_at: '2026-05-07T00:00:00Z', has_pdf: false, }, { id: 2, invoice_number: 'СЧ-2026-00011', amount_total: '500.00', status: 'paid', issued_at: '2026-05-08T00:00:00Z', has_pdf: true, }, ]; vi.mocked(billingApi.getInvoices).mockResolvedValue({ data: invs }); const wrapper = mount(InvoicesTable, { global: { plugins: [vuetify] } }); await flushPromises(); const pdfButtons = wrapper.findAll('button').filter((b) => b.text().includes('PDF')); expect(pdfButtons).toHaveLength(2); // Строка 1 (has_pdf=false) → disabled; строка 2 (has_pdf=true) → активна. expect(pdfButtons[0].attributes('disabled')).toBeDefined(); expect(pdfButtons[1].attributes('disabled')).toBeUndefined(); }); it('показывает error-alert при сбое', async () => { vi.mocked(billingApi.getInvoices).mockRejectedValue(new Error('fail')); const wrapper = mount(InvoicesTable, { global: { plugins: [vuetify] } }); await flushPromises(); expect(wrapper.text()).toContain('Не удалось загрузить счета'); }); it('renders amount_total with ₽ suffix', async () => { const inv: BillingInvoice = { id: 1, invoice_number: 'INV-1', amount_total: '1234.00', status: 'paid', issued_at: '2026-05-23T00:00:00Z', has_pdf: true, }; vi.mocked(billingApi.getInvoices).mockResolvedValue({ data: [inv] }); const wrapper = mount(InvoicesTable, { global: { plugins: [vuetify] } }); await flushPromises(); expect(wrapper.text()).toMatch(/1\s?234\s?₽/); }); });