From 98670d5e0846293ca8938197da54c856cb28b867 Mon Sep 17 00:00:00 2001 From: Traines Date: Wed, 8 Jan 2025 23:02:57 +0000 Subject: [PATCH] stop() --- format/stop-req.js | 7 - index.js | 21 +- lib/default-profile.js | 4 +- p/dbnav/base.json | 1 + p/dbnav/index.js | 5 + p/dbnav/parse-stop.js | 47 ++++ p/dbnav/stop-req.js | 16 ++ readme.md | 9 +- test/dbnav-departures.js | 2 +- test/dbnav-refresh-journey.js | 2 +- test/dbnav-stop.js | 25 ++ test/e2e/dbnav.js | 2 +- .../requests_1722637011/recording.har | 136 ++++++++++ test/fixtures/dbnav-stop.js | 247 ++++++++++++++++++ test/fixtures/dbnav-stop.json | 1 + 15 files changed, 493 insertions(+), 32 deletions(-) delete mode 100644 format/stop-req.js create mode 100644 p/dbnav/parse-stop.js create mode 100644 p/dbnav/stop-req.js create mode 100644 test/dbnav-stop.js create mode 100644 test/fixtures/dbnav-stop.js create mode 100644 test/fixtures/dbnav-stop.json diff --git a/format/stop-req.js b/format/stop-req.js deleted file mode 100644 index 6bcdad68..00000000 --- a/format/stop-req.js +++ /dev/null @@ -1,7 +0,0 @@ -const formatStopReq = (ctx, stopRef) => { - // TODO -}; - -export { - formatStopReq, -}; diff --git a/index.js b/index.js index 2a30d330..4436f54e 100644 --- a/index.js +++ b/index.js @@ -4,8 +4,6 @@ import readStations from 'db-hafas-stations'; import {defaultProfile} from './lib/default-profile.js'; import {validateProfile} from './lib/validate-profile.js'; -import {INVALID_REQUEST} from './lib/errors.js'; -import {HafasError} from './lib/errors.js'; // background info: https://github.com/public-transport/hafas-client/issues/286 const FORBIDDEN_USER_AGENTS = [ @@ -254,12 +252,10 @@ const createClient = (profile, userAgent, opt = {}) => { : results; }; - const stop = async (stop, opt = {}) => { // TODO - if ('object' === typeof stop) { - stop = profile.formatStation(stop.id); - } else if ('string' === typeof stop) { - stop = profile.formatStation(stop); - } else { + const stop = async (stop, opt = {}) => { + if (isObj(stop) && stop.id) { + stop = stop.id; + } else if ('string' !== typeof stop) { throw new TypeError('stop must be an object or a string.'); } @@ -273,15 +269,8 @@ const createClient = (profile, userAgent, opt = {}) => { const req = profile.formatStopReq({profile, opt}, stop); const {res} = await profile.request({profile, opt}, userAgent, req); - if (!res || !Array.isArray(res.locL) || !res.locL[0]) { - throw new HafasError('invalid response, expected locL[0]', null, { - // This problem occurs on invalid input. 🙄 - code: INVALID_REQUEST, - }); - } - const ctx = {profile, opt, res, common}; - return profile.parseLocation(ctx, res.locL[0]); + return profile.parseStop(ctx, res, stop); }; const nearby = async (location, opt = {}) => { diff --git a/lib/default-profile.js b/lib/default-profile.js index 42b09bfe..67ac6edf 100644 --- a/lib/default-profile.js +++ b/lib/default-profile.js @@ -3,7 +3,6 @@ import {products} from '../lib/products.js'; import {ageGroup, ageGroupFromAge, ageGroupLabel} from './age-group.js'; import {formatStationBoardReq} from '../format/station-board-req.js'; -import {formatStopReq} from '../format/stop-req.js'; import {formatTripReq} from '../format/trip-req.js'; import {formatNearbyReq} from '../format/nearby-req.js'; @@ -63,7 +62,7 @@ const defaultProfile = { formatStationBoardReq, formatLocationsReq: notImplemented, - formatStopReq, + formatStopReq: notImplemented, formatTripReq, formatNearbyReq, formatJourneysReq: notImplemented, @@ -92,6 +91,7 @@ const defaultProfile = { parseHintByCode, parsePrice, parseTickets, + parseStop: notImplemented, formatAddress, formatCoord, diff --git a/p/dbnav/base.json b/p/dbnav/base.json index d8c036b9..9ad7546f 100644 --- a/p/dbnav/base.json +++ b/p/dbnav/base.json @@ -3,6 +3,7 @@ "refreshJourneysEndpointTickets": "https://app.vendo.noncd.db.de/mob/angebote/recon", "refreshJourneysEndpointPolyline": "https://app.vendo.noncd.db.de/mob/trip/recon", "locationsEndpoint": "https://app.vendo.noncd.db.de/mob/location/search", + "stopEndpoint": "https://app.vendo.noncd.db.de/mob/location/details/", "nearbyEndpoint": "https://app.vendo.noncd.db.de/mob/location/nearby", "tripEndpoint": "https://app.vendo.noncd.db.de/mob/zuglauf/", "boardEndpoint": "https://app.vendo.noncd.db.de/mob/bahnhofstafel/", diff --git a/p/dbnav/index.js b/p/dbnav/index.js index 9d4b2e48..a093c1ce 100644 --- a/p/dbnav/index.js +++ b/p/dbnav/index.js @@ -7,8 +7,10 @@ import {formatJourneysReq, formatRefreshJourneyReq} from './journeys-req.js'; import {formatTripReq} from './trip-req.js'; import {formatLocationFilter} from './location-filter.js'; import {formatLocationsReq} from './locations-req.js'; +import {formatStopReq} from './stop-req.js'; import {formatNearbyReq} from './nearby-req.js'; import {formatStationBoardReq} from './station-board-req.js'; +import {parseStop} from './parse-stop.js'; const profile = { ...baseProfile, @@ -21,8 +23,11 @@ const profile = { formatTripReq, formatNearbyReq, formatLocationsReq, + formatStopReq, formatStationBoardReq, formatLocationFilter, + + parseStop, }; export { diff --git a/p/dbnav/parse-stop.js b/p/dbnav/parse-stop.js new file mode 100644 index 00000000..1caa2def --- /dev/null +++ b/p/dbnav/parse-stop.js @@ -0,0 +1,47 @@ + + +const parseStop = (ctx, l, id) => { + const {profile, common, opt} = ctx; + + if (!l) { + return null; + } + let stop = { + type: 'station', + id: id, + name: l.haltName, + }; + + stop.products = profile.parseProducts(ctx, l.produktGattungen?.map(p => p.produktGattung)); + if (opt.linesOfStops) { + stop.lines = l.produktGattungen?.flatMap(p => { + const foundProduct = profile.products.find(pp => pp.dbnav == p.produktGattung); + return p.produkte?.map(l => { + return { + type: 'line', + name: l.name, + productName: l.name && l.name.split(' ')[0] || undefined, + mode: foundProduct?.mode, + product: foundProduct?.id, + public: true, + }; + }); + }); + } + + if (common && common.locations && common.locations[stop.id]) { + delete stop.type; + stop = { + ...common.locations[stop.id], + ...stop, + }; + } + + // TODO isMeta + // TODO entrances + return stop; +}; + +export { + parseStop, +}; diff --git a/p/dbnav/stop-req.js b/p/dbnav/stop-req.js new file mode 100644 index 00000000..caf054eb --- /dev/null +++ b/p/dbnav/stop-req.js @@ -0,0 +1,16 @@ +import {getHeaders} from './header.js'; + +const formatStopReq = (ctx, stopRef) => { + const {profile} = ctx; + + return { + endpoint: profile.stopEndpoint, + path: stopRef, + headers: getHeaders('application/x.db.vendo.mob.location.v3+json'), + method: 'get', + }; +}; + +export { + formatStopReq, +}; diff --git a/readme.md b/readme.md index 5c4a55de..479d0bce 100644 --- a/readme.md +++ b/readme.md @@ -16,9 +16,9 @@ What doesn't work (yet, see TODO's scattered around the code): * `journeys()` details like scheduledDays, stop/station groups, some line details ... * loadFactor and other details in boards -* certain stop details like products for `locations()` and geopositions and remarks for boards – this can be remedied by turning on `enrichStations` in the options, enriching location info with [db-hafas-stations](https://github.com/derhuerst/db-hafas-stations). +* certain stop details like products for `locations()` and geopositions and remarks for boards – this can be remedied by turning on `enrichStations` in the config, enriching location info with [db-hafas-stations](https://github.com/derhuerst/db-hafas-stations). * some query options/filters (e.g. routingMode for journeys, direction for boards) -* all other endpoints (`tripsByName()`, `radar()`, `journeysFromTrip()`, `reachableFrom()`, `remarks()`, `lines()`, `stop()`, `station()`) +* all other endpoints (`tripsByName()`, `radar()`, `journeysFromTrip()`, `reachableFrom()`, `remarks()`, `lines()`, `station()`) Depending on the configured profile, db-vendo-client will use multiple different DB APIs that offer varying functionality, so choose wisely: @@ -26,11 +26,12 @@ Depending on the configured profile, db-vendo-client will use multiple different | ------------- | ------------- | ------------- | | no API key required | ✅ | ✅ | | max duration boards | 12h | 1h | -| remarks | not for boards | ✅ | +| remarks | not for boards | ✅ (still no `remarks()` endpoint) | | cancelled trips | not contained in boards | contained with cancelled flag | | tickets | only for `refreshJourney()` | only for `refreshJourney()`, mutually exclusive with polylines | | polylines | only for `trip()` | only for `refreshJourney()/trip()`, mutually exclusive with tickets | | trip ids used | HAFAS trip ids for journeys, RIS trip ids for boards | HAFAS trip ids | +| `stop()` | ❌ | ✅ | | assumed backend API stability | less stable | more stable | Feel free to report anything that you stumble upon via Issues or create a PR :) @@ -54,7 +55,7 @@ Use it as a dependency, e.g. just replacing [hafas-client](https://github.com/pu npm i db-vendo-client ``` -See an example in [api.js](api.js). It shows how you can use `db-vendo-client` together with `hafas-rest-api` in order to run a [FPTF](https://github.com/public-transport/friendly-public-transport-format) API server. The [Dockerfile](Dockerfile) serves this API: +See an example in [api.js](api.js). It shows how you can use `db-vendo-client` together with [hafas-rest-api](https://github.com/public-transport/hafas-rest-api/) in order to run a [FPTF](https://github.com/public-transport/friendly-public-transport-format) API server. The [Dockerfile](Dockerfile) serves this API: ``` docker run -e USER_AGENT=my-awesome-program -p 3000:3000 ghcr.io/public-transport/db-vendo-client diff --git a/test/dbnav-departures.js b/test/dbnav-departures.js index 9982cdf6..27ab4afb 100644 --- a/test/dbnav-departures.js +++ b/test/dbnav-departures.js @@ -6,7 +6,7 @@ const require = createRequire(import.meta.url); import tap from 'tap'; import {createClient} from '../index.js'; -import {profile as rawProfile} from '../p/db/index.js'; +import {profile as rawProfile} from '../p/dbnav/index.js'; const res = require('./fixtures/dbnav-departures.json'); import {dbnavDepartures as expected} from './fixtures/dbnav-departures.js'; diff --git a/test/dbnav-refresh-journey.js b/test/dbnav-refresh-journey.js index 77c8e310..b0b5c6e9 100644 --- a/test/dbnav-refresh-journey.js +++ b/test/dbnav-refresh-journey.js @@ -6,7 +6,7 @@ const require = createRequire(import.meta.url); import tap from 'tap'; import {createClient} from '../index.js'; -import {profile as rawProfile} from '../p/db/index.js'; +import {profile as rawProfile} from '../p/dbnav/index.js'; const res = require('./fixtures/dbnav-refresh-journey.json'); import {dbNavJourney as expected} from './fixtures/dbnav-refresh-journey.js'; diff --git a/test/dbnav-stop.js b/test/dbnav-stop.js new file mode 100644 index 00000000..6338f59a --- /dev/null +++ b/test/dbnav-stop.js @@ -0,0 +1,25 @@ +// 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 {createClient} from '../index.js'; +import {profile as rawProfile} from '../p/dbnav/index.js'; +const res = require('./fixtures/dbnav-stop.json'); +import {dbnavDepartures as expected} from './fixtures/dbnav-stop.js'; + +const client = createClient(rawProfile, 'public-transport/hafas-client:test'); +const {profile} = client; + +const opt = { + linesOfStops: true, +}; + +tap.test('parses a dbnav stop correctly', (t) => { + const ctx = {profile, opt, common: null, res}; + const stop = profile.parseStop(ctx, res, '8000096'); + t.same(stop, expected); + t.end(); +}); diff --git a/test/e2e/dbnav.js b/test/e2e/dbnav.js index 0d0b6c81..ce1fd9e3 100644 --- a/test/e2e/dbnav.js +++ b/test/e2e/dbnav.js @@ -476,7 +476,6 @@ tap.test('locations named Jungfernheide', async (t) => { t.end(); }); -/* tap.test('stop', async (t) => { const s = await client.stop(regensburgHbf); @@ -486,6 +485,7 @@ tap.test('stop', async (t) => { t.end(); }); +/* tap.test('line with additionalName', async (t) => { const {departures} = await client.departures(potsdamHbf, { when, diff --git a/test/e2e/fixtures/requests_1722637011/recording.har b/test/e2e/fixtures/requests_1722637011/recording.har index 2c9ea196..1dabb7ce 100644 --- a/test/e2e/fixtures/requests_1722637011/recording.har +++ b/test/e2e/fixtures/requests_1722637011/recording.har @@ -5109,6 +5109,142 @@ "ssl": -1, "wait": 445 } + }, + { + "_id": "d50b6b1f76add52cd3eb6ffa13dea4d4", + "_order": 0, + "cache": {}, + "request": { + "bodySize": 0, + "cookies": [], + "headers": [ + { + "_fromType": "array", + "name": "content-type", + "value": "application/x.db.vendo.mob.location.v3+json" + }, + { + "_fromType": "array", + "name": "accept-encoding", + "value": "gzip, br, deflate" + }, + { + "_fromType": "array", + "name": "accept", + "value": "application/x.db.vendo.mob.location.v3+json" + }, + { + "_fromType": "array", + "name": "accept-language", + "value": "en" + }, + { + "_fromType": "array", + "name": "user-agent", + "value": "public-transport/hafas-client:test" + }, + { + "_fromType": "array", + "name": "connection", + "value": "keep-alive" + }, + { + "_fromType": "array", + "name": "x-correlation-id", + "value": "null" + }, + { + "name": "host", + "value": "app.vendo.noncd.db.de" + } + ], + "headersSize": 369, + "httpVersion": "HTTP/1.1", + "method": "GET", + "queryString": [], + "url": "https://app.vendo.noncd.db.de/mob/location/details/8000309" + }, + "response": { + "bodySize": 1945, + "content": { + "mimeType": "application/x.db.vendo.mob.location.v3+json", + "size": 1945, + "text": "{\"haltName\":\"Regensburg Hbf\",\"produktGattungen\":[{\"produktGattung\":\"HOCHGESCHWINDIGKEITSZUEGE\",\"produkte\":[{\"name\":\"ICE\"}]},{\"produktGattung\":\"INTERCITYUNDEUROCITYZUEGE\",\"produkte\":[{\"name\":\"IC\"},{\"name\":\"NJ\"}]},{\"produktGattung\":\"INTERREGIOUNDSCHNELLZUEGE\",\"produkte\":[{\"name\":\"BUS\"}]},{\"produktGattung\":\"NAHVERKEHRSONSTIGEZUEGE\",\"produkte\":[{\"name\":\"ALX\"},{\"name\":\"OPB\"},{\"name\":\"RB\"},{\"name\":\"RE\"},{\"name\":\"ag\"},{\"name\":\"Bus EV\"},{\"name\":\"Bus EV\"},{\"name\":\"Bus EV\"},{\"name\":\"Bus EV\"},{\"name\":\"Bus RB23\"},{\"name\":\"Bus RE23\"},{\"name\":\"Bus RE25\"}]},{\"produktGattung\":\"BUSSE\",\"produkte\":[{\"name\":\"Bus 1\"},{\"name\":\"Bus 2\"},{\"name\":\"Bus 3\"},{\"name\":\"Bus 4\"},{\"name\":\"Bus 5\"},{\"name\":\"Bus 5\"},{\"name\":\"Bus 5A\"},{\"name\":\"Bus 6\"},{\"name\":\"Bus 7\"},{\"name\":\"Bus 8\"},{\"name\":\"Bus 8A\"},{\"name\":\"Bus 9\"},{\"name\":\"Bus 10\"},{\"name\":\"Bus 11\"},{\"name\":\"Bus 11A\"},{\"name\":\"Bus 12\"},{\"name\":\"Bus 13\"},{\"name\":\"Bus 14\"},{\"name\":\"Bus 15\"},{\"name\":\"Bus 16\"},{\"name\":\"Bus 17\"},{\"name\":\"Bus 18\"},{\"name\":\"Bus 19\"},{\"name\":\"Bus 20\"},{\"name\":\"Bus 21\"},{\"name\":\"Bus 22\"},{\"name\":\"Bus 23\"},{\"name\":\"Bus 24\"},{\"name\":\"Bus 26\"},{\"name\":\"Bus 27\"},{\"name\":\"Bus 28\"},{\"name\":\"Bus 29\"},{\"name\":\"Bus 30\"},{\"name\":\"Bus 31\"},{\"name\":\"Bus 32\"},{\"name\":\"Bus 33\"},{\"name\":\"Bus 34\"},{\"name\":\"Bus 35\"},{\"name\":\"Bus 38\"},{\"name\":\"Bus 41\"},{\"name\":\"Bus 42\"},{\"name\":\"Bus 43\"},{\"name\":\"Bus 71\"},{\"name\":\"Bus 73\"},{\"name\":\"Bus 73\"},{\"name\":\"Bus 73\"},{\"name\":\"Bus 75\"},{\"name\":\"Bus 77\"},{\"name\":\"Bus 80\"},{\"name\":\"Bus 105\"},{\"name\":\"Bus 117\"},{\"name\":\"Bus 6010\"},{\"name\":\"Bus A\"},{\"name\":\"Bus C1\"},{\"name\":\"Bus C6\"},{\"name\":\"Bus D\"},{\"name\":\"Bus DULT\"},{\"name\":\"Bus N1\"},{\"name\":\"Bus N2\"},{\"name\":\"Bus N3\"},{\"name\":\"Bus N4\"},{\"name\":\"Bus N5\"},{\"name\":\"Bus N6\"},{\"name\":\"Bus N7\"},{\"name\":\"Bus X1\"},{\"name\":\"Bus X4\"},{\"name\":\"Bus X6\"},{\"name\":\"Bus X9\"},{\"name\":\"Bus21/24\"},{\"name\":\"Bus26/27\"},{\"name\":\"Bus36/37\"}]},{\"produktGattung\":\"ANRUFPFLICHTIGEVERKEHRE\",\"produkte\":[{\"name\":\"RUF 32\"}]}]}" + }, + "cookies": [ + { + "domain": ".app.vendo.noncd.db.de", + "httpOnly": true, + "name": "TS01be2125", + "path": "/", + "secure": true, + "value": "01d513bcd1b9bf9e9663294318145959b6eb5e2a2b5df7da01060b1dc5e7ff5985ac13cb509abfbace0e7798ec534a603b2c68e08c" + } + ], + "headers": [ + { + "name": "date", + "value": "Wed, 08 Jan 2025 22:50:18 GMT" + }, + { + "name": "content-type", + "value": "application/x.db.vendo.mob.location.v3+json" + }, + { + "name": "content-length", + "value": "1945" + }, + { + "name": "connection", + "value": "keep-alive" + }, + { + "name": "server-timing", + "value": "intid;desc=6025e1514766819a, intid;desc=6025e1514766819a, intid;desc=6025e1514766819a, intid;desc=6025e1514766819a" + }, + { + "name": "x-correlation-id", + "value": "null" + }, + { + "name": "strict-transport-security", + "value": "max-age=16070400; includeSubDomains" + }, + { + "name": "x-xss-protection", + "value": "0" + }, + { + "name": "content-security-policy", + "value": "frame-ancestors 'none';" + }, + { + "name": "x-content-type-options", + "value": "nosniff" + }, + { + "_fromType": "array", + "name": "set-cookie", + "value": "TS01be2125=01d513bcd1b9bf9e9663294318145959b6eb5e2a2b5df7da01060b1dc5e7ff5985ac13cb509abfbace0e7798ec534a603b2c68e08c; Path=/; Domain=.app.vendo.noncd.db.de; Secure; HTTPOnly" + } + ], + "headersSize": 655, + "httpVersion": "HTTP/1.1", + "redirectURL": "", + "status": 200, + "statusText": "OK" + }, + "startedDateTime": "2025-01-08T22:50:18.535Z", + "time": 170, + "timings": { + "blocked": -1, + "connect": -1, + "dns": -1, + "receive": 0, + "send": 0, + "ssl": -1, + "wait": 170 + } } ], "pages": [], diff --git a/test/fixtures/dbnav-stop.js b/test/fixtures/dbnav-stop.js new file mode 100644 index 00000000..f10612a9 --- /dev/null +++ b/test/fixtures/dbnav-stop.js @@ -0,0 +1,247 @@ +const dbnavDepartures = { + type: 'station', + name: 'Stuttgart Hbf', + id: '8000096', + products: { + nationalExpress: true, + national: true, + regionalExpress: true, + regional: true, + suburban: true, + bus: true, + ferry: false, + subway: false, + tram: true, + taxi: false, + }, + lines: [ + { + type: 'line', + name: 'ICE', + productName: 'ICE', + mode: 'train', + product: 'nationalExpress', + public: true, + }, + { + type: 'line', + name: 'RJ', + productName: 'RJ', + mode: 'train', + product: 'nationalExpress', + public: true, + }, + { + type: 'line', + name: 'RJX', + productName: 'RJX', + mode: 'train', + product: 'nationalExpress', + public: true, + }, + { + type: 'line', + name: 'TGV', + productName: 'TGV', + mode: 'train', + product: 'nationalExpress', + public: true, + }, + { + type: 'line', + name: 'EC', + productName: 'EC', + mode: 'train', + product: 'national', + public: true, + }, + { + type: 'line', + name: 'IC', + productName: 'IC', + mode: 'train', + product: 'national', + public: true, + }, + { + type: 'line', + name: 'NJ', + productName: 'NJ', + mode: 'train', + product: 'national', + public: true, + }, + { + type: 'line', + name: 'BUS', + productName: 'BUS', + mode: 'train', + product: 'regionalExpress', + public: true, + }, + { + type: 'line', + name: 'Bus', + productName: 'Bus', + mode: 'train', + product: 'regionalExpress', + public: true, + }, + { + type: 'line', + name: 'D', + productName: 'D', + mode: 'train', + product: 'regionalExpress', + public: true, + }, + { + type: 'line', + name: 'DBK', + productName: 'DBK', + mode: 'train', + product: 'regionalExpress', + public: true, + }, + { + type: 'line', + name: 'EN', + productName: 'EN', + mode: 'train', + product: 'regionalExpress', + public: true, + }, + { + type: 'line', + name: 'FLX', + productName: 'FLX', + mode: 'train', + product: 'regionalExpress', + public: true, + }, + { + type: 'line', + name: 'WB', + productName: 'WB', + mode: 'train', + product: 'regionalExpress', + public: true, + }, + { + type: 'line', + name: 'GA', + productName: 'GA', + mode: 'train', + product: 'regional', + public: true, + }, + { + type: 'line', + name: 'IRE', + productName: 'IRE', + mode: 'train', + product: 'regional', + public: true, + }, + { + type: 'line', + name: 'MEX', + productName: 'MEX', + mode: 'train', + product: 'regional', + public: true, + }, + { + type: 'line', + name: 'RB', + productName: 'RB', + mode: 'train', + product: 'regional', + public: true, + }, + { + type: 'line', + name: 'RE', + productName: 'RE', + mode: 'train', + product: 'regional', + public: true, + }, + { + type: 'line', + name: 'Bus EV', + productName: 'Bus', + mode: 'train', + product: 'regional', + public: true, + }, + { + type: 'line', + name: 'BusMEX90', + productName: 'BusMEX90', + mode: 'train', + product: 'regional', + public: true, + }, + { + type: 'line', + name: 'S 1', + productName: 'S', + mode: 'train', + product: 'suburban', + public: true, + }, + { + type: 'line', + name: 'S 2', + productName: 'S', + mode: 'train', + product: 'suburban', + public: true, + }, + { + type: 'line', + name: 'Bus 40', + productName: 'Bus', + mode: 'bus', + product: 'bus', + public: true, + }, + { + type: 'line', + name: 'Bus 42', + productName: 'Bus', + mode: 'bus', + product: 'bus', + public: true, + }, + { + type: 'line', + name: 'BusMEX90', + productName: 'BusMEX90', + mode: 'bus', + product: 'bus', + public: true, + }, + { + type: 'line', + name: 'STB U1', + productName: 'STB', + mode: 'train', + product: 'tram', + public: true, + }, + { + type: 'line', + name: 'STB U5', + productName: 'STB', + mode: 'train', + product: 'tram', + public: true, + }, + ], +}; + +export { + dbnavDepartures, +}; diff --git a/test/fixtures/dbnav-stop.json b/test/fixtures/dbnav-stop.json new file mode 100644 index 00000000..c6e0c2a0 --- /dev/null +++ b/test/fixtures/dbnav-stop.json @@ -0,0 +1 @@ +{"haltName":"Stuttgart Hbf","produktGattungen":[{"produktGattung":"HOCHGESCHWINDIGKEITSZUEGE","produkte":[{"name":"ICE"},{"name":"RJ"},{"name":"RJX"},{"name":"TGV"}]},{"produktGattung":"INTERCITYUNDEUROCITYZUEGE","produkte":[{"name":"EC"},{"name":"IC"},{"name":"NJ"}]},{"produktGattung":"INTERREGIOUNDSCHNELLZUEGE","produkte":[{"name":"BUS"},{"name":"Bus"},{"name":"D"},{"name":"DBK"},{"name":"EN"},{"name":"FLX"},{"name":"WB"}]},{"produktGattung":"NAHVERKEHRSONSTIGEZUEGE","produkte":[{"name":"GA"},{"name":"IRE"},{"name":"MEX"},{"name":"RB"},{"name":"RE"},{"name":"Bus EV"},{"name":"BusMEX90"}]},{"produktGattung":"SBAHNEN","produkte":[{"name":"S 1"},{"name":"S 2"}]},{"produktGattung":"BUSSE","produkte":[{"name":"Bus 40"},{"name":"Bus 42"},{"name":"BusMEX90"}]},{"produktGattung":"STRASSENBAHN","produkte":[{"name":"STB U1"},{"name":"STB U5"}]}]} \ No newline at end of file