import fs from 'fs/promises'; import { Command } from 'commander'; import * as mdModule from '../src/services/markdownHtmlAgent'; import * as faModule from '../src/services/qualimetrie/fullAgent'; // Mock fullAgent and markdownHtmlAgent for CLI testing jest.mock('../src/services/qualimetrie/fullAgent', () => ({ ...jest.requireActual('../src/services/qualimetrie/fullAgent'), fullAgent: jest.fn(), })); jest.mock('../src/services/markdownHtmlAgent', () => ({ markdownHtmlAgent: jest.fn(), })); jest.mock('fs/promises'); const { cli } = faModule; const fullAgent = faModule.fullAgent as jest.Mock; const markdownHtmlAgent = mdModule.markdownHtmlAgent as jest.Mock; describe('fullAgent CLI', () => { beforeEach(() => jest.resetAllMocks()); it('builder registers out and output options', () => { const cmd = new Command(); cli.builder(cmd); const longOpts = cmd.options.map(o => o.long); expect(longOpts).toEqual(expect.arrayContaining(['--out', '--output'])); }); it('handler writes markdown report by default', async () => { const fakeRes = { report: 'MD REPORT' }; fullAgent.mockResolvedValue(fakeRes); const writeSpy = jest.spyOn(fs, 'writeFile').mockResolvedValue(); const logSpy = jest.spyOn(console, 'log').mockImplementation(() => {}); await cli.handler({}); expect(fullAgent).toHaveBeenCalled(); expect(writeSpy).toHaveBeenCalledWith('report/index.md', 'MD REPORT', 'utf-8'); expect(logSpy).toHaveBeenCalledWith('Markdown report generated: report/index.md'); writeSpy.mockRestore(); logSpy.mockRestore(); }); it('handler writes HTML report when out=html', async () => { const fakeRes = { report: 'MD RAW', lint: { detailPath: 'eslint-report.json' }, security: { detailPath: 'audit-report.json' }, bom: { packages: [] }, }; fullAgent.mockResolvedValue(fakeRes); markdownHtmlAgent.mockResolvedValue(''); const writeSpy = jest.spyOn(fs, 'writeFile').mockResolvedValue(); const logSpy = jest.spyOn(console, 'log').mockImplementation(() => {}); await cli.handler({ out: 'html', output: 'out.html' }); expect(fullAgent).toHaveBeenCalled(); expect(markdownHtmlAgent).toHaveBeenCalledWith( expect.objectContaining({ title: 'Qualimetry Report', markdown: expect.stringContaining('MD RAW'), }) ); // attachments block should be included in markdown passed to HTML generator const mdArg = markdownHtmlAgent.mock.calls[0][0].markdown; expect(mdArg).toContain('## Attachments'); expect(mdArg).toContain('- [Coverage HTML report]'); expect(mdArg).toContain('- [BOM report JSON]'); expect(writeSpy).toHaveBeenCalledWith('out.html', '', 'utf-8'); expect(logSpy).toHaveBeenCalledWith('HTML report generated: out.html'); writeSpy.mockRestore(); logSpy.mockRestore(); }); it('handler exits on HTML generation failure', async () => { fullAgent.mockResolvedValue({ report: 'MD', lint: {}, security: {}, bom: { packages: [] } }); markdownHtmlAgent.mockRejectedValue(new Error('fail html')); const errorSpy = jest.spyOn(console, 'error').mockImplementation(() => {}); const exitSpy = jest.spyOn(process, 'exit').mockImplementation((code?: number | string | null) => { throw new Error(`exit:${code}`); }); await expect(cli.handler({ out: 'html', output: 'out' })).rejects.toThrow('exit:1'); expect(errorSpy).toHaveBeenCalledWith('Error generating HTML report:', 'fail html'); exitSpy.mockRestore(); errorSpy.mockRestore(); }); });