import { describe, expect, it, vi } from 'vitest' import { normalizeSourceUrl, UrlImporter } from './url-importer' const publicAddress = [{ address: '93.184.216.34', family: 4 }] describe('URL importer', () => { it('accepts HTTP(S) sources and rejects other protocols', () => { expect(() => normalizeSourceUrl('file:///etc/passwd')).toThrow('HTTP') expect(() => normalizeSourceUrl('不是 URL')).toThrow('有效') expect(normalizeSourceUrl('http://localhost/admin').href).toBe( 'http://localhost/admin' ) expect(normalizeSourceUrl('https://example.com/docs#top').href).toBe( 'https://example.com/docs' ) }) it('imports intranet URLs that resolve to private addresses', async () => { const transport = vi.fn(async () => ({ status: 200, headers: { 'content-type': 'text/plain' }, body: Buffer.from('内部知识') })) const importer = new UrlImporter({ lookup: async () => [{ address: '192.168.10.25', family: 4 }], transport }) await expect( importer.import( 'http://knowledge.internal/guide', new AbortController().signal ) ).resolves.toMatchObject({ url: 'http://knowledge.internal/guide', contentType: 'text/plain' }) expect(transport).toHaveBeenCalledWith( expect.objectContaining({ hostname: 'knowledge.internal' }), { address: '192.168.10.25', family: 4 }, expect.any(AbortSignal), expect.any(Number) ) }) it('fails when a hostname resolves to no address', async () => { const importer = new UrlImporter({ lookup: async () => [], transport: vi.fn() }) await expect( importer.import('https://example.com', new AbortController().signal) ).rejects.toThrow('无法解析') }) it('imports HTML and discovers only same-origin links', async () => { const transport = vi.fn(async () => ({ status: 200, headers: { 'content-type': 'text/html; charset=utf-8', etag: '"v1"' }, body: Buffer.from(`