Files
jina-ai--reader/tests/e2e/assert-status-code.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

156 lines
5.8 KiB
TypeScript

/**
* E2E tests for the assertStatusCode option using a real HTTP fixture server.
*
* The html-input path produces snapshots with no `status` field, so the
* assertion in CrawlerHost.iterSnapshots is silently skipped there. To
* exercise the assertion proper, these tests drive the crawler against a
* local fixture server with `engine: 'curl'`.
*
* URL note: `assertNormalizedUrl` in src/services/misc.ts rejects bare IP
* literals in non-public ranges unconditionally, so the fixture URL uses
* the `localhost` hostname (server binds dual-stack).
*/
import { describe, it, before, after } from 'node:test';
import assert from 'node:assert';
import { getAgent } from '../helpers/client';
import { startFixtureServer, FixtureServer } from '../helpers/fixture-server';
describe('assertStatusCode against real network fixture', () => {
let fixture: FixtureServer;
before(async () => {
fixture = await startFixtureServer();
});
after(async () => {
await fixture.close();
});
async function crawlUrl(body: Record<string, unknown>, headers: Record<string, string> = {}) {
let req = getAgent()
.post('/')
.set('Accept', 'application/json')
.set('Content-Type', 'application/json');
for (const [k, v] of Object.entries(headers)) {
req = req.set(k, v);
}
return req.send(body);
}
// ── matching status: request succeeds ──────────────────────────────────
it('200 fixture passes when assertStatusCode matches', async () => {
const res = await crawlUrl({
url: fixture.url('/status/200'),
engine: 'curl',
assertStatusCode: 200,
});
assert.strictEqual(res.status, 200);
assert.match(res.body.data.content, /Status 200/);
});
it('404 fixture passes when assertStatusCode: 404 matches the real status', async () => {
const res = await crawlUrl({
url: fixture.url('/status/404'),
engine: 'curl',
assertStatusCode: 404,
});
assert.strictEqual(res.status, 200);
assert.match(res.body.data.content, /Status 404/);
});
it('200 fixture without assertStatusCode still works (default behavior)', async () => {
const res = await crawlUrl({
url: fixture.url('/status/200'),
engine: 'curl',
});
assert.strictEqual(res.status, 200);
assert.match(res.body.data.content, /Status 200/);
});
it('404 fixture without assertStatusCode does not throw (status check is opt-in)', async () => {
const res = await crawlUrl({
url: fixture.url('/status/404'),
engine: 'curl',
});
assert.strictEqual(res.status, 200);
assert.match(res.body.data.content, /Status 404/);
});
// ── mismatching status: request rejected with AssertionFailureError ────
it('200 expected vs 404 actual throws AssertionFailureError (body form)', async () => {
const res = await crawlUrl({
url: fixture.url('/status/404'),
engine: 'curl',
assertStatusCode: 200,
});
assert.ok(res.status >= 400, `Expected error status, got ${res.status}`);
assert.strictEqual(res.body.name, 'AssertionFailureError');
assert.match(
res.body.message || res.body.readableMessage,
/Expected status code 200 but got 404/
);
});
it('200 expected vs 500 actual throws AssertionFailureError', async () => {
const res = await crawlUrl({
url: fixture.url('/status/500'),
engine: 'curl',
assertStatusCode: 200,
});
assert.ok(res.status >= 400);
assert.strictEqual(res.body.name, 'AssertionFailureError');
assert.match(
res.body.message || res.body.readableMessage,
/Expected status code 200 but got 500/
);
});
it('404 expected vs 200 actual throws AssertionFailureError', async () => {
const res = await crawlUrl({
url: fixture.url('/status/200'),
engine: 'curl',
assertStatusCode: 404,
});
assert.ok(res.status >= 400);
assert.strictEqual(res.body.name, 'AssertionFailureError');
assert.match(
res.body.message || res.body.readableMessage,
/Expected status code 404 but got 200/
);
});
// ── header form behaves the same ────────────────────────────────────────
it('X-Assert-Status-Code header: match passes', async () => {
const res = await crawlUrl(
{ url: fixture.url('/status/200'), engine: 'curl' },
{ 'X-Assert-Status-Code': '200' }
);
assert.strictEqual(res.status, 200);
});
it('X-Assert-Status-Code header: mismatch throws AssertionFailureError', async () => {
const res = await crawlUrl(
{ url: fixture.url('/status/500'), engine: 'curl' },
{ 'X-Assert-Status-Code': '200' }
);
assert.ok(res.status >= 400);
assert.strictEqual(res.body.name, 'AssertionFailureError');
assert.match(
res.body.message || res.body.readableMessage,
/Expected status code 200 but got 500/
);
});
it('X-Assert-Status-Code: foo (non-numeric) is ignored — request succeeds despite 404', async () => {
const res = await crawlUrl(
{ url: fixture.url('/status/404'), engine: 'curl' },
{ 'X-Assert-Status-Code': 'foo' }
);
assert.strictEqual(res.status, 200);
assert.match(res.body.data.content, /Status 404/);
});
});