├── .gitignore
├── .editorconfig
├── .npmignore
├── .travis.yml
├── exampleRequests
├── getServiceDetails.xml
├── getNextArrival.xml
├── getNextDeparture.xml
├── getFastestDeparturesRequest.xml
├── getArrivalBoard.xml
├── ArrivalBoardOptions.xml
├── getDepartureBoard.xml
├── getNextDeparturesWithDetailsRequest.xml
├── getFastestDeparturesWithDetailsRequest.xml
├── getArrivalBoardWithDetails.xml
├── getArrivalDepartureBoard.xml
├── getDepartureBoardWithDetails.xml
├── getArrDepBoardWithDetailsRequest.xml
└── generateRequests.js
├── CHANGELOG.md
├── .github
└── ISSUE_TEMPLATE
│ └── bug_report.md
├── package.json
├── LICENSE
├── test
├── templateStringTest.js
├── clientTest.js
├── requestTest.js
└── test.js
├── exampleResponses
├── nextDeparture.xml
├── fastestDeparture.xml
├── arrivalBoardWithDets_bus.xml
├── nextDepartureWithDetails.xml
├── fastestDeparturesWithDetails.xml
├── arrivalBoardWithDets.xml
├── serviceDetails.xml
├── arrivalsBoard.xml
├── departureBoard.xml
├── arrivalDepartureBoard.xml
└── departureBoardWithDetails.xml
├── requestBuilder.js
├── templates.js
├── bin
└── darwin.js
├── index.js
├── README.md
└── parsers.js
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules/
2 | token.txt
3 | .nyc_output
4 |
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | [*]
2 | end_of_line = lf
3 | insert_final_newline = true
4 | indent_style = space
5 | indent_size = 4
6 |
--------------------------------------------------------------------------------
/.npmignore:
--------------------------------------------------------------------------------
1 | .editorconfig
2 | token.txt
3 | exampleResponses
4 | exampleRequests
5 | .nyc_output
6 | change.log
7 | test
8 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: node_js
2 | node_js:
3 | - "lts/*"
4 | script:
5 | - mocha "./test/**/!(clientTest).js"
6 |
--------------------------------------------------------------------------------
/exampleRequests/getServiceDetails.xml:
--------------------------------------------------------------------------------
1 | $$TOKEN$$123456789
2 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | ### 1.0.6 [2018-01-11]
2 |
3 | 1. Upgrade to version 11 of the API wasn't completed fully in v1.0.5. Fixed in this release.
4 | 2. darwin command line tool for requests.
5 |
6 | ### 1.0.5 [2018-01-11]
7 |
8 | 1. Update National Rail base url to point to version 11 of the Darwin api.
9 | 2. Increase unit test coverage of requests and parsers.
10 | 3. Bug fix in apply options that caused incorrect defaults to be used if no options object passed to a function.
11 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/bug_report.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Bug report
3 | about: Create a report to help us improve
4 | title: ''
5 | labels: ''
6 | assignees: ''
7 |
8 | ---
9 |
10 | **Describe the bug**
11 | A clear and concise description of what the bug is.
12 |
13 | **To Reproduce**
14 | Steps to reproduce the behavior:
15 |
16 | **Expected behavior**
17 | A clear and concise description of what you expected to happen.
18 |
19 | **Additional context**
20 | Add any other context about the problem here.
21 |
--------------------------------------------------------------------------------
/exampleRequests/getNextArrival.xml:
--------------------------------------------------------------------------------
1 | $$TOKEN$$ISL WAT0120
2 |
--------------------------------------------------------------------------------
/exampleRequests/getNextDeparture.xml:
--------------------------------------------------------------------------------
1 | $$TOKEN$$ISL WAT0120
2 |
--------------------------------------------------------------------------------
/exampleRequests/getFastestDeparturesRequest.xml:
--------------------------------------------------------------------------------
1 | $$TOKEN$$ISL WAT0120
2 |
--------------------------------------------------------------------------------
/exampleRequests/getArrivalBoard.xml:
--------------------------------------------------------------------------------
1 | $$TOKEN$$15ISLto0120
2 |
--------------------------------------------------------------------------------
/exampleRequests/ArrivalBoardOptions.xml:
--------------------------------------------------------------------------------
1 | $$TOKEN$$5ISLWATto560
2 |
--------------------------------------------------------------------------------
/exampleRequests/getDepartureBoard.xml:
--------------------------------------------------------------------------------
1 | $$TOKEN$$15ISLto0120
2 |
--------------------------------------------------------------------------------
/exampleRequests/getNextDeparturesWithDetailsRequest.xml:
--------------------------------------------------------------------------------
1 | $$TOKEN$$ISL WAT0120
2 |
--------------------------------------------------------------------------------
/exampleRequests/getFastestDeparturesWithDetailsRequest.xml:
--------------------------------------------------------------------------------
1 | $$TOKEN$$ISL WAT0120
2 |
--------------------------------------------------------------------------------
/exampleRequests/getArrivalBoardWithDetails.xml:
--------------------------------------------------------------------------------
1 | $$TOKEN$$15ISLto0120
2 |
--------------------------------------------------------------------------------
/exampleRequests/getArrivalDepartureBoard.xml:
--------------------------------------------------------------------------------
1 | $$TOKEN$$15ISLto0120
2 |
--------------------------------------------------------------------------------
/exampleRequests/getDepartureBoardWithDetails.xml:
--------------------------------------------------------------------------------
1 | $$TOKEN$$15ISLto0120
2 |
--------------------------------------------------------------------------------
/exampleRequests/getArrDepBoardWithDetailsRequest.xml:
--------------------------------------------------------------------------------
1 | $$TOKEN$$15ISLto0120
2 |
--------------------------------------------------------------------------------
/exampleRequests/generateRequests.js:
--------------------------------------------------------------------------------
1 | /**
2 | Creates a complete set of requests for se with testing
3 | */
4 |
5 | var requestBuilder = require('../requestBuilder.js')
6 |
7 | console.log(requestBuilder.getDepartureBoardRequest('ISL', {}))
8 | console.log(requestBuilder.getDepartureBoardWithDetails('ISL', {}))
9 | console.log(requestBuilder.getArrivalsBoard('ISL', {}))
10 | console.log(requestBuilder.getArrivalsBoardWithDetails('ISL', {}))
11 | console.log(requestBuilder.getArrivalsDepartureBoard('ISL', {}))
12 | console.log(requestBuilder.getArrivalsDepartureBoardWithDetails('ISL', {}))
13 | console.log(requestBuilder.getServiceDetails('123456789', {}))
14 | console.log(requestBuilder.getNextDeparture('ISL', 'WAT', {}))
15 | console.log(requestBuilder.getNextDepartureWithDetails('ISL', 'WAT', {}))
16 | console.log(requestBuilder.getArrival('ISL', 'WAT', {}))
17 | console.log(requestBuilder.getFastestDeparture('ISL', 'WAT', {}))
18 | console.log(requestBuilder.getFastestDepartureWithDetails('ISL', 'WAT', {}))
19 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "national-rail-darwin",
3 | "version": "1.0.8",
4 | "description": " national rail's darwin soap based api",
5 | "main": "index.js",
6 | "bin": {
7 | "darwin": "bin/darwin.js"
8 | },
9 | "scripts": {
10 | "test": "nyc mocha"
11 | },
12 | "repository": {
13 | "type": "git",
14 | "url": "git+https://github.com/d5039m/national-rail-darwin.git"
15 | },
16 | "keywords": [
17 | "national-rail",
18 | "darwin",
19 | "trains",
20 | "rail"
21 | ],
22 | "author": "Matthew Salt",
23 | "license": "MIT",
24 | "bugs": {
25 | "url": "https://github.com/d5039m/national-rail-darwin/issues"
26 | },
27 | "homepage": "https://github.com/d5039m/national-rail-darwin#readme",
28 | "dependencies": {
29 | "bluebird": "3.4.6",
30 | "commander": "^2.13.0",
31 | "request": "^2.85.0",
32 | "xmldoc": "0.5.1"
33 | },
34 | "devDependencies": {
35 | "assert": "^1.4.1",
36 | "mocha": "^4.0.1",
37 | "nyc": "^14.1.1",
38 | "standard": "^8.6.0"
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2016 Matthew Salt
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/test/templateStringTest.js:
--------------------------------------------------------------------------------
1 | // var parsers = require('../parsers.js')
2 | // var fs = require('fs')
3 | // var fileContent
4 | // fileContent = fs.readFileSync('./exampleResponses/serviceDetails.xml', 'UTF-8')
5 | // parsers.parseServiceIdResponse(fileContent)
6 |
7 | // fileContent = fs.readFileSync('./exampleResponses/nextDepartureWithDetails.xml', 'UTF-8')
8 | // parsers.parseNextDepartureWithDetailsResponse(fileContent)
9 |
10 | // fileContent = fs.readFileSync('./exampleResponses/fastestDeparturesWithDetails.xml', 'UTF-8')
11 | // parsers.parseFastestDeparturesWithDetail(fileContent)
12 |
13 | // fileContent = fs.readFileSync('./exampleResponses/fastestDeparture.xml', 'UTF-8')
14 | // parsers.parseFastestDeparture(fileContent)
15 |
16 | // fileContent = fs.readFileSync('./exampleResponses/arrivalBoardWithDets.xml', 'UTF-8')
17 | // parsers.parseArrivalsBoardWithDetails(fileContent)
18 |
19 | // fileContent = fs.readFileSync('./exampleResponses/arrivalDepartureBoard.xml', 'UTF-8')
20 | // parsers.parseArrivalsDepartureBoard(fileContent)
21 |
22 | // fileContent = fs.readFileSync('./exampleResponses/arrivalDepartureBoardWithDetails.xml', 'UTF-8')
23 | // parsers.parseArrivalsDepartureBoardWithDetails(fileContent)
24 |
25 | // fileContent = fs.readFileSync('./exampleResponses/arrivalsBoard.xml', 'UTF-8')
26 | // parsers.parseArrivalsBoardResponse(fileContent)
27 |
28 | // fileContent = fs.readFileSync('./exampleResponses/departureBoard.xml', 'UTF-8')
29 | // parsers.parseDepartureBoardResponse(fileContent)
30 |
31 | // fileContent = fs.readFileSync('./exampleResponses/departureBoardWithDetails.xml', 'UTF-8')
32 | // parsers.parseDepartureBoardWithDetailsResponse(fileContent)
33 |
34 | // fileContent = fs.readFileSync('./exampleResponses/nextDeparture.xml', 'UTF-8')
35 | // parsers.parseNextDestinationResponse(fileContent)
36 |
--------------------------------------------------------------------------------
/exampleResponses/nextDeparture.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | 2018-01-11T18:34:01.9836252+00:00
6 | Isleworth
7 | ISL
8 | true
9 |
10 |
11 |
12 | 18:34
13 | On time
14 | 18:34
15 | On time
16 | 1
17 | South Western Railway
18 | SW
19 | train
20 | 10
21 | wfmF+NYLrCpeoJVHBxSxrQ==
22 | SW182100
23 |
24 |
25 | London Waterloo
26 | WAT
27 |
28 |
29 |
30 |
31 | London Waterloo
32 | WAT
33 | via Brentford
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
--------------------------------------------------------------------------------
/exampleResponses/fastestDeparture.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | 2018-01-11T18:33:01.3148363+00:00
6 | Isleworth
7 | ISL
8 | true
9 |
10 |
11 |
12 | 18:34
13 | On time
14 | 18:34
15 | On time
16 | 1
17 | South Western Railway
18 | SW
19 | train
20 | 10
21 | wfmF+NYLrCpeoJVHBxSxrQ==
22 | SW182100
23 |
24 |
25 | London Waterloo
26 | WAT
27 |
28 |
29 |
30 |
31 | London Waterloo
32 | WAT
33 | via Brentford
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
--------------------------------------------------------------------------------
/test/clientTest.js:
--------------------------------------------------------------------------------
1 | var fs = require('fs')
2 | var path = require('path')
3 | var token = fs.readFileSync(path.resolve('.', 'token.txt'), 'UTF-8').trim()
4 | var requestBuilder = require('../requestBuilder.js')
5 |
6 | var Rail = require('../index.js')
7 | var client = new Rail(token.trim())
8 |
9 | client.thenablePOST(requestBuilder.getArrivalsBoardWithDetails('ISL', {'destination': 'WAT'})).then(function (result) {
10 | console.log('1) Success')
11 | }).catch(function (err) {
12 | console.log('1) Error: ' + err)
13 | })
14 | client.thenablePOST(requestBuilder.getArrivalsBoard('ISL', {})).then(function (result) {
15 | console.log('2) Success')
16 | }).catch(function (err) {
17 | console.log('2) Error: ' + err)
18 | })
19 | client.thenablePOST(requestBuilder.getArrivalsBoardWithDetails('ISL', {})).then(function (result) {
20 | console.log('3) Success')
21 | }).catch(function (err) {
22 | console.log('3) Error: ' + err)
23 | })
24 | client.thenablePOST(requestBuilder.getArrivalsDepartureBoard('ISL', {})).then(function (result) {
25 | console.log('4) Success')
26 | }).catch(function (err) {
27 | console.log('4) Error: ' + err)
28 | })
29 | client.thenablePOST(requestBuilder.getDepartureBoardRequest('ISL', {})).then(function (result) {
30 | console.log('5) Success')
31 | }).catch(function (err) {
32 | console.log('5) Error: ' + err)
33 | })
34 | client.thenablePOST(requestBuilder.getDepartureBoardWithDetails('ISL', {})).then(function (result) {
35 | console.log('6) Success')
36 | }).catch(function (err) {
37 | console.log('6) Error: ' + err)
38 | })
39 | client.thenablePOST(requestBuilder.getFastestDeparture('ISL', 'WAT', {})).then(function (result) {
40 | console.log('7) Success')
41 | }).catch(function (err) {
42 | console.log('7) Error: ' + err)
43 | })
44 | client.thenablePOST(requestBuilder.getFastestDepartureWithDetails('ISL', 'WAT', {})).then(function (result) {
45 | console.log('8) Success')
46 | }).catch(function (err) {
47 | console.log('8) Error: ' + err)
48 | })
49 | client.thenablePOST(requestBuilder.getNextDepartureWithDetails('ISL', 'WAT', {})).then(function (result) {
50 | console.log('9) Success')
51 | }).catch(function (err) {
52 | console.log('9) Error: ' + err)
53 | })
54 | client.thenablePOST(requestBuilder.getNextDeparture('ISL', 'WAT', {})).then(function (result) {
55 | console.log('10) Success')
56 | }).catch(function (err) {
57 | console.log('10) Error: ' + err)
58 | })
59 | client.thenablePOST(requestBuilder.getArrival('ISL', 'WAT', {})).then(function (result) {
60 | console.log('11) Success')
61 | }).catch(function (err) {
62 | console.log('11) Error: ' + err)
63 | })
64 | client.thenablePOST(requestBuilder.getServiceDetails('123456789', {})).then(function (result) {
65 | console.log('12) Success')
66 | }).catch(function (err) {
67 | console.log('12) Error: ' + err.statusCode + ' ' + err.body)
68 | })
69 |
--------------------------------------------------------------------------------
/test/requestTest.js:
--------------------------------------------------------------------------------
1 | /* eslint-env mocha */
2 |
3 | /*
4 | Test that request xmls build by the requestBuilder match what we're expecting.
5 | */
6 | var assert = require('assert')
7 | var requestBuilder = require('../requestBuilder.js')
8 | var fs = require('fs')
9 |
10 | describe('Check request xmls build correctly', function () {
11 | it('Arrival Departure Board with Details', function () {
12 | var fileContent = fs.readFileSync('./exampleRequests/getArrDepBoardWithDetailsRequest.xml', 'UTF-8')
13 | var request = requestBuilder.getArrivalsDepartureBoardWithDetails('ISL')
14 | assert.equal(request, fileContent.trim('string'))
15 | })
16 |
17 | it('Get Arrival Board', function () {
18 | var fileContent = fs.readFileSync('./exampleRequests/getArrivalBoard.xml', 'UTF-8')
19 | var request = requestBuilder.getArrivalsBoard('ISL', {})
20 | assert.equal(request, fileContent.trim('string'))
21 | })
22 |
23 | it('Get Arrival Board with options', function () {
24 | var fileContent = fs.readFileSync('./exampleRequests/ArrivalBoardOptions.xml', 'UTF-8')
25 | var request = requestBuilder.getArrivalsBoard('ISL',
26 | {'timeOffset': 5, 'timeWindow': 60, 'rows': 5, 'destination': 'WAT'})
27 | assert.equal(request, fileContent.trim('string'))
28 | })
29 |
30 | it('Get Arrival Board with Details', function () {
31 | var fileContent = fs.readFileSync('./exampleRequests/getArrivalBoardWithDetails.xml', 'UTF-8')
32 | var request = requestBuilder.getArrivalsBoardWithDetails('ISL', {})
33 | assert.equal(request, fileContent.trim('string'))
34 | })
35 |
36 | it('Get Arrival Departure Board', function () {
37 | var fileContent = fs.readFileSync('./exampleRequests/getArrivalDepartureBoard.xml', 'UTF-8')
38 | var request = requestBuilder.getArrivalsDepartureBoard('ISL', {})
39 | assert.equal(request, fileContent.trim('string'))
40 | })
41 |
42 | it('Get Departure Board', function () {
43 | var fileContent = fs.readFileSync('./exampleRequests/getDepartureBoard.xml', 'UTF-8')
44 | var request = requestBuilder.getDepartureBoardRequest('ISL', {})
45 | assert.equal(request, fileContent.trim('string'))
46 | })
47 |
48 | it('Get Departure Board with Details', function () {
49 | var fileContent = fs.readFileSync('./exampleRequests/getDepartureBoardWithDetails.xml', 'UTF-8')
50 | var request = requestBuilder.getDepartureBoardWithDetails('ISL', {})
51 | assert.equal(request, fileContent.trim('string'))
52 | })
53 |
54 | it('Get Fastest Departures Request', function () {
55 | var fileContent = fs.readFileSync('./exampleRequests/getFastestDeparturesRequest.xml', 'UTF-8')
56 | var request = requestBuilder.getFastestDeparture('ISL', 'WAT', {})
57 | assert.equal(request, fileContent.trim('string'))
58 | })
59 |
60 | it('Get Fastest Departures With Details Request', function () {
61 | var fileContent = fs.readFileSync('./exampleRequests/getFastestDeparturesWithDetailsRequest.xml', 'UTF-8')
62 | var request = requestBuilder.getFastestDepartureWithDetails('ISL', 'WAT', {})
63 | assert.equal(request, fileContent.trim('string'))
64 | })
65 |
66 | it('Get Next Departures with Details Request', function () {
67 | var fileContent = fs.readFileSync('./exampleRequests/getNextDeparturesWithDetailsRequest.xml', 'UTF-8')
68 | var request = requestBuilder.getNextDepartureWithDetails('ISL', 'WAT', {})
69 | assert.equal(request, fileContent.trim('string'))
70 | })
71 |
72 | it('Get Next Departures Request', function () {
73 | var fileContent = fs.readFileSync('./exampleRequests/getNextDeparture.xml', 'UTF-8')
74 | var request = requestBuilder.getNextDeparture('ISL', 'WAT', {})
75 | assert.equal(request, fileContent.trim('string'))
76 | })
77 |
78 | it('Get Arrival (getNextArrival) test', function () {
79 | var fileContent = fs.readFileSync('./exampleRequests/getNextArrival.xml', 'UTF-8')
80 | var request = requestBuilder.getArrival('ISL', 'WAT', {})
81 | assert.equal(request, fileContent.trim('string'))
82 | })
83 |
84 | it('Get Service Details', function () {
85 | var fileContent = fs.readFileSync('./exampleRequests/getServiceDetails.xml', 'UTF-8')
86 | var request = requestBuilder.getServiceDetails('123456789', {})
87 | assert.equal(request, fileContent.trim('string'))
88 | })
89 | })
90 |
--------------------------------------------------------------------------------
/requestBuilder.js:
--------------------------------------------------------------------------------
1 | var templates = require('./templates.js')
2 |
3 | function applyOptions (requestXML, options) {
4 | var optionDefaults = {
5 | timeOffset: [ 0, 'INT' ],
6 | timeWindow: [ 120, 'INT' ],
7 | rows: [ 15, 'INT' ],
8 | destination: [ '', 'TEXT' ]
9 | }
10 | for (var key in optionDefaults) {
11 | var value = optionDefaults[key][0]
12 | if (options && options[key]) {
13 | if (optionDefaults[key][1] === 'INT') value = parseInt(options[key])
14 | else value = options[key]
15 | }
16 | requestXML = requestXML.replace('$$' + key.toUpperCase() + '$$', value)
17 | }
18 | return requestXML
19 | }
20 |
21 | var getDepartureBoardRequest = function (station, options) {
22 | var requestXML = applyOptions(templates.departureBoard, options)
23 | requestXML = requestXML.replace('$$FROM$$', station)
24 | return requestXML
25 | }
26 |
27 | var getDepartureBoardWithDetails = function (station, options) {
28 | var requestXML = applyOptions(templates.departureBoardWithDetails, options)
29 | requestXML = requestXML.replace('$$FROM$$', station)
30 | return requestXML
31 | }
32 |
33 | var getArrivalsBoard = function (station, options) {
34 | var requestXML = applyOptions(templates.arrivalsBoard, options)
35 | requestXML = requestXML.replace('$$FROM$$', station)
36 | return requestXML
37 | }
38 |
39 | var getArrivalsBoardWithDetails = function (station, options) {
40 | var requestXML = applyOptions(templates.arrivalsBoardWithDetails, options)
41 | requestXML = requestXML.replace('$$FROM$$', station)
42 | return requestXML
43 | }
44 | var getArrivalsDepartureBoard = function (station, options) {
45 | var requestXML = applyOptions(templates.arrivalsDepartureBoard, options)
46 | requestXML = requestXML.replace('$$FROM$$', station)
47 | return requestXML
48 | }
49 | var getArrivalsDepartureBoardWithDetails = function (station, options) {
50 | var requestXML = applyOptions(templates.arrivalsDepartureBoardWithDetails, options)
51 | requestXML = requestXML.replace('$$FROM$$', station)
52 | return requestXML
53 | }
54 | var getServiceDetails = function (serviceId) {
55 | var requestXML = templates.serviceDetails.replace('$$SERVICEID$$', serviceId)
56 | return requestXML
57 | }
58 | var getNextDeparture = function (station, destination, options) {
59 | options.destination = destination
60 | var requestXML = applyOptions(templates.nextDeparture, options)
61 | requestXML = requestXML.replace('$$FROM$$', station)
62 | return requestXML
63 | }
64 | var getNextDepartureWithDetails = function (station, destination, options) {
65 | options.destination = destination
66 | var requestXML = applyOptions(templates.nextDepartureWithDetails, options)
67 | requestXML = requestXML.replace('$$FROM$$', station)
68 | return requestXML
69 | }
70 | var getArrival = function (station, destination, options) {
71 | options.destination = destination
72 | var requestXML = applyOptions(templates.nextArrival, options)
73 | requestXML = requestXML.replace('$$FROM$$', station)
74 | return requestXML
75 | }
76 | var getFastestDeparture = function (station, destination, options) {
77 | options.destination = destination
78 | var requestXML = applyOptions(templates.fastestDeparture, options)
79 | requestXML = requestXML.replace('$$FROM$$', station)
80 | return requestXML
81 | }
82 | var getFastestDepartureWithDetails = function (station, destination, options) {
83 | options.destination = destination
84 | var requestXML = applyOptions(templates.fastestDepartureWithDetails, options)
85 | requestXML = requestXML.replace('$$FROM$$', station)
86 | return requestXML
87 | }
88 | module.exports.getDepartureBoardRequest = getDepartureBoardRequest
89 | module.exports.getDepartureBoardWithDetails = getDepartureBoardWithDetails
90 | module.exports.getArrivalsBoard = getArrivalsBoard
91 | module.exports.getArrivalsBoardWithDetails = getArrivalsBoardWithDetails
92 | module.exports.getArrivalsDepartureBoard = getArrivalsDepartureBoard
93 | module.exports.getArrivalsDepartureBoardWithDetails = getArrivalsDepartureBoardWithDetails
94 | module.exports.getServiceDetails = getServiceDetails
95 | module.exports.getNextDeparture = getNextDeparture
96 | module.exports.getNextDepartureWithDetails = getNextDepartureWithDetails
97 | module.exports.getArrival = getArrival
98 | module.exports.getFastestDeparture = getFastestDeparture
99 | module.exports.getFastestDepartureWithDetails = getFastestDepartureWithDetails
100 |
--------------------------------------------------------------------------------
/exampleResponses/arrivalBoardWithDets_bus.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
9 |
16 | 2017-11-05T13:01:03.9634517+00:00
17 | Manchester Victoria
18 | MCV
19 | true
20 |
21 |
22 | 13:13
23 | On time
24 | BUS
25 | Northern
26 | NT
27 | bus
28 | 4K/pJ3foFNnVXFl6ON8t+A==
29 |
30 |
31 | Preston
32 | PRE
33 |
34 |
35 |
36 |
37 | Manchester Victoria
38 | MCV
39 |
40 |
41 |
42 |
43 |
44 | Preston
45 | PRE
46 | 11:00
47 | On time
48 |
49 |
50 | Leyland
51 | LEY
52 | 11:20
53 | On time
54 |
55 |
56 | Buckshaw Parkway
57 | BSV
58 | 11:34
59 | On time
60 |
61 |
62 | Chorley
63 | CRL
64 | 11:49
65 | On time
66 |
67 |
68 | Adlington (Lancashire)
69 | ADL
70 | 11:59
71 | On time
72 |
73 |
74 | Blackrod
75 | BLK
76 | 12:06
77 | On time
78 |
79 |
80 | Horwich Parkway
81 | HWI
82 | 12:12
83 | On time
84 |
85 |
86 | Lostock
87 | LOT
88 | 12:20
89 | On time
90 |
91 |
92 | Bolton
93 | BON
94 | 12:38
95 | On time
96 |
97 |
98 | Salford Crescent
99 | SLD
100 | 13:03
101 | On time
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
--------------------------------------------------------------------------------
/templates.js:
--------------------------------------------------------------------------------
1 | var soapHeader =
2 | '' +
3 | `` +
4 | `` +
5 | `$$TOKEN$$` +
6 | `` +
7 | ``
8 |
9 | var getServiceBoardStandardRequest =
10 | `$$ROWS$$` +
11 | `$$FROM$$` +
12 | `$$DESTINATION$$` +
13 | `to` +
14 | `$$TIMEOFFSET$$` +
15 | `$$TIMEWINDOW$$`
16 |
17 | var getServiceStandardRequest =
18 | `$$FROM$$` +
19 | `` +
20 | ` $$DESTINATION$$` +
21 | `` +
22 | `$$TIMEOFFSET$$` +
23 | `$$TIMEWINDOW$$`
24 |
25 | var arrivalsBoardWithDetails =
26 | soapHeader +
27 | `` +
28 | `` +
29 | getServiceBoardStandardRequest +
30 | `` +
31 | `` +
32 | ``
33 |
34 | var arrivalsDepartureBoard =
35 | soapHeader +
36 | `` +
37 | `` +
38 | getServiceBoardStandardRequest +
39 | `` +
40 | `` +
41 | ``
42 |
43 | var arrivalsDepartureBoardWithDetails =
44 | soapHeader +
45 | `` +
46 | `` +
47 | getServiceBoardStandardRequest +
48 | `` +
49 | `` +
50 | ``
51 |
52 | var departureBoardTemplate =
53 | soapHeader +
54 | `` +
55 | `` +
56 | getServiceBoardStandardRequest +
57 | `` +
58 | `` +
59 | ``
60 |
61 | var departureBoardWithDetails =
62 | soapHeader +
63 | `` +
64 | `` +
65 | getServiceBoardStandardRequest +
66 | `` +
67 | `` +
68 | ``
69 |
70 | var arrivalsBoardTemplate =
71 | soapHeader +
72 | `` +
73 | `` +
74 | getServiceBoardStandardRequest +
75 | `` +
76 | `` +
77 | ``
78 |
79 | var serviceDetailsTemplate =
80 | soapHeader +
81 | `` +
82 | `` +
83 | `$$SERVICEID$$` +
84 | `` +
85 | `` +
86 | ``
87 |
88 | var nextDeparture =
89 | soapHeader +
90 | `` +
91 | `` +
92 | getServiceStandardRequest +
93 | `` +
94 | `` +
95 | ``
96 |
97 | var nextDepartureWithDetails =
98 | soapHeader +
99 | `` +
100 | `` +
101 | getServiceStandardRequest +
102 | `` +
103 | `` +
104 | ``
105 |
106 | var nextArrival =
107 | soapHeader +
108 | `` +
109 | `` +
110 | getServiceStandardRequest +
111 | `` +
112 | `` +
113 | ``
114 |
115 | var fastestDeparture =
116 | soapHeader +
117 | `` +
118 | `` +
119 | getServiceStandardRequest +
120 | `` +
121 | `` +
122 | ``
123 |
124 | var fastestDepartureWithDetails =
125 | soapHeader +
126 | `` +
127 | `` +
128 | getServiceStandardRequest +
129 | `` +
130 | `` +
131 | ``
132 |
133 | module.exports.departureBoard = departureBoardTemplate
134 | module.exports.arrivalsBoard = arrivalsBoardTemplate
135 | module.exports.arrivalsBoardWithDetails = arrivalsBoardWithDetails
136 | module.exports.arrivalsDepartureBoard = arrivalsDepartureBoard
137 | module.exports.arrivalsDepartureBoardWithDetails = arrivalsDepartureBoardWithDetails
138 | module.exports.serviceDetails = serviceDetailsTemplate
139 | module.exports.nextDeparture = nextDeparture
140 | module.exports.nextDepartureWithDetails = nextDepartureWithDetails
141 | module.exports.departureBoardWithDetails = departureBoardWithDetails
142 | module.exports.fastestDeparture = fastestDeparture
143 | module.exports.fastestDepartureWithDetails = fastestDepartureWithDetails
144 |
145 | module.exports.nextArrival = nextArrival
146 | module.exports.header = soapHeader
147 |
--------------------------------------------------------------------------------
/bin/darwin.js:
--------------------------------------------------------------------------------
1 | #! /usr/bin/env node
2 | const program = require('commander')
3 | const util = require('util')
4 | var Rail = require('../index.js')
5 |
6 | var processOptions = function (parent) {
7 | var opts = {}
8 | if (parent.destination) {
9 | opts.destination = parent.destination
10 | }
11 | if (parent.rows) {
12 | opts.rows = parent.rows
13 | }
14 | if (parent.window) {
15 | opts.window = parent.window
16 | }
17 | return opts
18 | }
19 |
20 | function getClient () {
21 | var token = process.env.DARWIN_TOKEN
22 | if (program.token) {
23 | token = program.token
24 | }
25 | return new Rail(token)
26 | }
27 |
28 | var getPrinter = function (json) {
29 | return (err, result) => {
30 | if (err) {
31 | console.log(err.statusCode)
32 | console.log(err.body)
33 | console.log(err)
34 | } else {
35 | console.log(json ? JSON.stringify(result) : util.inspect(result, {depth: null}))
36 | }
37 | }
38 | }
39 |
40 | program
41 | .version('0.0.1')
42 | .description('Access the national-rail-darwin api. All 11 service calls from the Darwin public API are implemented here.')
43 | .option('-d, --destination ', 'Filter on a destination station. Must be a CRS code.')
44 | .option('-r, --rows ', 'Maximum number of rows to return. Defaults to 15.')
45 | .option('-w, --window ', 'Maxmimum number of minutes to search within. Defaults to 120.')
46 | .option('-t, --token ', 'Specify Darwin API token to use. Defaults to env.DARWIN_TOKEN')
47 | .option('-j, --json', 'Return raw JSON')
48 |
49 | program
50 | .command('arr-board ')
51 | .alias('ab')
52 | .description('Print Arrival Board')
53 | .action((station, options) => {
54 | getClient().getArrivalsBoard(station, processOptions(options.parent), getPrinter(options.parent.json))
55 | })
56 |
57 | program
58 | .command('arr-board-details ')
59 | .alias('ab-details')
60 | .description('Print Arrival Board with Details')
61 | .action((station, options) => {
62 | getClient().getArrivalsBoardWithDetails(station, processOptions(options.parent), getPrinter(options.parent.json))
63 | })
64 |
65 | program
66 | .command('arr-dep-board ')
67 | .alias('ad')
68 | .description('Print Arrival Departure Board')
69 | .action((station, options) => {
70 | getClient().getArrivalsDepartureBoard(station, processOptions(options.parent), getPrinter(options.parent.json))
71 | })
72 |
73 | program
74 | .command('arr-dep-board-details ')
75 | .alias('ad-details')
76 | .description('Print Arrival Departure Board with Details')
77 | .action((station, options) => {
78 | getClient().getArrivalsDepartureBoardWithDetails(station, processOptions(options.parent), getPrinter(options.parent.json))
79 | })
80 |
81 | program
82 | .command('departureBoard ')
83 | .alias('db')
84 | .description('Print Departure Board')
85 | .action((station, options) => {
86 | getClient().getDepartureBoard(station, processOptions(options.parent), getPrinter(options.parent.json))
87 | })
88 |
89 | program
90 | .command('departureBoardWithDetails ')
91 | .alias('db-details')
92 | .description('Print Departure Board with Details')
93 | .action((station, options) => {
94 | getClient().getDepartureBoardWithDetails(station, processOptions(options.parent), getPrinter(options.parent.json))
95 | })
96 |
97 | program
98 | .command('fastest-dep ')
99 | .alias('fd')
100 | .description('Print Fastest Departure')
101 | .action((station, destination, options) => {
102 | getClient().getFastestDeparture(station, destination, processOptions(options.parent), getPrinter(options.parent.json))
103 | })
104 |
105 | program
106 | .command('fastest-dep-details ')
107 | .alias('fd-details')
108 | .description('Print Fastest Departure with Details')
109 | .action((station, destination, options) => {
110 | getClient().getFastestDepartureWithDetails(station, destination, processOptions(options.parent), getPrinter(options.parent.json))
111 | })
112 |
113 | program
114 | .command('next-arrival ')
115 | .alias('na')
116 | .description('Print Next Arrival')
117 | .action((station, destination, options) => {
118 | getClient().getArrival(station, destination, processOptions(options.parent), getPrinter(options.parent.json))
119 | })
120 |
121 | program
122 | .command('next-departure ')
123 | .alias('nd')
124 | .description('Print Next Departure')
125 | .action((station, destination, options) => {
126 | getClient().getNextDeparture(station, destination, processOptions(options.parent), getPrinter(options.parent.json))
127 | })
128 |
129 | program
130 | .command('next-departure-details ')
131 | .alias('nd-details')
132 | .description('Print Next Departure with Details')
133 | .action((station, destination, options) => {
134 | getClient().getNextDepartureWithDetails(station, destination, processOptions(options.parent), getPrinter(options.parent.json))
135 | })
136 |
137 | program
138 | .command('service-details ')
139 | .alias('sd')
140 | .description('Print Service Details')
141 | .action((serviceId) => {
142 | getClient().getServiceDetails(serviceId, getPrinter(options.parent.json))
143 | })
144 |
145 | program.parse(process.argv)
146 |
--------------------------------------------------------------------------------
/index.js:
--------------------------------------------------------------------------------
1 | var request = require('request')
2 | var Bluebird = require('bluebird')
3 |
4 | var requestBuilder = require('./requestBuilder.js')
5 | var parser = require('./parsers.js')
6 |
7 | var baseUrl = 'https://lite.realtime.nationalrail.co.uk/OpenLDBWS/ldb11.asmx'
8 |
9 | var Darwin = function (apiKey, options) {
10 | this.key = apiKey || process.env.DARWIN_TOKEN
11 | if (options && options.baseUrl) {
12 | baseUrl = options.baseUrl
13 | }
14 | }
15 |
16 | Darwin.prototype.getBaseUrl = function () {
17 | return baseUrl
18 | }
19 |
20 | Darwin.prototype.thenablePOST = function (xml) {
21 | var xmlWithToken = xml.replace('$$TOKEN$$', this.key)
22 | return new Bluebird(function (resolve, reject) {
23 | request.post({
24 | url: baseUrl,
25 | headers: {
26 | 'content-type': 'text/xml'
27 | },
28 | body: xmlWithToken
29 | }, function (err, response, body) {
30 | if (err) {
31 | console.log(err)
32 | reject(err)
33 | } else if (response.statusCode > 300) {
34 | reject(response)
35 | } else {
36 | resolve(body)
37 | }
38 | })
39 | })
40 | }
41 |
42 | function thenableGET (url) {
43 | return new Bluebird(function (resolve, reject) {
44 | request.get({
45 | url: url
46 | }, function (err, response, body) {
47 | if (err) {
48 | reject(err)
49 | } else if (response.statusCode > 300) {
50 | reject(response)
51 | } else {
52 | resolve(body)
53 | }
54 | })
55 | })
56 | }
57 |
58 | Darwin.prototype.getDepartureBoard = function (station, options, callback) {
59 | var requestXML = requestBuilder.getDepartureBoardRequest(station, options)
60 | this.thenablePOST(requestXML).then(function (result) {
61 | callback(null, parser.parseDepartureBoardResponse(result))
62 | }).catch(function (err) {
63 | callback(err, null)
64 | })
65 | }
66 |
67 | Darwin.prototype.getDepartureBoardWithDetails = function (station, options, callback) {
68 | var requestXML = requestBuilder.getDepartureBoardWithDetails(station, options)
69 | this.thenablePOST(requestXML).then(function (result) {
70 | callback(null, parser.parseDepartureBoardWithDetailsResponse(result))
71 | }).catch(function (err) {
72 | callback(err, null)
73 | })
74 | }
75 |
76 | Darwin.prototype.getArrivalsBoard = function (station, options, callback) {
77 | var requestXML = requestBuilder.getArrivalsBoard(station, options)
78 | this.thenablePOST(requestXML).then(function (result) {
79 | callback(null, parser.parseArrivalsBoardResponse(result))
80 | }).catch(function (err) {
81 | callback(err, null)
82 | })
83 | }
84 |
85 | Darwin.prototype.getArrivalsBoardWithDetails = function (station, options, callback) {
86 | var requestXML = requestBuilder.getArrivalsBoardWithDetails(station, options)
87 | this.thenablePOST(requestXML).then(function (result) {
88 | callback(null, parser.parseArrivalsBoardWithDetails(result))
89 | }).catch(function (err) {
90 | callback(err, null)
91 | })
92 | }
93 |
94 | Darwin.prototype.getArrivalsDepartureBoard = function (station, options, callback) {
95 | var requestXML = requestBuilder.getArrivalsDepartureBoard(station, options)
96 | this.thenablePOST(requestXML).then(function (result) {
97 | callback(null, parser.parseArrivalsDepartureBoard(result))
98 | }).catch(function (err) {
99 | callback(err, null)
100 | })
101 | }
102 |
103 | Darwin.prototype.getArrivalsDepartureBoardWithDetails = function (station, options, callback) {
104 | var requestXML = requestBuilder.getArrivalsDepartureBoardWithDetails(station, options)
105 | this.thenablePOST(requestXML).then(function (result) {
106 | callback(null, parser.parseArrivalsDepartureBoardWithDetails(result))
107 | }).catch(function (err) {
108 | callback(err, null)
109 | })
110 | }
111 |
112 | Darwin.prototype.getServiceDetails = function (serviceId, callback) {
113 | var requestXML = requestBuilder.getServiceDetails(serviceId)
114 | this.thenablePOST(requestXML).then(function (result) {
115 | callback(null, parser.parseServiceDetails(result))
116 | }).catch(function (err) {
117 | callback(err, null)
118 | })
119 | }
120 |
121 | Darwin.prototype.getNextDeparture = function (station, destination, options, callback) {
122 | var requestXML = requestBuilder.getNextDeparture(station, destination, options)
123 | this.thenablePOST(requestXML).then(function (result) {
124 | callback(null, parser.parseNextDepartureResponse(result))
125 | }).catch(function (err) {
126 | callback(err, null)
127 | })
128 | }
129 |
130 | Darwin.prototype.getNextDepartureWithDetails = function (station, destination, options, callback) {
131 | var requestXML = requestBuilder.getNextDepartureWithDetails(station, destination, options)
132 | this.thenablePOST(requestXML).then(function (result) {
133 | callback(null, parser.parseNextDepartureWithDetailsResponse(result))
134 | }).catch(function (err) {
135 | callback(err, null)
136 | })
137 | }
138 |
139 | Darwin.prototype.getArrival = function (station, destination, options, callback) {
140 | var requestXML = requestBuilder.getArrival(station, destination, options)
141 | this.thenablePOST(requestXML).then(function (result) {
142 | callback(null, parser.parseArrivalsBoardResponse(result))
143 | }).catch(function (err) {
144 | callback(err, null)
145 | })
146 | }
147 |
148 | Darwin.prototype.getFastestDeparture = function (station, destination, options, callback) {
149 | var requestXML = requestBuilder.getFastestDeparture(station, destination, options)
150 | this.thenablePOST(requestXML).then(function (result) {
151 | callback(null, parser.parseFastestDeparture(result))
152 | }).catch(function (err) {
153 | callback(err, null)
154 | })
155 | }
156 |
157 | Darwin.prototype.getFastestDepartureWithDetails = function (station, destination, options, callback) {
158 | var requestXML = requestBuilder.getFastestDepartureWithDetails(station, destination, options)
159 | this.thenablePOST(requestXML).then(function (result) {
160 | callback(null, parser.parseFastestDeparturesWithDetail(result))
161 | }).catch(function (err) {
162 | callback(err, null)
163 | })
164 | }
165 |
166 | Darwin.prototype.getStationDetails = function (stationName, callback) {
167 | var url = 'http://ojp.nationalrail.co.uk/find/stationsDLRLU/' + encodeURIComponent(stationName)
168 | thenableGET(url).then(function (body) {
169 | var results = JSON.parse(body)
170 | var output = results.map(function (result) {
171 | return {
172 | 'code': result[0],
173 | 'name': result[1],
174 | 'longitude': result[8],
175 | 'latitude': result[7],
176 | 'postcode': result[9],
177 | 'operator': result[10]
178 | }
179 | })
180 | callback(null, output)
181 | }).catch(function (err) {
182 | callback(err, null)
183 | })
184 | }
185 |
186 | module.exports = Darwin
187 |
--------------------------------------------------------------------------------
/exampleResponses/nextDepartureWithDetails.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | 2018-01-11T18:34:24.0265665+00:00
6 | Isleworth
7 | ISL
8 | true
9 |
10 |
11 |
12 | 18:34
13 | On time
14 | 18:34
15 | On time
16 | 1
17 | South Western Railway
18 | SW
19 | train
20 | 10
21 | wfmF+NYLrCpeoJVHBxSxrQ==
22 | SW182100
23 |
24 |
25 | London Waterloo
26 | WAT
27 |
28 |
29 |
30 |
31 | London Waterloo
32 | WAT
33 | via Brentford
34 |
35 |
36 |
37 |
38 |
39 | Syon Lane
40 | SYL
41 | 18:36
42 | On time
43 | 10
44 |
45 |
46 | Brentford
47 | BFD
48 | 18:38
49 | On time
50 | 10
51 |
52 |
53 | Kew Bridge
54 | KWB
55 | 18:41
56 | On time
57 | 10
58 |
59 |
60 | Chiswick
61 | CHK
62 | 18:44
63 | On time
64 | 10
65 |
66 |
67 | Barnes Bridge
68 | BNI
69 | 18:46
70 | On time
71 | 10
72 |
73 |
74 | Barnes
75 | BNS
76 | 18:49
77 | On time
78 | 10
79 |
80 |
81 | Putney
82 | PUT
83 | 18:52
84 | On time
85 | 10
86 |
87 |
88 | Wandsworth Town
89 | WNT
90 | 18:55
91 | On time
92 | 10
93 |
94 |
95 | Clapham Junction
96 | CLJ
97 | 18:58
98 | On time
99 | 10
100 |
101 |
102 | Queenstown Road Battersea
103 | QRB
104 | 19:01
105 | On time
106 | 10
107 |
108 |
109 | Vauxhall
110 | VXH
111 | 19:04
112 | On time
113 | 10
114 |
115 |
116 | London Waterloo
117 | WAT
118 | 19:11
119 | On time
120 | 10
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
--------------------------------------------------------------------------------
/exampleResponses/fastestDeparturesWithDetails.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | 2018-01-11T18:33:24.6837861+00:00
6 | Isleworth
7 | ISL
8 | true
9 |
10 |
11 |
12 | 18:34
13 | On time
14 | 18:34
15 | On time
16 | 1
17 | South Western Railway
18 | SW
19 | train
20 | 10
21 | wfmF+NYLrCpeoJVHBxSxrQ==
22 | SW182100
23 |
24 |
25 | London Waterloo
26 | WAT
27 |
28 |
29 |
30 |
31 | London Waterloo
32 | WAT
33 | via Brentford
34 |
35 |
36 |
37 |
38 |
39 | Syon Lane
40 | SYL
41 | 18:36
42 | On time
43 | 10
44 |
45 |
46 | Brentford
47 | BFD
48 | 18:38
49 | On time
50 | 10
51 |
52 |
53 | Kew Bridge
54 | KWB
55 | 18:41
56 | On time
57 | 10
58 |
59 |
60 | Chiswick
61 | CHK
62 | 18:44
63 | On time
64 | 10
65 |
66 |
67 | Barnes Bridge
68 | BNI
69 | 18:46
70 | On time
71 | 10
72 |
73 |
74 | Barnes
75 | BNS
76 | 18:49
77 | On time
78 | 10
79 |
80 |
81 | Putney
82 | PUT
83 | 18:52
84 | On time
85 | 10
86 |
87 |
88 | Wandsworth Town
89 | WNT
90 | 18:55
91 | On time
92 | 10
93 |
94 |
95 | Clapham Junction
96 | CLJ
97 | 18:58
98 | On time
99 | 10
100 |
101 |
102 | Queenstown Road Battersea
103 | QRB
104 | 19:01
105 | On time
106 | 10
107 |
108 |
109 | Vauxhall
110 | VXH
111 | 19:04
112 | On time
113 | 10
114 |
115 |
116 | London Waterloo
117 | WAT
118 | 19:11
119 | On time
120 | 10
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # national-rail-darwin
2 |
3 | [](http://standardjs.com/)
4 | [](https://travis-ci.org/mattsalt/national-rail-darwin)
5 |
6 | ### Introduction
7 |
8 | `national-rail-darwin` aims to give you json object representations of the SOAP responses from National Rail's Darwin api. Details of the api can be found [here](http://lite.realtime.nationalrail.co.uk/openldbws/). You will need to get an API token to access Darwin, this requires registration. You can signup at [http://realtime.nationalrail.co.uk/OpenLDBWSRegistration/](http://realtime.nationalrail.co.uk/OpenLDBWSRegistration/).
9 |
10 | Currently only CRS codes are supported, a future update will allow full station names to be used. You can find a complete list of CRS codes on the [ National Rail website](http://www.nationalrail.co.uk/stations_destinations/48541.aspx).
11 |
12 | ### Installation
13 |
14 | ```
15 | npm install national-rail-darwin
16 | ```
17 |
18 | ### Usage
19 |
20 | All 11 requests exposed by the Darwin api are available in `national-rail-darwin`
21 | - getDepartureBoard(crsCode, options, callback)
22 | - getArrivalsBoard(crsCode, options, callback)
23 | - getArrivalsBoardWithDetails(crsCode, options, callback)
24 | - getArrivalsDepartureBoard(crsCode, options, callback)
25 | - getArrivalsDepartureBoardWithDetails(crsCode, options, callback)
26 | - getServiceDetails(serviceId, callback)
27 | - getNextDeparture(crsCode, destinationCrsCode, options, callback)
28 | - getNextDepartureWithDetails(crsCode, destinationCrsCode, options, callback)
29 | - getDepartureBoardWithDetails(crsCode, options, callback)
30 | - getFastestDeparture(crsCode, destinationCrsCode, options, callback)
31 | - getFastestDepartureWithDetails(crsCode, destinationCrsCode, options, callback)
32 |
33 | Additional functions
34 | - getStationDetails(Station, callback)
35 |
36 |
37 | Your api token can either be provided when the client is created or picked up from the environment variable `DARWIN_TOKEN`.
38 |
39 | ```
40 | var Rail = require('national-rail-darwin')
41 | var rail = new Rail() // or -> new Rail(DARWIN_TOKEN)
42 | ```
43 |
44 | ### Options
45 |
46 | Some functions take an options object. See the specific method definitions for details of these.
47 |
48 | ### Methods
49 |
50 | All methods return arrays of basic service objects of the form:
51 | ```
52 | {
53 | sta: '23:57',
54 | eta: 'On time',
55 | std: '23:57',
56 | etd: 'On time',
57 | platform: '2',
58 | delayReason: null,
59 | origin: {
60 | name:,
61 | crs:
62 | },
63 | destination: {
64 | name:,
65 | crs:
66 | },
67 | length: '5',
68 | serviceId: 'xxxxxxxxxxxxxxxx+xx/xxx=='
69 | }
70 | ```
71 |
72 | #### getDepartureBoard
73 | ```javascript
74 | rail.getDepartureBoard('WAT', {}, function(err,result){
75 | //do stuff
76 | })
77 | ```
78 |
79 | Gets all public departures for the supplied station within 2 hours.
80 | Options:
81 | 'destination': Only show trains that call at the supplied station.
82 | 'rows': Maximum number of services to retrieve (1 - 149).
83 |
84 | #### getArrivalsBoard
85 |
86 | ```javascript
87 | rail.getArrivalsBoard('PUT', {}, function(err, result){
88 | //do stuff
89 | })
90 | ```
91 |
92 | Similar to getDepartureBoard but shows arrivals within the next two hours.
93 | Options:
94 | 'destination': Only show trains that have called at the supplied station.
95 | 'rows': Maximum number of services to retrieve.
96 |
97 | #### getArrivalsBoardWithDetails
98 |
99 | ```javascript
100 | rail.getArrivalsBoardWithDetails('PUT', {}, function(err, result){
101 | //do stuff
102 | })
103 | ```
104 | Adds service details including previous calling points to the getArrivalsBoardResult.
105 | Options:
106 | 'destination': Only show trains that have called at the supplied station.
107 | 'rows': Maximum number of services to retrieve.
108 |
109 | #### getArrivalsDepartureBoard
110 |
111 | ```javascript
112 | rail.getArrivalsDepartureBoard('PUT', {}, function(err, result){
113 | //do stuff
114 | })
115 | ```
116 | Returns all public arrivals and departures for the supplied CRS code within 2 hours.
117 | Options:
118 | 'destination': Only show trains that have called at the supplied station.
119 | 'rows': Maximum number of services to retrieve.
120 |
121 | #### getArrivalsDepartureBoardWithDetails
122 |
123 | ```javascript
124 | rail.getArrivalsDepartureBoardWithDetails('PUT', {}, function(err, result){
125 | //do stuff
126 | })
127 | ```
128 | Returns array of train services with both previous and subsequent calling points included for each service.
129 | Options:
130 | 'destination': Only show trains that have called at the supplied station.
131 | 'rows': Maximum number of services to retrieve.
132 |
133 | #### getServiceDetails
134 | ```javascript
135 | rail.getServiceDetails('SERVICE ID', function(err, result){
136 | //do stuff
137 | })
138 | ```
139 |
140 | Gets detailed information about a particular service relative to the station that generated the serviceId. ServiceId is returned from other calls such as getDepartureBoard or getNextDeparture. The object returns includes all calling points of the service requested. The data is only available while the particular service is showing on the station departure board. This is normally for up to two minutes after the service is expected to depart.
141 |
142 | #### getNextDeparture
143 | ```javascript
144 | rail.getNextDeparture(crsCode, destinationCrsCode, {}, function(err, result){
145 | //do stuff
146 | })
147 | ```
148 | Returns the next train leaving from supplied station calling at the destination CRS Code.
149 |
150 | #### getNextDepartureWithDetails
151 | ```javascript
152 | rail.getNextDepartureWithDetails(crsCode, destinationCrsCode, {}, function(err, result){
153 | //do stuff
154 | })
155 | ```
156 | Returns the next train leaving from supplied station calling at the destination CRS Code within two hours including subsequent calling points.
157 |
158 | #### getDepartureBoardWithDetails
159 | ```javascript
160 | rail.getDepartureBoardWithDetails('WAT', {}, function(err,result){
161 | //do stuff
162 | })
163 | ```
164 | Adds a list of future calling points to the standard departure board response.
165 | 'destination': Only show trains that call at the supplied station.
166 | 'rows': Maximum number of services to retrieve.
167 |
168 | #### getFastestDeparture
169 | ```javascript
170 | rail.getFastestDeparture('from', 'destination crs', {}, function(err,result){
171 | //do stuff
172 | })
173 | ```
174 | Returns the service with the earliest arrival time at the destination station leaving from the supplied station.
175 |
176 | #### getFastestDepartureWithDetails
177 | ```javascript
178 | rail.getFastestDepartureWithDetails('from', 'destination crs', {}, function(err,result){
179 | //do stuff
180 | })
181 | ```
182 | Same response as getFastestDeparture but includes service details such as previous and subsequent calling points.
183 |
184 | #### getStationDetails
185 | ```javascript
186 | rail.getStationDetails('Leeds', function(err,result){
187 | //do stuff
188 | })
189 | ```
190 | Look up station details including CRSCode from the full station name
191 |
192 |
193 | ### Command Line
194 |
195 | national-rail-darwin now provides a command line tool, darwin, for querying the Darwin API. All Darwin requests are accessible via this tool. Install globally and run
196 | ```
197 | darwin --help
198 | ```
199 | for usage details.
200 |
201 | To authenticate using the command line you can either specify your API token using the `--token` flag or set `DARWIN_TOKEN` as an environment variable.
202 |
203 | You can print the result as raw JSON by using the `--json` option if you want
204 | to manipulate the output with something like [`jq`](https://stedolan.github.io/jq/).
205 |
206 | For example:
207 | ```
208 | darwin --json -t XXX arr-board ANZ | jq '.trainServices[]'
209 | ```
210 |
--------------------------------------------------------------------------------
/exampleResponses/arrivalBoardWithDets.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | 2018-01-11T18:27:35.8553243+00:00
6 | Isleworth
7 | ISL
8 | Putney
9 | PUT
10 | true
11 |
12 |
13 | 18:34
14 | On time
15 | 1
16 | South Western Railway
17 | SW
18 | train
19 | 10
20 | wfmF+NYLrCpeoJVHBxSxrQ==
21 | SW182100
22 |
23 |
24 | London Waterloo
25 | WAT
26 |
27 |
28 |
29 |
30 | London Waterloo
31 | WAT
32 | via Brentford
33 |
34 |
35 |
36 |
37 |
38 | London Waterloo
39 | WAT
40 | 17:45
41 | On time
42 | 10
43 |
44 |
45 | Vauxhall
46 | VXH
47 | 17:50
48 | On time
49 | 10
50 |
51 |
52 | Queenstown Road Battersea
53 | QRB
54 | 17:53
55 | On time
56 | 10
57 |
58 |
59 | Clapham Junction
60 | CLJ
61 | 17:56
62 | On time
63 | 10
64 |
65 |
66 | Wandsworth Town
67 | WNT
68 | 17:58
69 | On time
70 | 10
71 |
72 |
73 | Putney
74 | PUT
75 | 18:01
76 | On time
77 | 10
78 |
79 |
80 | Barnes
81 | BNS
82 | 18:05
83 | On time
84 | 10
85 |
86 |
87 | Mortlake
88 | MTL
89 | 18:07
90 | On time
91 | 10
92 |
93 |
94 | North Sheen
95 | NSH
96 | 18:09
97 | On time
98 | 10
99 |
100 |
101 | Richmond
102 | RMD
103 | 18:12
104 | On time
105 | 10
106 |
107 |
108 | St Margarets (London)
109 | SMG
110 | 18:14
111 | On time
112 | 10
113 |
114 |
115 | Twickenham
116 | TWI
117 | 18:17
118 | On time
119 | 10
120 |
121 |
122 | Whitton
123 | WTN
124 | 18:20
125 | On time
126 | 10
127 |
128 |
129 | Hounslow
130 | HOU
131 | 18:31
132 | On time
133 | 10
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
--------------------------------------------------------------------------------
/exampleResponses/serviceDetails.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | 2018-01-11T18:34:53.3079542+00:00
6 | train
7 | Isleworth
8 | ISL
9 | South Western Railway
10 | SW
11 | SW182100
12 | 10
13 | 1
14 | 18:34
15 | On time
16 | 18:34
17 | On time
18 |
19 |
20 |
21 | London Waterloo
22 | WAT
23 | 17:45
24 | On time
25 | 10
26 |
27 |
28 | Vauxhall
29 | VXH
30 | 17:50
31 | On time
32 | 10
33 |
34 |
35 | Queenstown Road Battersea
36 | QRB
37 | 17:53
38 | On time
39 | 10
40 |
41 |
42 | Clapham Junction
43 | CLJ
44 | 17:56
45 | On time
46 | 10
47 |
48 |
49 | Wandsworth Town
50 | WNT
51 | 17:58
52 | On time
53 | 10
54 |
55 |
56 | Putney
57 | PUT
58 | 18:01
59 | On time
60 | 10
61 |
62 |
63 | Barnes
64 | BNS
65 | 18:05
66 | On time
67 | 10
68 |
69 |
70 | Mortlake
71 | MTL
72 | 18:07
73 | On time
74 | 10
75 |
76 |
77 | North Sheen
78 | NSH
79 | 18:09
80 | On time
81 | 10
82 |
83 |
84 | Richmond
85 | RMD
86 | 18:12
87 | On time
88 | 10
89 |
90 |
91 | St Margarets (London)
92 | SMG
93 | 18:14
94 | On time
95 | 10
96 |
97 |
98 | Twickenham
99 | TWI
100 | 18:17
101 | On time
102 | 10
103 |
104 |
105 | Whitton
106 | WTN
107 | 18:20
108 | On time
109 | 10
110 |
111 |
112 | Hounslow
113 | HOU
114 | 18:31
115 | On time
116 | 10
117 |
118 |
119 |
120 |
121 |
122 |
123 | Syon Lane
124 | SYL
125 | 18:36
126 | On time
127 | 10
128 |
129 |
130 | Brentford
131 | BFD
132 | 18:38
133 | On time
134 | 10
135 |
136 |
137 | Kew Bridge
138 | KWB
139 | 18:41
140 | On time
141 | 10
142 |
143 |
144 | Chiswick
145 | CHK
146 | 18:44
147 | On time
148 | 10
149 |
150 |
151 | Barnes Bridge
152 | BNI
153 | 18:46
154 | On time
155 | 10
156 |
157 |
158 | Barnes
159 | BNS
160 | 18:49
161 | On time
162 | 10
163 |
164 |
165 | Putney
166 | PUT
167 | 18:52
168 | On time
169 | 10
170 |
171 |
172 | Wandsworth Town
173 | WNT
174 | 18:55
175 | On time
176 | 10
177 |
178 |
179 | Clapham Junction
180 | CLJ
181 | 18:58
182 | On time
183 | 10
184 |
185 |
186 | Queenstown Road Battersea
187 | QRB
188 | 19:01
189 | On time
190 | 10
191 |
192 |
193 | Vauxhall
194 | VXH
195 | 19:04
196 | On time
197 | 10
198 |
199 |
200 | London Waterloo
201 | WAT
202 | 19:11
203 | On time
204 | 10
205 |
206 |
207 |
208 |
209 |
210 |
211 |
212 |
--------------------------------------------------------------------------------
/parsers.js:
--------------------------------------------------------------------------------
1 | var xmldoc = require('xmldoc')
2 |
3 | function parseArrivalsBoardResponse (soapResponse) {
4 | var board = getTrainServicesBoard(soapResponse, 'GetArrivalBoardResponse')
5 | var trains = []
6 |
7 | try {
8 | board.eachChild(function (service) {
9 | trains.push(parseStandardService(service))
10 | })
11 | } catch (e) { }
12 |
13 | return { 'trainServices': trains }
14 | }
15 |
16 | function parseArrivalsBoardWithDetails (soapResponse) {
17 | var board = getTrainServicesBoard(soapResponse, 'GetArrBoardWithDetailsResponse')
18 | var trains = []
19 |
20 | try {
21 | board.eachChild(function (service) {
22 | var train = parseStandardService(service)
23 | service.eachChild(function (element) {
24 | switch (element.name) {
25 | case 'lt7:previousCallingPoints':
26 | var previousCallingPoints = element.childNamed('lt7:callingPointList')
27 | train.previousCallingPoints = parseCallingPointList(previousCallingPoints)
28 | break
29 | }
30 | })
31 | trains.push(train)
32 | })
33 | } catch (e) { }
34 |
35 | return { 'trainServices': trains }
36 | }
37 |
38 | function parseArrivalsDepartureBoard (soapResponse) {
39 | var board = getTrainServicesBoard(soapResponse, 'GetArrivalDepartureBoardResponse')
40 | var trains = []
41 |
42 | try {
43 | board.eachChild(function (service) {
44 | trains.push(parseStandardService(service))
45 | })
46 | } catch (e) { }
47 |
48 | return { 'trainServices': trains }
49 | }
50 |
51 | function parseArrivalsDepartureBoardWithDetails (soapResponse) {
52 | var board = getTrainServicesBoard(soapResponse, 'GetArrDepBoardWithDetailsResponse')
53 | var trains = []
54 |
55 | try {
56 | board.eachChild(function (service) {
57 | var train = parseStandardService(service)
58 | service.eachChild(function (element) {
59 | switch (element.name) {
60 | case 'lt7:previousCallingPoints':
61 | var previousCallingPoints = element.childNamed('lt7:callingPointList')
62 | train.previousCallingPoints = parseCallingPointList(previousCallingPoints)
63 | break
64 | case 'lt7:subsequentCallingPoints':
65 | var subsequentCallingPoints = element.childNamed('lt7:callingPointList')
66 | train.subsequentCallingPoints = parseCallingPointList(subsequentCallingPoints)
67 | break
68 | }
69 | })
70 | trains.push(train)
71 | })
72 | } catch (e) { }
73 |
74 | return { 'trainServices': trains }
75 | }
76 |
77 | function parseServiceDetails (soapResponse) {
78 | var serviceXml = extractResponseObject(soapResponse, 'GetServiceDetailsResponse')
79 | .childNamed('GetServiceDetailsResult')
80 | var service = parseStandardService(serviceXml)
81 |
82 | serviceXml.eachChild(function (element) {
83 | switch (element.name) {
84 | case 'lt7:previousCallingPoints':
85 | var previousCallingPoints = element.childNamed('lt7:callingPointList')
86 | service.previousCallingPoints = parseCallingPointList(previousCallingPoints)
87 | break
88 | case 'lt7:subsequentCallingPoints':
89 | var subsequentCallingPoints = element.childNamed('lt7:callingPointList')
90 | service.subsequentCallingPoints = parseCallingPointList(subsequentCallingPoints)
91 | break
92 | }
93 | })
94 |
95 | return { 'serviceDetails': service }
96 | }
97 |
98 | function parseDepartureBoardResponse (soapResponse) {
99 | var board = getTrainServicesBoard(soapResponse, 'GetDepartureBoardResponse')
100 | var trains = []
101 | try {
102 | board.eachChild(function (service) {
103 | trains.push(parseStandardService(service))
104 | })
105 | } catch (e) { }
106 |
107 | return { 'trainServices': trains }
108 | }
109 |
110 | function parseDepartureBoardWithDetailsResponse (soapResponse) {
111 | var board = getTrainServicesBoard(soapResponse, 'GetDepBoardWithDetailsResponse')
112 | var trains = []
113 |
114 | try {
115 | board.eachChild(function (service) {
116 | var train = parseStandardService(service)
117 | service.eachChild(function (element) {
118 | switch (element.name) {
119 | case 'lt7:subsequentCallingPoints':
120 | var subsequentCallingPoints = element.childNamed('lt7:callingPointList')
121 | train.subsequentCallingPoints = parseCallingPointList(subsequentCallingPoints)
122 | break
123 | }
124 | })
125 | trains.push(train)
126 | })
127 | } catch (e) { }
128 |
129 | return { 'trainServices': trains }
130 | }
131 |
132 | function parseNextDepartureResponse (response) {
133 | var board = getDepartureBoardDestination(response, 'GetNextDeparturesResponse')
134 | var trains = []
135 |
136 | try {
137 | board.eachChild(function (service) {
138 | trains.push(parseStandardService(service))
139 | })
140 | } catch (e) { }
141 |
142 | return { 'trainServices': trains }
143 | }
144 |
145 | function parseNextDepartureWithDetailsResponse (response) {
146 | var board = getDepartureBoardDestination(response, 'GetNextDeparturesWithDetailsResponse')
147 | var trains = []
148 |
149 | try {
150 | board.eachChild(function (service) {
151 | var train = parseStandardService(service)
152 | service.eachChild(function (element) {
153 | switch (element.name) {
154 | case 'lt7:subsequentCallingPoints':
155 | var subsequentCallingPoints = element.childNamed('lt7:callingPointList')
156 | train.subsequentCallingPoints = parseCallingPointList(subsequentCallingPoints)
157 | break
158 | }
159 | })
160 | trains.push(train)
161 | })
162 | } catch (e) { }
163 |
164 | return { 'trainServices': trains }
165 | }
166 |
167 | function parseFastestDeparture (response) {
168 | var board = getDepartureBoardDestination(response, 'GetFastestDeparturesResponse')
169 | var trains = []
170 |
171 | try {
172 | board.eachChild(function (service) {
173 | trains.push(parseStandardService(service))
174 | })
175 | } catch (e) { }
176 | return { 'trainServices': trains }
177 | }
178 |
179 | function parseFastestDepartureWithDetails (response) {
180 | var board = getDepartureBoardDestination(response, 'GetFastestDeparturesWithDetailsResponse')
181 | var trains = []
182 | try {
183 | board.eachChild(function (service) {
184 | var train = parseStandardService(service)
185 | service.eachChild(function (element) {
186 | switch (element.name) {
187 | case 'lt7:subsequentCallingPoints':
188 | var subsequentCallingPoints = element.childNamed('lt7:callingPointList')
189 | train.subsequentCallingPoints = parseCallingPointList(subsequentCallingPoints)
190 | break
191 | }
192 | })
193 | trains.push(train)
194 | })
195 | } catch (e) { }
196 |
197 | return { 'trainServices': trains }
198 | }
199 |
200 | function getTrainServicesBoard (response, responseType) {
201 | var board = extractResponseObject(response, responseType)
202 | .childNamed('GetStationBoardResult')
203 | .childNamed('lt7:trainServices')
204 | return board
205 | }
206 |
207 | function parseStandardService (service) {
208 | var train = {}
209 | service.eachChild(function (element) {
210 | switch (element.name) {
211 | case 'lt4:generatedAt':
212 | case 'lt7:generatedAt':
213 | service.generatedAt = element.val
214 | break
215 | case 'lt4:std':
216 | case 'lt7:std':
217 | train.std = element.val
218 | break
219 | case 'lt4:etd':
220 | case 'lt7:etd':
221 | train.etd = element.val
222 | break
223 | case 'lt4:sta':
224 | case 'lt7:sta':
225 | train.sta = element.val
226 | break
227 | case 'lt4:eta':
228 | case 'lt7:eta':
229 | train.eta = element.val
230 | break
231 | case 'lt4:platform':
232 | case 'lt7:platform':
233 | train.platform = element.val
234 | break
235 | case 'lt4:delayReason':
236 | case 'lt7:delayReason':
237 | train.delayReason = element.val
238 | break
239 | case 'lt4:serviceID':
240 | case 'lt7:serviceID':
241 | train.serviceId = element.val
242 | break
243 | case 'lt4:length':
244 | case 'lt7:length':
245 | train.length = element.val
246 | break
247 | case 'lt4:operator':
248 | case 'lt7:operator':
249 | train.operator = element.val
250 | break
251 | case 'lt4:operatorCode':
252 | case 'lt7:operatorCode':
253 | train.operatorCode = element.val
254 | break
255 | case 'lt5:rsid':
256 | case 'lt7:rsid':
257 | train.rsid = element.val
258 | break
259 | case 'lt5:origin':
260 | case 'lt7:origin':
261 | var origin = element.childNamed('lt4:location')
262 | train.origin = parseLocation(origin)
263 | break
264 | case 'lt5:destination':
265 | case 'lt7:destination':
266 | var destin = element.childNamed('lt4:location')
267 | train.destination = parseLocation(destin)
268 | break
269 | }
270 | })
271 | return train
272 | }
273 |
274 | function parseCallingPointList (soapCallingPointList) {
275 | var callingPoints = []
276 | soapCallingPointList.eachChild(function (child) {
277 | var callingPoint = {}
278 | child.eachChild(function (element) {
279 | switch (element.name) {
280 | case 'lt7:length':
281 | callingPoint.length = element.val
282 | break
283 | case 'lt7:crs':
284 | callingPoint.crs = element.val
285 | break
286 | case 'lt7:locationName':
287 | callingPoint.locationName = element.val
288 | break
289 | case 'lt7:st':
290 | callingPoint.st = element.val
291 | break
292 | case 'lt7:et':
293 | callingPoint.et = element.val
294 | break
295 | }
296 | })
297 | callingPoints.push(callingPoint)
298 | })
299 | return callingPoints
300 | }
301 |
302 | function extractResponseObject (soapMessage, response) {
303 | var parsed = new xmldoc.XmlDocument(soapMessage)
304 | return parsed.childNamed('soap:Body').childNamed(response)
305 | }
306 |
307 | function parseLocation (location) {
308 | return {
309 | name: location.childNamed('lt4:locationName').val,
310 | crs: location.childNamed('lt4:crs').val
311 | }
312 | }
313 |
314 | function getDepartureBoardDestination (response, responseType) {
315 | var board = extractResponseObject(response, responseType)
316 | .childNamed('DeparturesBoard')
317 | .childNamed('lt7:departures')
318 | .childNamed('lt7:destination')
319 |
320 | return board
321 | }
322 |
323 | module.exports.parseArrivalsBoardResponse = parseArrivalsBoardResponse
324 | module.exports.parseArrivalsBoardWithDetails = parseArrivalsBoardWithDetails
325 | module.exports.parseArrivalsDepartureBoard = parseArrivalsDepartureBoard
326 | module.exports.parseArrivalsDepartureBoardWithDetails = parseArrivalsDepartureBoardWithDetails
327 |
328 | module.exports.parseDepartureBoardResponse = parseDepartureBoardResponse
329 | module.exports.parseDepartureBoardWithDetailsResponse = parseDepartureBoardWithDetailsResponse
330 |
331 | module.exports.parseFastestDeparture = parseFastestDeparture
332 | module.exports.parseFastestDeparturesWithDetail = parseFastestDepartureWithDetails
333 |
334 | module.exports.parseNextDepartureResponse = parseNextDepartureResponse
335 | module.exports.parseNextDepartureWithDetailsResponse = parseNextDepartureWithDetailsResponse
336 |
337 | module.exports.parseServiceDetails = parseServiceDetails
338 |
--------------------------------------------------------------------------------
/exampleResponses/arrivalsBoard.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | 2018-01-11T18:31:09.4477859+00:00
6 | Isleworth
7 | ISL
8 | Putney
9 | PUT
10 | true
11 |
12 |
13 | 18:34
14 | On time
15 | 1
16 | South Western Railway
17 | SW
18 | train
19 | 10
20 | wfmF+NYLrCpeoJVHBxSxrQ==
21 | SW182100
22 |
23 |
24 | London Waterloo
25 | WAT
26 |
27 |
28 |
29 |
30 | London Waterloo
31 | WAT
32 | via Brentford
33 |
34 |
35 |
36 |
37 | 18:42
38 | On time
39 | 2
40 | South Western Railway
41 | SW
42 | train
43 | 10
44 | nh3WKFCFpkwRTwqpzEUc/A==
45 | SW211600
46 |
47 |
48 | London Waterloo
49 | WAT
50 |
51 |
52 |
53 |
54 | Mortlake
55 | MTL
56 |
57 |
58 |
59 |
60 | 18:49
61 | 18:51
62 | 1
63 | South Western Railway
64 | SW
65 | train
66 | 4
67 | KXIphaTeuVHS0/a4SWgoAg==
68 | SW188000
69 |
70 |
71 | Weybridge
72 | WYB
73 |
74 |
75 |
76 |
77 | London Waterloo
78 | WAT
79 | via Brentford
80 |
81 |
82 |
83 |
84 | 19:04
85 | On time
86 | 1
87 | South Western Railway
88 | SW
89 | train
90 | 8
91 | b5oGjwYNIrFOQCoeerXVsA==
92 | SW182200
93 |
94 |
95 | London Waterloo
96 | WAT
97 |
98 |
99 |
100 |
101 | London Waterloo
102 | WAT
103 | via Brentford
104 |
105 |
106 |
107 |
108 | 19:12
109 | On time
110 | 2
111 | South Western Railway
112 | SW
113 | train
114 | 10
115 | 5QgCfHmYd7JNvbV0YSyhVw==
116 | SW211700
117 |
118 |
119 | London Waterloo
120 | WAT
121 |
122 |
123 |
124 |
125 | Mortlake
126 | MTL
127 |
128 |
129 |
130 |
131 | 19:19
132 | On time
133 | 1
134 | South Western Railway
135 | SW
136 | train
137 | 4
138 | 2HTkZpwWG3h0h2h2gnYvPw==
139 | SW188200
140 |
141 |
142 | Weybridge
143 | WYB
144 |
145 |
146 |
147 |
148 | London Waterloo
149 | WAT
150 | via Brentford
151 |
152 |
153 |
154 |
155 | 19:34
156 | On time
157 | 1
158 | South Western Railway
159 | SW
160 | train
161 | 8
162 | +kJe9WIrueGPWUYhDzmRQg==
163 | SW182300
164 |
165 |
166 | London Waterloo
167 | WAT
168 |
169 |
170 |
171 |
172 | London Waterloo
173 | WAT
174 | via Brentford
175 |
176 |
177 |
178 |
179 | 19:42
180 | On time
181 | 2
182 | South Western Railway
183 | SW
184 | train
185 | 10
186 | cm080rz49AMkBqto0DmPCQ==
187 | SW211800
188 |
189 |
190 | London Waterloo
191 | WAT
192 |
193 |
194 |
195 |
196 | Mortlake
197 | MTL
198 |
199 |
200 |
201 |
202 | 19:49
203 | On time
204 | 1
205 | South Western Railway
206 | SW
207 | train
208 | 10
209 | 14nFdX55toGlajTRiRUE7g==
210 | SW188400
211 |
212 |
213 | Weybridge
214 | WYB
215 |
216 |
217 |
218 |
219 | London Waterloo
220 | WAT
221 | via Brentford
222 |
223 |
224 |
225 |
226 | 20:04
227 | On time
228 | 1
229 | South Western Railway
230 | SW
231 | train
232 | 10
233 | oUW4Wt3Vc+7BHVWXcrkWpQ==
234 | SW182400
235 |
236 |
237 | London Waterloo
238 | WAT
239 |
240 |
241 |
242 |
243 | London Waterloo
244 | WAT
245 | via Brentford
246 |
247 |
248 |
249 |
250 |
251 |
252 |
253 |
254 |
--------------------------------------------------------------------------------
/exampleResponses/departureBoard.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | 2018-01-11T18:32:13.9061324+00:00
6 | Isleworth
7 | ISL
8 | Putney
9 | PUT
10 | true
11 |
12 |
13 | 18:34
14 | On time
15 | 1
16 | South Western Railway
17 | SW
18 | train
19 | 10
20 | wfmF+NYLrCpeoJVHBxSxrQ==
21 | SW182100
22 |
23 |
24 | London Waterloo
25 | WAT
26 |
27 |
28 |
29 |
30 | London Waterloo
31 | WAT
32 | via Brentford
33 |
34 |
35 |
36 |
37 | 18:42
38 | On time
39 | 2
40 | South Western Railway
41 | SW
42 | train
43 | 10
44 | nh3WKFCFpkwRTwqpzEUc/A==
45 | SW211600
46 |
47 |
48 | London Waterloo
49 | WAT
50 |
51 |
52 |
53 |
54 | Mortlake
55 | MTL
56 |
57 |
58 |
59 |
60 | 18:49
61 | 18:51
62 | 1
63 | South Western Railway
64 | SW
65 | train
66 | 4
67 | KXIphaTeuVHS0/a4SWgoAg==
68 | SW188000
69 |
70 |
71 | Weybridge
72 | WYB
73 |
74 |
75 |
76 |
77 | London Waterloo
78 | WAT
79 | via Brentford
80 |
81 |
82 |
83 |
84 | 19:04
85 | On time
86 | 1
87 | South Western Railway
88 | SW
89 | train
90 | 8
91 | b5oGjwYNIrFOQCoeerXVsA==
92 | SW182200
93 |
94 |
95 | London Waterloo
96 | WAT
97 |
98 |
99 |
100 |
101 | London Waterloo
102 | WAT
103 | via Brentford
104 |
105 |
106 |
107 |
108 | 19:12
109 | On time
110 | 2
111 | South Western Railway
112 | SW
113 | train
114 | 10
115 | 5QgCfHmYd7JNvbV0YSyhVw==
116 | SW211700
117 |
118 |
119 | London Waterloo
120 | WAT
121 |
122 |
123 |
124 |
125 | Mortlake
126 | MTL
127 |
128 |
129 |
130 |
131 | 19:19
132 | On time
133 | 1
134 | South Western Railway
135 | SW
136 | train
137 | 4
138 | 2HTkZpwWG3h0h2h2gnYvPw==
139 | SW188200
140 |
141 |
142 | Weybridge
143 | WYB
144 |
145 |
146 |
147 |
148 | London Waterloo
149 | WAT
150 | via Brentford
151 |
152 |
153 |
154 |
155 | 19:34
156 | On time
157 | 1
158 | South Western Railway
159 | SW
160 | train
161 | 8
162 | +kJe9WIrueGPWUYhDzmRQg==
163 | SW182300
164 |
165 |
166 | London Waterloo
167 | WAT
168 |
169 |
170 |
171 |
172 | London Waterloo
173 | WAT
174 | via Brentford
175 |
176 |
177 |
178 |
179 | 19:42
180 | On time
181 | 2
182 | South Western Railway
183 | SW
184 | train
185 | 10
186 | cm080rz49AMkBqto0DmPCQ==
187 | SW211800
188 |
189 |
190 | London Waterloo
191 | WAT
192 |
193 |
194 |
195 |
196 | Mortlake
197 | MTL
198 |
199 |
200 |
201 |
202 | 19:49
203 | On time
204 | 1
205 | South Western Railway
206 | SW
207 | train
208 | 10
209 | 14nFdX55toGlajTRiRUE7g==
210 | SW188400
211 |
212 |
213 | Weybridge
214 | WYB
215 |
216 |
217 |
218 |
219 | London Waterloo
220 | WAT
221 | via Brentford
222 |
223 |
224 |
225 |
226 | 20:04
227 | On time
228 | 1
229 | South Western Railway
230 | SW
231 | train
232 | 10
233 | oUW4Wt3Vc+7BHVWXcrkWpQ==
234 | SW182400
235 |
236 |
237 | London Waterloo
238 | WAT
239 |
240 |
241 |
242 |
243 | London Waterloo
244 | WAT
245 | via Brentford
246 |
247 |
248 |
249 |
250 |
251 |
252 |
253 |
254 |
--------------------------------------------------------------------------------
/exampleResponses/arrivalDepartureBoard.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | 2018-01-11T18:31:44.5623443+00:00
6 | Isleworth
7 | ISL
8 | Putney
9 | PUT
10 | true
11 |
12 |
13 | 18:34
14 | On time
15 | 18:34
16 | On time
17 | 1
18 | South Western Railway
19 | SW
20 | train
21 | 10
22 | wfmF+NYLrCpeoJVHBxSxrQ==
23 | SW182100
24 |
25 |
26 | London Waterloo
27 | WAT
28 |
29 |
30 |
31 |
32 | London Waterloo
33 | WAT
34 | via Brentford
35 |
36 |
37 |
38 |
39 | 18:42
40 | On time
41 | 18:42
42 | On time
43 | 2
44 | South Western Railway
45 | SW
46 | train
47 | 10
48 | nh3WKFCFpkwRTwqpzEUc/A==
49 | SW211600
50 |
51 |
52 | London Waterloo
53 | WAT
54 |
55 |
56 |
57 |
58 | Mortlake
59 | MTL
60 |
61 |
62 |
63 |
64 | 18:49
65 | 18:51
66 | 18:49
67 | 18:51
68 | 1
69 | South Western Railway
70 | SW
71 | train
72 | 4
73 | KXIphaTeuVHS0/a4SWgoAg==
74 | SW188000
75 |
76 |
77 | Weybridge
78 | WYB
79 |
80 |
81 |
82 |
83 | London Waterloo
84 | WAT
85 | via Brentford
86 |
87 |
88 |
89 |
90 | 19:04
91 | On time
92 | 19:04
93 | On time
94 | 1
95 | South Western Railway
96 | SW
97 | train
98 | 8
99 | b5oGjwYNIrFOQCoeerXVsA==
100 | SW182200
101 |
102 |
103 | London Waterloo
104 | WAT
105 |
106 |
107 |
108 |
109 | London Waterloo
110 | WAT
111 | via Brentford
112 |
113 |
114 |
115 |
116 | 19:12
117 | On time
118 | 19:12
119 | On time
120 | 2
121 | South Western Railway
122 | SW
123 | train
124 | 10
125 | 5QgCfHmYd7JNvbV0YSyhVw==
126 | SW211700
127 |
128 |
129 | London Waterloo
130 | WAT
131 |
132 |
133 |
134 |
135 | Mortlake
136 | MTL
137 |
138 |
139 |
140 |
141 | 19:19
142 | On time
143 | 19:19
144 | On time
145 | 1
146 | South Western Railway
147 | SW
148 | train
149 | 4
150 | 2HTkZpwWG3h0h2h2gnYvPw==
151 | SW188200
152 |
153 |
154 | Weybridge
155 | WYB
156 |
157 |
158 |
159 |
160 | London Waterloo
161 | WAT
162 | via Brentford
163 |
164 |
165 |
166 |
167 | 19:34
168 | On time
169 | 19:34
170 | On time
171 | 1
172 | South Western Railway
173 | SW
174 | train
175 | 8
176 | +kJe9WIrueGPWUYhDzmRQg==
177 | SW182300
178 |
179 |
180 | London Waterloo
181 | WAT
182 |
183 |
184 |
185 |
186 | London Waterloo
187 | WAT
188 | via Brentford
189 |
190 |
191 |
192 |
193 | 19:42
194 | On time
195 | 19:42
196 | On time
197 | 2
198 | South Western Railway
199 | SW
200 | train
201 | 10
202 | cm080rz49AMkBqto0DmPCQ==
203 | SW211800
204 |
205 |
206 | London Waterloo
207 | WAT
208 |
209 |
210 |
211 |
212 | Mortlake
213 | MTL
214 |
215 |
216 |
217 |
218 | 19:49
219 | On time
220 | 19:49
221 | On time
222 | 1
223 | South Western Railway
224 | SW
225 | train
226 | 10
227 | 14nFdX55toGlajTRiRUE7g==
228 | SW188400
229 |
230 |
231 | Weybridge
232 | WYB
233 |
234 |
235 |
236 |
237 | London Waterloo
238 | WAT
239 | via Brentford
240 |
241 |
242 |
243 |
244 | 20:04
245 | On time
246 | 20:04
247 | On time
248 | 1
249 | South Western Railway
250 | SW
251 | train
252 | 10
253 | oUW4Wt3Vc+7BHVWXcrkWpQ==
254 | SW182400
255 |
256 |
257 | London Waterloo
258 | WAT
259 |
260 |
261 |
262 |
263 | London Waterloo
264 | WAT
265 | via Brentford
266 |
267 |
268 |
269 |
270 |
271 |
272 |
273 |
274 |
--------------------------------------------------------------------------------
/test/test.js:
--------------------------------------------------------------------------------
1 | /* eslint-env mocha */
2 | var assert = require('assert')
3 | var parsers = require('../parsers.js')
4 | var fs = require('fs')
5 |
6 | describe('Client options override correctly', function () {
7 | var Rail = require('../index.js')
8 |
9 | it('Original base url remains when not overriden', function () {
10 | const baseUrl = 'https://lite.realtime.nationalrail.co.uk/OpenLDBWS/ldb11.asmx'
11 | let client = new Rail('abc123')
12 | assert.equal(client.getBaseUrl(), baseUrl)
13 | })
14 |
15 | it('Overrides the base url', function () {
16 | const newBaseUrl = 'http://somewhere'
17 | let client = new Rail('abc123', { baseUrl: newBaseUrl })
18 | assert.equal(client.getBaseUrl(), newBaseUrl)
19 | })
20 | })
21 |
22 | /* arrivalBoardWithDets.xml */
23 | describe('ArrivalBoardWithDetails parsed correctly', function () {
24 | var fileContent = fs.readFileSync('./exampleResponses/arrivalBoardWithDets.xml', 'UTF-8')
25 | var parsedResult = parsers.parseArrivalsBoardWithDetails(fileContent)
26 |
27 | it('5 train services returned', function () {
28 | assert.equal(1, parsedResult.trainServices.length)
29 | })
30 |
31 | it('Service id of first service is resovled', function () {
32 | assert.equal('wfmF+NYLrCpeoJVHBxSxrQ==', parsedResult.trainServices[0].serviceId)
33 | })
34 |
35 | it('STA of service is correct', function () {
36 | assert.equal('18:34', parsedResult.trainServices[0].sta)
37 | })
38 |
39 | it('Operator of service is Southwestern trains', function () {
40 | assert.equal('South Western Railway', parsedResult.trainServices[0].operator)
41 | })
42 | })
43 |
44 | /* arrivalBoardWithDets_bus.xml */
45 | describe('Arrival Departure Board with Details when no train services are available', function () {
46 | var fileContent = fs.readFileSync('./exampleResponses/arrivalBoardWithDets_bus.xml', 'UTF-8')
47 | var parsedResult = parsers.parseArrivalsBoardWithDetails(fileContent)
48 |
49 | it('does not throw an error', function () {
50 | assert.deepEqual([], parsedResult.trainServices)
51 | })
52 | })
53 |
54 | /* arrivalDepartureBoard.xml */
55 | describe('Arrival Departure Board', function () {
56 | var fileContent = fs.readFileSync('./exampleResponses/arrivalDepartureBoard.xml', 'UTF-8')
57 | var parsedResult = parsers.parseArrivalsDepartureBoard(fileContent)
58 |
59 | it('10 Services returned', function () {
60 | assert.equal(10, parsedResult.trainServices.length)
61 | })
62 |
63 | it('Service 1 on time', function () {
64 | assert.equal('On time', parsedResult.trainServices[0].eta)
65 | })
66 |
67 | it('Service 1 platform ', function () {
68 | assert.equal(1, parsedResult.trainServices[0].platform)
69 | })
70 |
71 | it('Service 1 length ', function () {
72 | assert.equal(10, parsedResult.trainServices[0].length)
73 | })
74 |
75 | it('Service 1 destination ', function () {
76 | assert.equal('London Waterloo', parsedResult.trainServices[0].destination.name)
77 | })
78 | })
79 |
80 | /* arrivalDepartureBoardWithDetails.xml */
81 | describe('Arrival Departure Board with Details parsing is correct', function () {
82 | var fileContent = fs.readFileSync('./exampleResponses/arrivalDepartureBoardWithDetails.xml', 'UTF-8')
83 | var parsedResult = parsers.parseArrivalsDepartureBoardWithDetails(fileContent)
84 |
85 | it('Arrival Departure Board sta = 21:34', function () {
86 | assert.equal('18:34', parsedResult.trainServices[0].sta)
87 | })
88 | it('lArrival Departure Board eta = On time', function () {
89 | assert.equal('On time', parsedResult.trainServices[0].eta)
90 | })
91 | it('Arrival Departure Board std = 18:34', function () {
92 | assert.equal('18:34', parsedResult.trainServices[0].std)
93 | })
94 | it('Arrival Departure Board etd = On time', function () {
95 | assert.equal('On time', parsedResult.trainServices[0].etd)
96 | })
97 | it('Arrival Departure Board platform = 1', function () {
98 | assert.equal('1', parsedResult.trainServices[0].platform)
99 | })
100 | it('Arrival Departure Board operator = South Western Railway', function () {
101 | assert.equal('South Western Railway', parsedResult.trainServices[0].operator)
102 | })
103 | it('Arrival Departure Board operatorCode = SW', function () {
104 | assert.equal('SW', parsedResult.trainServices[0].operatorCode)
105 | })
106 | it('Arrival Departure Board length = 10', function () {
107 | assert.equal('10', parsedResult.trainServices[0].length)
108 | })
109 | it('Arrival Departure BoardservicId = MrHNnCAHgnHGs5KtWtLkWw==', function () {
110 | assert.equal('wfmF+NYLrCpeoJVHBxSxrQ==', parsedResult.trainServices[0].serviceId)
111 | })
112 | it('Arrival Departure Board origin = WAT and LondonWaterloo', function () {
113 | var origin = parsedResult.trainServices[0].origin
114 | assert.equal('London Waterloo', origin.name)
115 | assert.equal('WAT', origin.crs)
116 | })
117 | it('Arrival Departure Board origin = WAT and LondonWaterloo', function () {
118 | var destination = parsedResult.trainServices[0].destination
119 | assert.equal('London Waterloo', destination.name)
120 | assert.equal('WAT', destination.crs)
121 | })
122 | it('PreviousCallingPoints array is correct size 14', function () {
123 | var arr = parsedResult.trainServices[0].previousCallingPoints
124 | assert.equal(14, arr.length)
125 | })
126 | it('Last previous calling point crs code = WAT', function () {
127 | var arr = parsedResult.trainServices[0].previousCallingPoints
128 | assert.equal('HOU', arr[13].crs)
129 | })
130 | it('Last previous calling point locationName = London Waterloo', function () {
131 | var arr = parsedResult.trainServices[0].previousCallingPoints
132 | assert.equal('Hounslow', arr[13].locationName)
133 | })
134 | it('Last previous calling point st = 09:45', function () {
135 | var arr = parsedResult.trainServices[0].previousCallingPoints
136 | assert.equal('18:31', arr[13].st)
137 | })
138 | it('Last previous calling point et = On time', function () {
139 | var arr = parsedResult.trainServices[0].previousCallingPoints
140 | assert.equal('On time', arr[13].et)
141 | })
142 | it('SubsequentCallingPoints array is correct size 14', function () {
143 | var arr = parsedResult.trainServices[0].subsequentCallingPoints
144 | assert.equal(12, arr.length)
145 | })
146 | it('First subsequent calling point crs code = WAT', function () {
147 | var arr = parsedResult.trainServices[0].subsequentCallingPoints
148 | assert.equal('SYL', arr[0].crs)
149 | })
150 | it('First subsequent calling point locationName = London Waterloo', function () {
151 | var arr = parsedResult.trainServices[0].subsequentCallingPoints
152 | assert.equal('Syon Lane', arr[0].locationName)
153 | })
154 | it('First subsequent calling point st = 09:45', function () {
155 | var arr = parsedResult.trainServices[0].subsequentCallingPoints
156 | assert.equal('18:36', arr[0].st)
157 | })
158 | it('First subsequent calling point et = On time', function () {
159 | var arr = parsedResult.trainServices[0].subsequentCallingPoints
160 | assert.equal('On time', arr[0].et)
161 | })
162 | })
163 |
164 | /* arrivalsBoard.xml */
165 | describe('Arrival Departure Board', function () {
166 | var fileContent = fs.readFileSync('./exampleResponses/arrivalsBoard.xml', 'UTF-8')
167 | var parsedResult = parsers.parseArrivalsBoardResponse(fileContent)
168 |
169 | it('10 Services returned', function () {
170 | assert.equal(10, parsedResult.trainServices.length)
171 | })
172 |
173 | it('Service 9 on time', function () {
174 | assert.equal('On time', parsedResult.trainServices[8].eta)
175 | })
176 |
177 | it('Service 9 platform ', function () {
178 | assert.equal(1, parsedResult.trainServices[8].platform)
179 | })
180 |
181 | it('Service 9 length ', function () {
182 | assert.equal(10, parsedResult.trainServices[8].length)
183 | })
184 |
185 | it('Service 1 origin ', function () {
186 | assert.equal('Weybridge', parsedResult.trainServices[8].origin.name)
187 | })
188 | })
189 |
190 | /* departureBoard.xml */
191 | describe('Departure Board', function () {
192 | var fileContent = fs.readFileSync('./exampleResponses/departureBoard.xml', 'UTF-8')
193 | var parsedResult = parsers.parseDepartureBoardResponse(fileContent)
194 |
195 | it('15 Services returned', function () {
196 | assert.equal(10, parsedResult.trainServices.length)
197 | })
198 |
199 | it('Service 10 etd', function () {
200 | assert.equal('On time', parsedResult.trainServices[9].etd)
201 | })
202 | it('Service 10 eta undefined', function () {
203 | assert.equal(undefined, parsedResult.trainServices[9].eta)
204 | })
205 |
206 | it('Service 10 platform ', function () {
207 | assert.equal(1, parsedResult.trainServices[9].platform)
208 | })
209 |
210 | it('Service 10 length ', function () {
211 | assert.equal(10, parsedResult.trainServices[9].length)
212 | })
213 |
214 | it('Service 1 origin ', function () {
215 | assert.equal('London Waterloo', parsedResult.trainServices[0].origin.name)
216 | })
217 | })
218 |
219 | /* departureBoardWithDetails.xml */
220 | describe('Departure Board With Details', function () {
221 | var fileContent = fs.readFileSync('./exampleResponses/departureBoardWithDetails.xml', 'UTF-8')
222 | var parsedResult = parsers.parseDepartureBoardWithDetailsResponse(fileContent)
223 |
224 | it('10 Services returned', function () {
225 | assert.equal(10, parsedResult.trainServices.length)
226 | })
227 |
228 | it('Service 10 std', function () {
229 | assert.equal('20:04', parsedResult.trainServices[9].std)
230 | })
231 |
232 | it('Service 10 sta undefined', function () {
233 | assert.equal(undefined, parsedResult.trainServices[9].sta)
234 | })
235 |
236 | it('Service 10 platform ', function () {
237 | assert.equal(1, parsedResult.trainServices[9].platform)
238 | })
239 |
240 | it('Service 10 operator ', function () {
241 | assert.equal('South Western Railway', parsedResult.trainServices[9].operator)
242 | })
243 |
244 | it('Service 10 has 9 calling points ', function () {
245 | assert.equal(12, parsedResult.trainServices[0].subsequentCallingPoints.length)
246 | })
247 |
248 | it('Service 10 calling point 9 is Clapham Junction ', function () {
249 | assert.equal('Clapham Junction', parsedResult.trainServices[0].subsequentCallingPoints[8].locationName)
250 | assert.equal('CLJ', parsedResult.trainServices[0].subsequentCallingPoints[8].crs)
251 | })
252 | })
253 |
254 | /* fastestDeparture.xml */
255 | describe('FastestDeparture parsed correctly', function () {
256 | var fileContent = fs.readFileSync('./exampleResponses/fastestDeparture.xml', 'UTF-8')
257 | var parsedResult = parsers.parseFastestDeparture(fileContent)
258 |
259 | it('1 train service returned', function () {
260 | assert.equal(1, parsedResult.trainServices.length)
261 | })
262 |
263 | it('Service id of service is resovled', function () {
264 | assert.equal('wfmF+NYLrCpeoJVHBxSxrQ==', parsedResult.trainServices[0].serviceId)
265 | })
266 |
267 | it('STA of service is correct', function () {
268 | assert.equal('18:34', parsedResult.trainServices[0].sta)
269 | })
270 |
271 | it('Operator of service is South Western Railway', function () {
272 | assert.equal('South Western Railway', parsedResult.trainServices[0].operator)
273 | })
274 |
275 | it('Origin of service is London Waterloo', function () {
276 | assert.equal('London Waterloo', parsedResult.trainServices[0].origin.name)
277 | assert.equal('WAT', parsedResult.trainServices[0].origin.crs)
278 | })
279 | })
280 |
281 | /* fastestDepartureWithDetails.xml */
282 | describe('FastestDeparture with Details parsed correctly', function () {
283 | var fileContent = fs.readFileSync('./exampleResponses/fastestDeparturesWithDetails.xml', 'UTF-8')
284 | var parsedResult = parsers.parseFastestDeparturesWithDetail(fileContent)
285 |
286 | it('1 train service returned', function () {
287 | assert.equal(1, parsedResult.trainServices.length)
288 | })
289 |
290 | it('Service id of service is resovled', function () {
291 | assert.equal('wfmF+NYLrCpeoJVHBxSxrQ==', parsedResult.trainServices[0].serviceId)
292 | })
293 |
294 | it('ETA of service is correct', function () {
295 | assert.equal('On time', parsedResult.trainServices[0].eta)
296 | })
297 |
298 | it('Operator of service is South Western Railway', function () {
299 | assert.equal('South Western Railway', parsedResult.trainServices[0].operator)
300 | })
301 |
302 | it('Origin of service is Weybridge', function () {
303 | assert.equal('London Waterloo', parsedResult.trainServices[0].destination.name)
304 | assert.equal('WAT', parsedResult.trainServices[0].destination.crs)
305 | })
306 |
307 | it('Subsequent Calling Points is ok', function () {
308 | assert.equal(12, parsedResult.trainServices[0].subsequentCallingPoints.length)
309 | assert.equal('Chiswick', parsedResult.trainServices[0].subsequentCallingPoints[3].locationName)
310 | assert.equal(10, parsedResult.trainServices[0].subsequentCallingPoints[3].length)
311 | assert.equal('18:44', parsedResult.trainServices[0].subsequentCallingPoints[3].st)
312 | })
313 | })
314 |
315 | /* nextDeparture.xml */
316 | describe('getNextDeparture parsed correctly', function () {
317 | var fileContent = fs.readFileSync('./exampleResponses/nextDeparture.xml', 'UTF-8')
318 | var parsedResult = parsers.parseNextDepartureResponse(fileContent)
319 |
320 | it('1 train service returned', function () {
321 | assert.equal(1, parsedResult.trainServices.length)
322 | })
323 |
324 | it('RSID Parsed correctly', function () {
325 | assert.equal('SW182100', parsedResult.trainServices[0].rsid)
326 | })
327 |
328 | it('Destination', function () {
329 | assert.equal('London Waterloo', parsedResult.trainServices[0].destination.name)
330 | })
331 |
332 | it('STD is parsed', function () {
333 | assert.equal('18:34', parsedResult.trainServices[0].std)
334 | })
335 | })
336 |
337 | /* nextDepartureWithDetails.xml */
338 | describe('getNextDepartureWithDetails parsed correctly', function () {
339 | var fileContent = fs.readFileSync('./exampleResponses/nextDepartureWithDetails.xml', 'UTF-8')
340 | var parsedResult = parsers.parseNextDepartureWithDetailsResponse(fileContent)
341 |
342 | it('1 train service returned', function () {
343 | assert.equal(1, parsedResult.trainServices.length)
344 | })
345 |
346 | it('Service id of service is resovled', function () {
347 | assert.equal('wfmF+NYLrCpeoJVHBxSxrQ==', parsedResult.trainServices[0].serviceId)
348 | })
349 |
350 | it('STA of service is correct', function () {
351 | assert.equal('18:34', parsedResult.trainServices[0].sta)
352 | })
353 |
354 | it('Operator of service is South Western Railway', function () {
355 | assert.equal('South Western Railway', parsedResult.trainServices[0].operator)
356 | })
357 |
358 | it('Origin of service is Weybridge', function () {
359 | assert.equal('London Waterloo', parsedResult.trainServices[0].origin.name)
360 | assert.equal('WAT', parsedResult.trainServices[0].origin.crs)
361 | })
362 | })
363 | /* serviceDetails.xml */
364 | describe('Service Details parsing is correct', function () {
365 | var fileContent = fs.readFileSync('./exampleResponses/serviceDetails.xml', 'UTF-8')
366 | var parsedResult = parsers.parseServiceDetails(fileContent)
367 | it('returned object from example operator code = SW', function () {
368 | assert.equal('SW', parsedResult.serviceDetails.operatorCode)
369 | })
370 | it('returned obejct from example operator = South Western Railway', function () {
371 | assert.equal('South Western Railway', parsedResult.serviceDetails.operator)
372 | })
373 | it('returned object from example sta = 18:34', function () {
374 | assert.equal('18:34', parsedResult.serviceDetails.sta)
375 | })
376 | it('returned object from example std = 18:34', function () {
377 | assert.equal('18:34', parsedResult.serviceDetails.std)
378 | })
379 | it('returned object from example operatorCode = SW', function () {
380 | assert.equal('SW', parsedResult.serviceDetails.operatorCode)
381 | })
382 | it('returned object from example operator = South Western Railway', function () {
383 | assert.equal('South Western Railway', parsedResult.serviceDetails.operator)
384 | })
385 |
386 | it('returned object from example eta is undefined', function () {
387 | assert.equal(undefined, parsedResult.serviceDetails.etd)
388 | })
389 | it('returned object from example length = 10', function () {
390 | assert.equal('10', parsedResult.serviceDetails.length)
391 | })
392 | it('returned object from example platform = 1', function () {
393 | assert.equal('1', parsedResult.serviceDetails.platform)
394 | })
395 | it('PreviousCallingPoints array is correct size 14', function () {
396 | var arr = parsedResult.serviceDetails.previousCallingPoints
397 | assert.equal(14, arr.length)
398 | })
399 | it('First previous calling point crs code = WAT', function () {
400 | var arr = parsedResult.serviceDetails.previousCallingPoints
401 | assert.equal('WAT', arr[0].crs)
402 | })
403 | it('First previous calling point locationName = London Waterloo', function () {
404 | var arr = parsedResult.serviceDetails.previousCallingPoints
405 | assert.equal('London Waterloo', arr[0].locationName)
406 | })
407 | it('First previous calling point st = 09:45', function () {
408 | var arr = parsedResult.serviceDetails.previousCallingPoints
409 | assert.equal('17:45', arr[0].st)
410 | })
411 | it('First previous calling point crs = SYL', function () {
412 | var arr = parsedResult.serviceDetails.previousCallingPoints
413 | assert.equal('WAT', arr[0].crs)
414 | })
415 | it('subsequentCallingPoints array is correct size 12', function () {
416 | var arr = parsedResult.serviceDetails.subsequentCallingPoints
417 | assert.equal(12, arr.length)
418 | })
419 | it('last subsequent calling point crs code = WAT', function () {
420 | var arr = parsedResult.serviceDetails.subsequentCallingPoints
421 | assert.equal('WAT', arr[11].crs)
422 | })
423 | it('last subsequent calling point locationName = London Waterloo', function () {
424 | var arr = parsedResult.serviceDetails.subsequentCallingPoints
425 | assert.equal('London Waterloo', arr[11].locationName)
426 | })
427 | it('last subsequent calling point st = 18:36', function () {
428 | var arr = parsedResult.serviceDetails.subsequentCallingPoints
429 | assert.equal('18:36', arr[0].st)
430 | })
431 | it('last subsequent calling point et = On time', function () {
432 | var arr = parsedResult.serviceDetails.subsequentCallingPoints
433 | assert.equal('On time', arr[11].et)
434 | })
435 | })
436 |
--------------------------------------------------------------------------------
/exampleResponses/departureBoardWithDetails.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | 2018-01-11T18:32:37.1502814+00:00
6 | Isleworth
7 | ISL
8 | Putney
9 | PUT
10 | true
11 |
12 |
13 | 18:34
14 | On time
15 | 1
16 | South Western Railway
17 | SW
18 | train
19 | 10
20 | wfmF+NYLrCpeoJVHBxSxrQ==
21 | SW182100
22 |
23 |
24 | London Waterloo
25 | WAT
26 |
27 |
28 |
29 |
30 | London Waterloo
31 | WAT
32 | via Brentford
33 |
34 |
35 |
36 |
37 |
38 | Syon Lane
39 | SYL
40 | 18:36
41 | On time
42 | 10
43 |
44 |
45 | Brentford
46 | BFD
47 | 18:38
48 | On time
49 | 10
50 |
51 |
52 | Kew Bridge
53 | KWB
54 | 18:41
55 | On time
56 | 10
57 |
58 |
59 | Chiswick
60 | CHK
61 | 18:44
62 | On time
63 | 10
64 |
65 |
66 | Barnes Bridge
67 | BNI
68 | 18:46
69 | On time
70 | 10
71 |
72 |
73 | Barnes
74 | BNS
75 | 18:49
76 | On time
77 | 10
78 |
79 |
80 | Putney
81 | PUT
82 | 18:52
83 | On time
84 | 10
85 |
86 |
87 | Wandsworth Town
88 | WNT
89 | 18:55
90 | On time
91 | 10
92 |
93 |
94 | Clapham Junction
95 | CLJ
96 | 18:58
97 | On time
98 | 10
99 |
100 |
101 | Queenstown Road Battersea
102 | QRB
103 | 19:01
104 | On time
105 | 10
106 |
107 |
108 | Vauxhall
109 | VXH
110 | 19:04
111 | On time
112 | 10
113 |
114 |
115 | London Waterloo
116 | WAT
117 | 19:11
118 | On time
119 | 10
120 |
121 |
122 |
123 |
124 |
125 | 18:42
126 | On time
127 | 2
128 | South Western Railway
129 | SW
130 | train
131 | 10
132 | nh3WKFCFpkwRTwqpzEUc/A==
133 | SW211600
134 |
135 |
136 | London Waterloo
137 | WAT
138 |
139 |
140 |
141 |
142 | Mortlake
143 | MTL
144 |
145 |
146 |
147 |
148 |
149 | Hounslow
150 | HOU
151 | 18:45
152 | On time
153 | 10
154 |
155 |
156 | Whitton
157 | WTN
158 | 18:53
159 | On time
160 | 10
161 |
162 |
163 | Twickenham
164 | TWI
165 | 18:56
166 | On time
167 | 10
168 |
169 |
170 | St Margarets (London)
171 | SMG
172 | 19:00
173 | On time
174 | 10
175 |
176 |
177 | Richmond
178 | RMD
179 | 19:03
180 | On time
181 | 10
182 |
183 |
184 | North Sheen
185 | NSH
186 | 19:06
187 | On time
188 | 10
189 |
190 |
191 | Mortlake
192 | MTL
193 | 19:08
194 | On time
195 | 10
196 |
197 |
198 |
199 |
200 |
201 | 18:49
202 | 18:53
203 | 1
204 | South Western Railway
205 | SW
206 | train
207 | 4
208 | KXIphaTeuVHS0/a4SWgoAg==
209 | SW188000
210 |
211 |
212 | Weybridge
213 | WYB
214 |
215 |
216 |
217 |
218 | London Waterloo
219 | WAT
220 | via Brentford
221 |
222 |
223 |
224 |
225 |
226 | Syon Lane
227 | SYL
228 | 18:51
229 | 18:55
230 | 4
231 |
232 |
233 | Brentford
234 | BFD
235 | 18:53
236 | 18:57
237 | 4
238 |
239 |
240 | Kew Bridge
241 | KWB
242 | 18:56
243 | 19:00
244 | 4
245 |
246 |
247 | Chiswick
248 | CHK
249 | 18:59
250 | 19:02
251 | 4
252 |
253 |
254 | Barnes Bridge
255 | BNI
256 | 19:01
257 | 19:05
258 | 4
259 |
260 |
261 | Barnes
262 | BNS
263 | 19:04
264 | 19:08
265 | 4
266 |
267 |
268 | Putney
269 | PUT
270 | 19:07
271 | 19:10
272 | 4
273 |
274 |
275 | Wandsworth Town
276 | WNT
277 | 19:10
278 | 19:13
279 | 4
280 |
281 |
282 | Clapham Junction
283 | CLJ
284 | 19:13
285 | 19:16
286 | 4
287 |
288 |
289 | Queenstown Road Battersea
290 | QRB
291 | 19:16
292 | 19:19
293 | 4
294 |
295 |
296 | Vauxhall
297 | VXH
298 | 19:19
299 | 19:22
300 | 4
301 |
302 |
303 | London Waterloo
304 | WAT
305 | 19:26
306 | On time
307 | 4
308 |
309 |
310 |
311 |
312 |
313 | 19:04
314 | On time
315 | 1
316 | South Western Railway
317 | SW
318 | train
319 | 8
320 | b5oGjwYNIrFOQCoeerXVsA==
321 | SW182200
322 |
323 |
324 | London Waterloo
325 | WAT
326 |
327 |
328 |
329 |
330 | London Waterloo
331 | WAT
332 | via Brentford
333 |
334 |
335 |
336 |
337 |
338 | Syon Lane
339 | SYL
340 | 19:06
341 | On time
342 | 8
343 |
344 |
345 | Brentford
346 | BFD
347 | 19:08
348 | On time
349 | 8
350 |
351 |
352 | Kew Bridge
353 | KWB
354 | 19:11
355 | On time
356 | 8
357 |
358 |
359 | Chiswick
360 | CHK
361 | 19:14
362 | On time
363 | 8
364 |
365 |
366 | Barnes Bridge
367 | BNI
368 | 19:16
369 | On time
370 | 8
371 |
372 |
373 | Barnes
374 | BNS
375 | 19:19
376 | On time
377 | 8
378 |
379 |
380 | Putney
381 | PUT
382 | 19:22
383 | On time
384 | 8
385 |
386 |
387 | Wandsworth Town
388 | WNT
389 | 19:25
390 | On time
391 | 8
392 |
393 |
394 | Clapham Junction
395 | CLJ
396 | 19:28
397 | On time
398 | 8
399 |
400 |
401 | Queenstown Road Battersea
402 | QRB
403 | 19:31
404 | On time
405 | 8
406 |
407 |
408 | Vauxhall
409 | VXH
410 | 19:34
411 | On time
412 | 8
413 |
414 |
415 | London Waterloo
416 | WAT
417 | 19:41
418 | On time
419 | 8
420 |
421 |
422 |
423 |
424 |
425 | 19:12
426 | On time
427 | 2
428 | South Western Railway
429 | SW
430 | train
431 | 10
432 | 5QgCfHmYd7JNvbV0YSyhVw==
433 | SW211700
434 |
435 |
436 | London Waterloo
437 | WAT
438 |
439 |
440 |
441 |
442 | Mortlake
443 | MTL
444 |
445 |
446 |
447 |
448 |
449 | Hounslow
450 | HOU
451 | 19:15
452 | On time
453 | 10
454 |
455 |
456 | Whitton
457 | WTN
458 | 19:23
459 | On time
460 | 10
461 |
462 |
463 | Twickenham
464 | TWI
465 | 19:26
466 | On time
467 | 10
468 |
469 |
470 | St Margarets (London)
471 | SMG
472 | 19:30
473 | On time
474 | 10
475 |
476 |
477 | Richmond
478 | RMD
479 | 19:33
480 | On time
481 | 10
482 |
483 |
484 | North Sheen
485 | NSH
486 | 19:36
487 | On time
488 | 10
489 |
490 |
491 | Mortlake
492 | MTL
493 | 19:38
494 | On time
495 | 10
496 |
497 |
498 |
499 |
500 |
501 | 19:19
502 | On time
503 | 1
504 | South Western Railway
505 | SW
506 | train
507 | 4
508 | 2HTkZpwWG3h0h2h2gnYvPw==
509 | SW188200
510 |
511 |
512 | Weybridge
513 | WYB
514 |
515 |
516 |
517 |
518 | London Waterloo
519 | WAT
520 | via Brentford
521 |
522 |
523 |
524 |
525 |
526 | Syon Lane
527 | SYL
528 | 19:21
529 | On time
530 | 4
531 |
532 |
533 | Brentford
534 | BFD
535 | 19:23
536 | On time
537 | 4
538 |
539 |
540 | Kew Bridge
541 | KWB
542 | 19:26
543 | On time
544 | 4
545 |
546 |
547 | Chiswick
548 | CHK
549 | 19:29
550 | On time
551 | 4
552 |
553 |
554 | Barnes Bridge
555 | BNI
556 | 19:31
557 | On time
558 | 4
559 |
560 |
561 | Barnes
562 | BNS
563 | 19:34
564 | On time
565 | 4
566 |
567 |
568 | Putney
569 | PUT
570 | 19:37
571 | On time
572 | 4
573 |
574 |
575 | Wandsworth Town
576 | WNT
577 | 19:40
578 | On time
579 | 4
580 |
581 |
582 | Clapham Junction
583 | CLJ
584 | 19:43
585 | On time
586 | 4
587 |
588 |
589 | Queenstown Road Battersea
590 | QRB
591 | 19:46
592 | On time
593 | 4
594 |
595 |
596 | Vauxhall
597 | VXH
598 | 19:49
599 | On time
600 | 4
601 |
602 |
603 | London Waterloo
604 | WAT
605 | 19:56
606 | On time
607 | 4
608 |
609 |
610 |
611 |
612 |
613 | 19:34
614 | On time
615 | 1
616 | South Western Railway
617 | SW
618 | train
619 | 8
620 | +kJe9WIrueGPWUYhDzmRQg==
621 | SW182300
622 |
623 |
624 | London Waterloo
625 | WAT
626 |
627 |
628 |
629 |
630 | London Waterloo
631 | WAT
632 | via Brentford
633 |
634 |
635 |
636 |
637 |
638 | Syon Lane
639 | SYL
640 | 19:36
641 | On time
642 | 8
643 |
644 |
645 | Brentford
646 | BFD
647 | 19:38
648 | On time
649 | 8
650 |
651 |
652 | Kew Bridge
653 | KWB
654 | 19:41
655 | On time
656 | 8
657 |
658 |
659 | Chiswick
660 | CHK
661 | 19:44
662 | On time
663 | 8
664 |
665 |
666 | Barnes Bridge
667 | BNI
668 | 19:46
669 | On time
670 | 8
671 |
672 |
673 | Barnes
674 | BNS
675 | 19:49
676 | On time
677 | 8
678 |
679 |
680 | Putney
681 | PUT
682 | 19:52
683 | On time
684 | 8
685 |
686 |
687 | Wandsworth Town
688 | WNT
689 | 19:55
690 | On time
691 | 8
692 |
693 |
694 | Clapham Junction
695 | CLJ
696 | 19:58
697 | On time
698 | 8
699 |
700 |
701 | Queenstown Road Battersea
702 | QRB
703 | 20:01
704 | On time
705 | 8
706 |
707 |
708 | Vauxhall
709 | VXH
710 | 20:04
711 | On time
712 | 8
713 |
714 |
715 | London Waterloo
716 | WAT
717 | 20:11
718 | On time
719 | 8
720 |
721 |
722 |
723 |
724 |
725 | 19:42
726 | On time
727 | 2
728 | South Western Railway
729 | SW
730 | train
731 | 10
732 | cm080rz49AMkBqto0DmPCQ==
733 | SW211800
734 |
735 |
736 | London Waterloo
737 | WAT
738 |
739 |
740 |
741 |
742 | Mortlake
743 | MTL
744 |
745 |
746 |
747 |
748 |
749 | Hounslow
750 | HOU
751 | 19:45
752 | On time
753 | 10
754 |
755 |
756 | Whitton
757 | WTN
758 | 19:53
759 | On time
760 | 10
761 |
762 |
763 | Twickenham
764 | TWI
765 | 19:56
766 | On time
767 | 10
768 |
769 |
770 | St Margarets (London)
771 | SMG
772 | 20:00
773 | On time
774 | 10
775 |
776 |
777 | Richmond
778 | RMD
779 | 20:03
780 | On time
781 | 10
782 |
783 |
784 | North Sheen
785 | NSH
786 | 20:06
787 | On time
788 | 10
789 |
790 |
791 | Mortlake
792 | MTL
793 | 20:08
794 | On time
795 | 10
796 |
797 |
798 |
799 |
800 |
801 | 19:49
802 | On time
803 | 1
804 | South Western Railway
805 | SW
806 | train
807 | 10
808 | 14nFdX55toGlajTRiRUE7g==
809 | SW188400
810 |
811 |
812 | Weybridge
813 | WYB
814 |
815 |
816 |
817 |
818 | London Waterloo
819 | WAT
820 | via Brentford
821 |
822 |
823 |
824 |
825 |
826 | Syon Lane
827 | SYL
828 | 19:51
829 | On time
830 | 10
831 |
832 |
833 | Brentford
834 | BFD
835 | 19:53
836 | On time
837 | 10
838 |
839 |
840 | Kew Bridge
841 | KWB
842 | 19:56
843 | On time
844 | 10
845 |
846 |
847 | Chiswick
848 | CHK
849 | 19:59
850 | On time
851 | 10
852 |
853 |
854 | Barnes Bridge
855 | BNI
856 | 20:01
857 | On time
858 | 10
859 |
860 |
861 | Barnes
862 | BNS
863 | 20:04
864 | On time
865 | 10
866 |
867 |
868 | Putney
869 | PUT
870 | 20:07
871 | On time
872 | 10
873 |
874 |
875 | Wandsworth Town
876 | WNT
877 | 20:10
878 | On time
879 | 10
880 |
881 |
882 | Clapham Junction
883 | CLJ
884 | 20:13
885 | On time
886 | 10
887 |
888 |
889 | Queenstown Road Battersea
890 | QRB
891 | 20:16
892 | On time
893 | 10
894 |
895 |
896 | Vauxhall
897 | VXH
898 | 20:19
899 | On time
900 | 10
901 |
902 |
903 | London Waterloo
904 | WAT
905 | 20:27
906 | On time
907 | 10
908 |
909 |
910 |
911 |
912 |
913 | 20:04
914 | On time
915 | 1
916 | South Western Railway
917 | SW
918 | train
919 | 10
920 | oUW4Wt3Vc+7BHVWXcrkWpQ==
921 | SW182400
922 |
923 |
924 | London Waterloo
925 | WAT
926 |
927 |
928 |
929 |
930 | London Waterloo
931 | WAT
932 | via Brentford
933 |
934 |
935 |
936 |
937 |
938 | Syon Lane
939 | SYL
940 | 20:06
941 | On time
942 | 10
943 |
944 |
945 | Brentford
946 | BFD
947 | 20:08
948 | On time
949 | 10
950 |
951 |
952 | Kew Bridge
953 | KWB
954 | 20:11
955 | On time
956 | 10
957 |
958 |
959 | Chiswick
960 | CHK
961 | 20:14
962 | On time
963 | 10
964 |
965 |
966 | Barnes Bridge
967 | BNI
968 | 20:16
969 | On time
970 | 10
971 |
972 |
973 | Barnes
974 | BNS
975 | 20:19
976 | On time
977 | 10
978 |
979 |
980 | Putney
981 | PUT
982 | 20:22
983 | On time
984 | 10
985 |
986 |
987 | Wandsworth Town
988 | WNT
989 | 20:25
990 | On time
991 | 10
992 |
993 |
994 | Clapham Junction
995 | CLJ
996 | 20:28
997 | On time
998 | 10
999 |
1000 |
1001 | Queenstown Road Battersea
1002 | QRB
1003 | 20:31
1004 | On time
1005 | 10
1006 |
1007 |
1008 | Vauxhall
1009 | VXH
1010 | 20:34
1011 | On time
1012 | 10
1013 |
1014 |
1015 | London Waterloo
1016 | WAT
1017 | 20:41
1018 | On time
1019 | 10
1020 |
1021 |
1022 |
1023 |
1024 |
1025 |
1026 |
1027 |
1028 |
1029 |
--------------------------------------------------------------------------------