mirror of
https://github.com/public-transport/db-vendo-client.git
synced 2025-02-23 15:19:35 +02:00
262 lines
6.7 KiB
JavaScript
262 lines
6.7 KiB
JavaScript
// todo: use import assertions once they're supported by Node.js & ESLint
|
|
// https://github.com/tc39/proposal-import-assertions
|
|
import {createRequire} from 'module';
|
|
const require = createRequire(import.meta.url);
|
|
|
|
import tap from 'tap';
|
|
import forEach from 'lodash/forEach.js';
|
|
import {
|
|
checkIfResponseIsOk as checkIfResIsOk,
|
|
request,
|
|
} from '../../lib/request.js';
|
|
import {
|
|
INVALID_REQUEST,
|
|
NOT_FOUND,
|
|
HafasError,
|
|
HafasInvalidRequestError,
|
|
HafasNotFoundError,
|
|
} from '../../lib/errors.js';
|
|
import {formatTripReq} from '../../format/trip-req.js';
|
|
|
|
const resParameter = require('../fixtures/error-parameter.json');
|
|
const resNoMatch = require('../fixtures/error-no-match.json');
|
|
const resH9360 = require('../fixtures/error-h9360.json');
|
|
const resLocation = require('../fixtures/error-location.json');
|
|
|
|
const USER_AGENT = 'public-transport/hafas-client:test';
|
|
|
|
const secret = Symbol('secret');
|
|
|
|
tap.test('checkIfResponseIsOk properly throws HAFAS "H9360" errors', (t) => {
|
|
try {
|
|
checkIfResIsOk({
|
|
body: resH9360,
|
|
errProps: {secret},
|
|
});
|
|
} catch (err) {
|
|
t.ok(err);
|
|
|
|
t.ok(err instanceof HafasError);
|
|
t.equal(err.isHafasError, true);
|
|
t.equal(err.message.slice(0, 7), 'H9360: ');
|
|
t.ok(err.message.length > 7);
|
|
|
|
t.ok(err instanceof HafasInvalidRequestError);
|
|
t.equal(err.isCausedByServer, false);
|
|
t.equal(err.code, INVALID_REQUEST);
|
|
t.equal(err.hafasCode, 'H9360');
|
|
|
|
t.equal(err.hafasResponseId, resH9360.id);
|
|
t.equal(err.hafasMessage, 'HAFAS Kernel: Date outside of the timetable period.');
|
|
t.equal(err.hafasDescription, 'Fehler bei der Datumseingabe oder Datum außerhalb der Fahrplanperiode (01.05.2022 - 10.12.2022)');
|
|
t.equal(err.secret, secret);
|
|
|
|
t.end();
|
|
}
|
|
});
|
|
|
|
tap.test('checkIfResponseIsOk properly throws HAFAS "LOCATION" errors', (t) => {
|
|
try {
|
|
checkIfResIsOk({
|
|
body: resLocation,
|
|
errProps: {secret},
|
|
});
|
|
} catch (err) {
|
|
t.ok(err);
|
|
|
|
t.ok(err instanceof HafasError);
|
|
t.equal(err.isHafasError, true);
|
|
t.equal(err.message.slice(0, 10), 'LOCATION: ');
|
|
t.ok(err.message.length > 10);
|
|
|
|
t.ok(err instanceof HafasNotFoundError);
|
|
t.equal(err.isCausedByServer, false);
|
|
t.equal(err.code, NOT_FOUND);
|
|
t.equal(err.hafasCode, 'LOCATION');
|
|
|
|
t.equal(err.hafasResponseId, resLocation.id);
|
|
t.equal(err.hafasMessage, 'HCI Service: location missing or invalid');
|
|
t.equal(err.hafasDescription, 'Während der Suche ist ein interner Fehler aufgetreten');
|
|
t.equal(err.secret, secret);
|
|
|
|
t.end();
|
|
}
|
|
});
|
|
|
|
tap.test('checkIfResponseIsOk properly throws HAFAS "NO_MATCH" errors', (t) => {
|
|
try {
|
|
checkIfResIsOk({
|
|
body: resNoMatch,
|
|
errProps: {secret},
|
|
});
|
|
} catch (err) {
|
|
t.ok(err);
|
|
|
|
t.ok(err instanceof HafasError);
|
|
t.equal(err.isHafasError, true);
|
|
t.equal(err.message.slice(0, 10), 'NO_MATCH: ');
|
|
t.ok(err.message.length > 10);
|
|
|
|
t.ok(err instanceof HafasNotFoundError);
|
|
t.equal(err.isCausedByServer, false);
|
|
t.equal(err.code, NOT_FOUND);
|
|
t.equal(err.hafasCode, 'NO_MATCH');
|
|
|
|
t.equal(err.hafasResponseId, resNoMatch.id);
|
|
t.equal(err.hafasMessage, 'Nothing found.');
|
|
t.equal(err.hafasDescription, 'Während der Suche ist leider ein interner Fehler aufgetreten. Bitte wenden Sie sich an unsere Serviceauskunft unter Tel. 0421 596059.');
|
|
t.equal(err.secret, secret);
|
|
|
|
t.end();
|
|
}
|
|
});
|
|
|
|
tap.test('checkIfResponseIsOk properly throws HAFAS "PARAMETER" errors', (t) => {
|
|
try {
|
|
checkIfResIsOk({
|
|
body: resParameter,
|
|
errProps: {secret},
|
|
});
|
|
} catch (err) {
|
|
t.ok(err);
|
|
|
|
t.ok(err instanceof HafasError);
|
|
t.equal(err.isHafasError, true);
|
|
t.equal(err.message.slice(0, 11), 'PARAMETER: ');
|
|
t.ok(err.message.length > 11);
|
|
|
|
t.ok(err instanceof HafasInvalidRequestError);
|
|
t.equal(err.isCausedByServer, false);
|
|
t.equal(err.code, INVALID_REQUEST);
|
|
t.equal(err.hafasCode, 'PARAMETER');
|
|
|
|
t.equal(err.hafasResponseId, resParameter.id);
|
|
t.equal(err.hafasMessage, 'HCI Service: parameter invalid');
|
|
t.equal(err.hafasDescription, 'Während der Suche ist ein interner Fehler aufgetreten');
|
|
t.equal(err.secret, secret);
|
|
|
|
t.end();
|
|
}
|
|
});
|
|
|
|
tap.test('checkIfResponseIsOk properly parses an unknown HAFAS errors', (t) => {
|
|
const body = {
|
|
ver: '1.42',
|
|
id: '1234567890',
|
|
err: 'FOO',
|
|
errTxt: 'random errTxt',
|
|
errTxtOut: 'even more random errTxtOut',
|
|
svcResL: [],
|
|
};
|
|
|
|
try {
|
|
checkIfResIsOk({
|
|
body,
|
|
errProps: {secret},
|
|
});
|
|
} catch (err) {
|
|
t.ok(err);
|
|
|
|
t.ok(err instanceof HafasError);
|
|
t.equal(err.isHafasError, true);
|
|
t.equal(err.message, `${body.err}: ${body.errTxt}`);
|
|
|
|
t.equal(err.isCausedByServer, false);
|
|
t.equal(err.code, null);
|
|
t.equal(err.hafasCode, body.err);
|
|
|
|
t.equal(err.hafasResponseId, body.id);
|
|
t.equal(err.hafasMessage, body.errTxt);
|
|
t.equal(err.hafasDescription, body.errTxtOut);
|
|
t.equal(err.secret, secret);
|
|
|
|
t.end();
|
|
}
|
|
});
|
|
|
|
const freeze = (val) => {
|
|
if (
|
|
'object' === typeof val
|
|
&& val !== null
|
|
&& !Array.isArray(val)
|
|
) {
|
|
Object.freeze(val);
|
|
}
|
|
};
|
|
const ctx = {
|
|
// random but unique
|
|
opt: {
|
|
language: 'ga',
|
|
},
|
|
profile: {
|
|
endpoint: 'https://does.not.exist',
|
|
client: {
|
|
type: 'FOO',
|
|
id: 'BAR',
|
|
name: 'baZ',
|
|
},
|
|
auth: {
|
|
type: 'AID',
|
|
aid: 'some-auth-token',
|
|
},
|
|
ver: '1.23.4',
|
|
|
|
timezone: 'Europe/Amsterdam',
|
|
locale: 'de-LU',
|
|
defaultLanguage: 'fr',
|
|
|
|
transformReq: (_, req) => req,
|
|
},
|
|
};
|
|
forEach(ctx, freeze);
|
|
|
|
tap.test('lib/request calls profile.transformReqBody & profile.transformReq properly', async (t) => {
|
|
const customTransformReqBody = (ctx, reqBody) => {
|
|
const p = 'transformReqBody call: ';
|
|
t.same(ctx, customCtx, 'ctx should be the passed-in ctx');
|
|
|
|
t.ok(reqBody, 'reqBody');
|
|
t.equal(reqBody.client, ctx.profile.client, p + 'reqBody.client');
|
|
t.equal(reqBody.ext, ctx.profile.ext, p + 'reqBody.ext');
|
|
t.equal(reqBody.var, ctx.profile.var, p + 'reqBody.var');
|
|
t.equal(reqBody.auth, ctx.profile.auth, p + 'reqBody.auth');
|
|
t.equal(reqBody.lang, ctx.opt.language, p + 'reqBody.lang');
|
|
|
|
// We test if lib/request.js handles returning a new object.
|
|
return {
|
|
...reqBody,
|
|
};
|
|
};
|
|
|
|
const customTransformReq = (ctx, req) => {
|
|
const p = 'transformReq call: ';
|
|
t.same(ctx, customCtx, p + 'ctx should be the passed-in ctx');
|
|
|
|
t.equal(typeof req.body, 'string', p + 'req.body');
|
|
t.ok(req.body, p + 'req.body');
|
|
|
|
// We test if lib/request.js handles returning a new object.
|
|
return {
|
|
...req,
|
|
// From node-fetch, used by isomorphic-fetch:
|
|
// > req/res timeout in ms, it resets on redirect. 0 to disable (OS limit applies). Signal is recommended instead.
|
|
timeout: 100,
|
|
};
|
|
};
|
|
|
|
const customCtx = {
|
|
...ctx,
|
|
profile: {
|
|
...ctx.profile,
|
|
transformReqBody: customTransformReqBody,
|
|
transformReq: customTransformReq,
|
|
},
|
|
};
|
|
const tripReq = formatTripReq(customCtx, 'unknown-trip-id');
|
|
|
|
// todo: set 1s timeout
|
|
await t.rejects(async () => {
|
|
await request(customCtx, USER_AGENT, tripReq);
|
|
});
|
|
t.end();
|
|
});
|