Files
jina-ai--reader/tests/e2e/retain-links.test.ts
T
wehub-resource-sync f1ba9c6c36
/ test (push) Failing after 1s
/ build-and-push-to-ghcr (push) Has been skipped
chore: import upstream snapshot with attribution
2026-07-13 12:23:39 +08:00

105 lines
4.5 KiB
TypeScript

/**
* E2E tests for the `retainLinks` crawler option.
*
* Modes: all | none | text | gpt-oss
*/
import { describe, it } from 'node:test';
import assert from 'node:assert';
import { crawl, crawlWithHeaders, getContent } from '../helpers/client';
describe('retainLinks: all (default)', () => {
it('keeps markdown link syntax in content', async () => {
const res = await crawl({ retainLinks: 'all', respondWith: 'markdown' });
assert.strictEqual(res.status, 200);
assert.match(res.body.data.content, /\[.*?\]\(https?:\/\//);
});
it('includes the link hrefs from the fixture', async () => {
const res = await crawl({ retainLinks: 'all', respondWith: 'markdown' });
const content: string = res.body.data.content;
assert.match(content, /example\.com\/crawling|example\.org\/robots/);
});
it('renders crawling link with exact text and href', async () => {
const content = getContent(await crawl({ retainLinks: 'all', respondWith: 'markdown' }));
// fixture: <a href="https://example.com/crawling">link to crawling docs</a>
assert.match(content, /\[link to crawling docs\]\(https:\/\/example\.com\/crawling\)/);
});
it('renders robots.txt link with exact text and href', async () => {
const content = getContent(await crawl({ retainLinks: 'all', respondWith: 'markdown' }));
// fixture: <a href="https://example.org/robots">link about robots.txt</a>
assert.match(content, /\[link about robots\.txt\]\(https:\/\/example\.org\/robots\)/);
});
});
describe('retainLinks: none', () => {
it('removes hyperlinks from content', async () => {
const res = await crawl({ retainLinks: 'none', respondWith: 'markdown' });
assert.strictEqual(res.status, 200);
const content: string = res.body.data.content;
assert.doesNotMatch(content, /(?<!!)\[.*?\]\(https?:\/\//);
});
it('still contains non-link text content', async () => {
const res = await crawl({ retainLinks: 'none', respondWith: 'markdown' });
assert.match(res.body.data.content, /web crawling|fetching pages/i);
});
});
describe('retainLinks: text', () => {
it('replaces links with their anchor text only (no href)', async () => {
const res = await crawl({ retainLinks: 'text', respondWith: 'markdown' });
assert.strictEqual(res.status, 200);
const content: string = res.body.data.content;
assert.doesNotMatch(content, /(?<!!)\[.*?\]\(https?:\/\//);
});
it('preserves anchor text but strips the href', async () => {
const content = getContent(await crawl({ retainLinks: 'text', respondWith: 'markdown' }));
// Text should appear
assert.ok(content.includes('link to crawling docs'), 'Anchor text missing');
// But not as a markdown link with href
assert.doesNotMatch(content, /\[link to crawling docs\]\(https/);
});
});
describe('retainLinks: gpt-oss', () => {
it('converts links to citation format', async () => {
const res = await crawl({ retainLinks: 'gpt-oss', respondWith: 'markdown' });
assert.strictEqual(res.status, 200);
const content: string = res.body.data.content;
assert.match(content, /【\d+†/);
});
it('does not use standard markdown link syntax for hyperlinks', async () => {
const res = await crawl({ retainLinks: 'gpt-oss', respondWith: 'markdown' });
assert.doesNotMatch(res.body.data.content, /(?<!!)\[.*?\]\(https?:\/\//);
});
it('populates the links summary automatically', async () => {
const res = await crawl({ retainLinks: 'gpt-oss', respondWith: 'markdown' });
assert.notStrictEqual(res.body.data.links, undefined);
});
it('links summary contains the crawling docs URL', async () => {
const res = await crawl({ retainLinks: 'gpt-oss', respondWith: 'markdown' });
const hrefs = Object.values(res.body.data.links as Record<string, string>);
assert.ok(
hrefs.some((h) => h === 'https://example.com/crawling'),
`Expected https://example.com/crawling in gpt-oss links summary: ${hrefs.join(', ')}`,
);
});
});
describe('retainLinks via X-Retain-Links header', () => {
it('header overrides body param', async () => {
const res = await crawlWithHeaders(
{ 'X-Retain-Links': 'none' },
{ respondWith: 'markdown' },
);
assert.strictEqual(res.status, 200);
assert.doesNotMatch(res.body.data.content, /(?<!!)\[.*?\]\(https?:\/\//);
});
});