feat: botón Generar PDF en los reportes HTML (Chrome sin pantalla, papel y márgenes de la plantilla fijos)
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
2d358f0cf1
commit
f71577e792
13 files changed
+287
-19
No files matched your search
@@ -9,6 +9,7 @@ import type { AuthUser } from '../auth/auth.types.js';
|
||||
import type { AppConfigService } from '../config/app-config.service.js';
|
||||
import type { PermissionsService } from '../permissions/permissions.service.js';
|
||||
import type { SapDbService } from '../sapdb/sapdb.service.js';
|
||||
import type { HtmlPdfService } from './html-pdf.service.js';
|
||||
import { createRenderer } from './html-render.js';
|
||||
import { validateHtmlReports } from './html-reports.js';
|
||||
import type { HtmlReportDef } from './html-reports.types.js';
|
||||
@@ -88,18 +89,21 @@ describe('servicio de reportes HTML', () => {
|
||||
let paths: string[];
|
||||
const run = vi.fn(async () => ({ rows: [{ CardName: 'ACME' }], truncated: false }));
|
||||
const record = vi.fn(async () => undefined);
|
||||
const toPdf = vi.fn(async (html: string) => Buffer.from(`%PDF ${html.length}`));
|
||||
const service = () =>
|
||||
new HtmlReportsService(
|
||||
{ get: () => dir } as unknown as AppConfigService,
|
||||
{ getPaths: async () => paths } as unknown as PermissionsService,
|
||||
{ record } as unknown as AuditService,
|
||||
{ run } as unknown as SapDbService,
|
||||
{ toPdf } as unknown as HtmlPdfService,
|
||||
);
|
||||
|
||||
beforeEach(() => {
|
||||
paths = ['*'];
|
||||
run.mockClear();
|
||||
record.mockClear();
|
||||
toPdf.mockClear();
|
||||
});
|
||||
|
||||
it('lista los reportes con sus parámetros, sin la plantilla ni el código de datos', async () => {
|
||||
@@ -113,7 +117,22 @@ describe('servicio de reportes HTML', () => {
|
||||
expect(html).toContain('<p>ACME</p>');
|
||||
expect(html).toContain('<i>3/3</i>');
|
||||
expect(run).toHaveBeenCalledWith(user, 'guia', { docEntry: 144153 }, '10.0.0.5');
|
||||
expect(record).toHaveBeenCalledWith(expect.objectContaining({ action: 'html_report', resource: 'etiquetas', detail: { params: ['doc', 'cantidad', 'papel', 'fecha'] } }));
|
||||
expect(record).toHaveBeenCalledWith(expect.objectContaining({ action: 'html_report', resource: 'etiquetas', detail: { format: 'html', params: ['doc', 'cantidad', 'papel', 'fecha'] } }));
|
||||
});
|
||||
|
||||
it('el PDF pasa el mismo HTML por Chrome y se audita como pdf', async () => {
|
||||
const pdf = await service().pdf(user, 'etiquetas', { doc: '144153', cantidad: '3' }, '10.0.0.5');
|
||||
expect(pdf.subarray(0, 4).toString()).toBe('%PDF');
|
||||
expect(toPdf).toHaveBeenCalledWith(expect.stringContaining('<p>ACME</p>'));
|
||||
expect(record).toHaveBeenCalledWith(expect.objectContaining({ detail: expect.objectContaining({ format: 'pdf' }) }));
|
||||
});
|
||||
|
||||
it('el PDF exige los mismos permisos y parámetros que el HTML', async () => {
|
||||
paths = ['/ventas/*'];
|
||||
await expect(service().pdf(user, 'etiquetas', { doc: '1', cantidad: '1' }, '')).rejects.toThrow(ForbiddenException);
|
||||
paths = ['*'];
|
||||
await expect(service().pdf(user, 'etiquetas', { doc: '1' }, '')).rejects.toThrow(BadRequestException);
|
||||
expect(toPdf).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('sin el permiso de menú no se lista ni se ejecuta; un reporte que no existe da 404; un parámetro mal puesto, 400', async () => {
|
||||
|
||||
Reference in new issue
Block a user