| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576 |
- import { Test, TestingModule } from '@nestjs/testing';
- import { ScrapeUseCase } from '../src//application/use-cases/scrape.use-case';
- import { DirectFetchAdapter } from '../src//infrastructure/adapters/direct-fetch.adapter';
- import { BrowserlessAdapter } from '../src//infrastructure/adapters/browserless.adapter';
- import { ReadabilityMarkdownConverter } from '../src//infrastructure/adapters/readability-markdown.converter';
- describe('ScrapeUseCase', () => {
- let useCase: ScrapeUseCase;
- let directMock: Mock<DirectFetchAdapter>;
- let browserlessMock: Mock<BrowserlessAdapter>;
- let converterMock: Mock<ReadabilityMarkdownConverter>;
- const sampleHtml = (len: number) => '<html><body>' + 'x'.repeat(len) + '</body></html>';
- beforeEach(async () => {
- directMock = { fetch: vi.fn() } as any;
- browserlessMock = { fetch: vi.fn() } as any;
- converterMock = { convert: vi.fn() } as any;
- const module: TestingModule = await Test.createTestingModule({
- providers: [
- ScrapeUseCase,
- { provide: DirectFetchAdapter, useValue: directMock },
- { provide: BrowserlessAdapter, useValue: browserlessMock },
- { provide: ReadabilityMarkdownConverter, useValue: converterMock },
- ],
- }).compile();
- useCase = module.get(ScrapeUseCase);
- });
- it('uses direct fetch when content is sufficient', async () => {
- const html = sampleHtml(2000);
- directMock.fetch.mockResolvedValue(html);
- converterMock.convert.mockResolvedValue({ title: 'T', markdown: 'M' });
- const result = await useCase.execute({ url: 'https://example.com' });
- expect(directMock.fetch).toHaveBeenCalled();
- expect(browserlessMock.fetch).not.toHaveBeenCalled();
- expect(result.metadata.source).toBe('direct');
- });
- it('falls back to browserless when direct content is insufficient', async () => {
- const shortHtml = '<html><body>short</body></html>';
- directMock.fetch.mockResolvedValue(shortHtml);
- browserlessMock.fetch.mockResolvedValue(sampleHtml(2000));
- converterMock.convert.mockResolvedValue({ title: 'T', markdown: 'M' });
- const result = await useCase.execute({ url: 'https://example.com' });
- expect(browserlessMock.fetch).toHaveBeenCalled();
- expect(result.metadata.source).toBe('browserless');
- });
- it('uses browserless directly when render=true', async () => {
- browserlessMock.fetch.mockResolvedValue(sampleHtml(2000));
- converterMock.convert.mockResolvedValue({ title: 'T', markdown: 'M' });
- const result = await useCase.execute({ url: 'https://example.com', render: true });
- expect(directMock.fetch).not.toHaveBeenCalled();
- expect(browserlessMock.fetch).toHaveBeenCalled();
- expect(result.metadata.source).toBe('browserless');
- });
- it('returns markdown and title from converter', async () => {
- directMock.fetch.mockResolvedValue(sampleHtml(2000));
- converterMock.convert.mockResolvedValue({ title: 'Page Title', markdown: '# Hello' });
- const result = await useCase.execute({ url: 'https://example.com' });
- expect(result.title).toBe('Page Title');
- expect(result.markdown).toBe('# Hello');
- });
- });
|