import { provideHttpClient } from '@angular/common/http'; import { HttpTestingController, provideHttpClientTesting } from '@angular/common/http/testing'; import { type ComponentFixture, TestBed } from '@angular/core/testing'; import { ActivatedRoute, Router, convertToParamMap, provideRouter } from '@angular/router'; import { of } from 'rxjs'; import { beforeEach, describe, expect, it, vi } from 'vitest'; import { CompanySettingsService } from '../../core/company/company-settings'; import { DocumentFormPage } from './document-form.page'; import { DOCUMENT_SCREENS } from './document-screens'; describe('redondeo en el formulario', () => { let fixture: ComponentFixture; let ctrl: HttpTestingController; const el = () => fixture.nativeElement as HTMLElement; // eslint-disable-next-line @typescript-eslint/no-explicit-any const page = () => fixture.componentInstance as any; const tick = async () => { fixture.detectChanges(); await new Promise((r) => setTimeout(r)); fixture.detectChanges(); }; /** Abre un documento nuevo; `roundingEnabled` es lo que la empresa responde en sus ajustes (`OADM.RoundMthd`). */ async function open(roundingEnabled: boolean) { const screen = DOCUMENT_SCREENS.find((s) => s.resource === 'Orders')!; const route = { snapshot: { data: { screen, title: 'Documento' }, paramMap: convertToParamMap({}) }, paramMap: of(convertToParamMap({})) }; await TestBed.configureTestingModule({ imports: [DocumentFormPage], providers: [provideRouter([]), provideHttpClient(), provideHttpClientTesting(), { provide: ActivatedRoute, useValue: route }], }).compileComponents(); ctrl = TestBed.inject(HttpTestingController); vi.spyOn(TestBed.inject(Router), 'navigate').mockResolvedValue(true); const settings = TestBed.inject(CompanySettingsService); const loaded = settings.ensureLoaded(); ctrl.expectOne('/api/company/settings').flush({ roundingEnabled, accountSegmentsSeparator: '-' }); await loaded; fixture = TestBed.createComponent(DocumentFormPage); await tick(); ctrl.expectOne((r) => r.url === '/api/sl/SalesTaxCodes').flush({ value: [{ Code: 'IVA', Rate: 19 }] }); ctrl.expectOne((r) => r.url === '/api/sl/AdditionalExpenses').flush({ value: [] }); await tick(); } const labels = () => [...el().querySelectorAll('label')].map((l) => l.textContent?.trim()); beforeEach(() => TestBed.resetTestingModule()); it('si la empresa redondea por moneda aparece la fila Redondeo', async () => { await open(true); expect(labels()).toContain('Redondeo'); }); it('si el redondeo es por documento la fila no se ve, pero el campo sigue en el documento', async () => { await open(false); expect(labels()).not.toContain('Redondeo'); expect(page().header()).toMatchObject({ Rounding: 'tNO', RoundingDiffAmount: 0 }); }); it('el redondeo marcado se suma al total y se envía al crear', async () => { await open(true); page().setHeader('CardCode', 'C1'); page().setLines([{ ItemCode: 'A1', Quantity: 1, Price: 100, TaxCode: 'IVA', LineTotal: 100 }]); page().setHeader('Rounding', 'tYES'); page().setHeader('RoundingDiffAmount', 0.4); await tick(); expect(page().totals()).toMatchObject({ rounding: 0.4, total: 119.4 }); (el().querySelector('.actions .btn.main') as HTMLElement).click(); await tick(); const req = ctrl.expectOne((r) => r.method === 'POST' && !r.url.includes('SeriesService')); expect(req.request.body).toMatchObject({ Rounding: 'tYES', RoundingDiffAmount: 0.4 }); req.flush({ DocEntry: 10, DocNum: 10 }); await tick(); }); it('sin marcar no se suma ni se envía', async () => { await open(true); page().setHeader('CardCode', 'C1'); page().setLines([{ ItemCode: 'A1', Quantity: 1, Price: 100, TaxCode: 'IVA', LineTotal: 100 }]); page().setHeader('RoundingDiffAmount', 0.4); // el importe solo cuenta con el redondeo marcado await tick(); expect(page().totals()).toMatchObject({ rounding: 0, total: 119 }); (el().querySelector('.actions .btn.main') as HTMLElement).click(); await tick(); const body = ctrl.expectOne((r) => r.method === 'POST' && !r.url.includes('SeriesService')).request.body as Record; expect(body).not.toHaveProperty('Rounding'); expect(body).not.toHaveProperty('RoundingDiffAmount'); }); });