2022-05-07 16:17:37 +02:00
// 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 )
2022-01-04 15:32:16 +01:00
2022-05-07 16:17:37 +02:00
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' )
2022-01-04 15:32:16 +01:00
const USER _AGENT = 'public-transport/hafas-client:test'
2022-05-07 16:17:37 +02:00
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 ( )
}
} )
2022-01-04 15:32:16 +01:00
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 ( )
} )