From 6eebee7f49196db240e8dabb75341f9b4c227ff6 Mon Sep 17 00:00:00 2001 From: Valentin Oliver Date: Sat, 3 Feb 2018 23:28:27 +0000 Subject: [PATCH 1/2] aircraft endpoint initial commit --- endpoints/aircraft/documentation.md | 13 +++ endpoints/aircraft/index.js | 86 ++++++++++++++++++++ endpoints/aircraft/tests/integration_test.js | 34 ++++++++ 3 files changed, 133 insertions(+) create mode 100644 endpoints/aircraft/documentation.md create mode 100644 endpoints/aircraft/index.js create mode 100644 endpoints/aircraft/tests/integration_test.js diff --git a/endpoints/aircraft/documentation.md b/endpoints/aircraft/documentation.md new file mode 100644 index 00000000..6c6a330a --- /dev/null +++ b/endpoints/aircraft/documentation.md @@ -0,0 +1,13 @@ +# Icelandic Aircraft Registry + +Source: [The Icelandic Transport Authority](https://www.samgongustofa.is/flug/loftfor/loftfaraskra/) + +- GET [/aircraft](https://apis.is/aircraft) + +Search the Icelandic aircraft registry + +| Parameters | Description | Example | +|-------------------|-----------------------------------------------------------------------|-----------------| +| Search (required) | Aircraft identification, registration number, type, owner or operator | [TF-AAC](https://apis.is/aircraft?search=TF-AAC), [1073](https://apis.is/ship?search=1073) | + +--- diff --git a/endpoints/aircraft/index.js b/endpoints/aircraft/index.js new file mode 100644 index 00000000..d31c585a --- /dev/null +++ b/endpoints/aircraft/index.js @@ -0,0 +1,86 @@ +/* eslint-disable no-undef */ +/* eslint-disable no-restricted-globals */ +/* eslint-disable prefer-promise-reject-errors */ +const request = require('request') +const $ = require('cheerio') +const h = require('apis-helpers') +const app = require('../../server') + +const lookupAircraft = searchStr => new Promise((resolve, reject) => { + // Encode searchString so that Icelandic characters will work + const searchString = encodeURIComponent(searchStr) + const url = `https://www.samgongustofa.is/flug/loftfor/loftfaraskra?aq=${searchString}` + request.get({ + headers: { 'User-Agent': h.browser() }, + url, + }, (error, response, body) => { + if (error || response.statusCode !== 200) { + reject('www.samgongustofa.is refuses to respond or give back data') + } + + const data = $(body) + const fieldList = [] + data.find('.vehicleinfo ul').each((index, element) => { + const fields = [] + $(element).find('li').each((i, el) => { + let val; + if (i < 7) { + val = $(el).find('span').text() + + } else { + // i === 7 contains info about aircraft owner + // i === 8 contains info about aircraft operator + // We'll parse these fields separately + + const text = $(el).find('span').text(); + const info = text.split(/\s{3,}/g); + + val = { + name: info[1], + address: info[2], + locality: info[3], + country: info[4], + } + } + + fields.push(val) + }) + + if (fields.length > 0) { + fieldList.push(fields) + } + }) + + if (fieldList.length > 0 && fieldList[0].length > 0) { + resolve(fieldList.map((fields) => { + return { + id: fields[0], + registrationNumber: parseInt(fields[1]), + type: fields[2], + buildYear: parseInt(fields[3]), + serialNumber: parseInt(fields[4]), + maxWeight: parseInt(fields[5]), + passengers: parseInt(fields[6]), + owner: fields[7], + operator: fields[8], + } + })) + } else { + reject(`No aircraft found with the query ${searchStr}`) + } + }) +}) + +app.get('/aircraft', (req, res) => { + const search = req.query.search || '' + + if (!search) { + return res.status(431).json({ error: 'Please provide a valid search string to lookup' }) + } + + lookupAircraft(search) + .then(aircraft => res.cache().json({ results: aircraft })) + .catch(error => res.status(500).json({ error })) +}) + +module.exports = lookupAircraft diff --git a/endpoints/aircraft/tests/integration_test.js b/endpoints/aircraft/tests/integration_test.js new file mode 100644 index 00000000..7298de1a --- /dev/null +++ b/endpoints/aircraft/tests/integration_test.js @@ -0,0 +1,34 @@ +/* eslint-disable import/extensions */ +const assert = require('assert') +const request = require('request') +const helpers = require('../../../lib/test_helpers.js') + +describe('aircraft', () => { + it('should return an array of objects containing correct fields', (done) => { + const fieldsToCheckFor = [ + 'id', + 'registrationNumber', + 'type', + 'buildYear', + 'serialNumber', + 'maxWeight', + 'passengers', + 'owner', + 'operator', + ] + const params = helpers.testRequestParams('/aircraft', { search: '100' }) + const resultHandler = helpers.testRequestHandlerForFields(done, fieldsToCheckFor) + request.get(params, resultHandler) + }) + it('should return a 404 when an aircraft is not found', (done) => { + const params = helpers.testRequestParams('/aircraft', { search: 'loftur' }) + request.get(params, (error, response, body) => { + if (error) { + return done(error) + } + const json = JSON.parse(body) + assert.equal(json.error, 'No aircraft found with the query \'loftur\'') + done() + }) + }) +}) From 3cc779657f21a350efc4b9adcddaf751256ad877 Mon Sep 17 00:00:00 2001 From: Valentin Oliver Date: Wed, 7 Feb 2018 22:37:24 +0000 Subject: [PATCH 2/2] lint errors fixed --- endpoints/aircraft/index.js | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/endpoints/aircraft/index.js b/endpoints/aircraft/index.js index d31c585a..5acafc1f 100644 --- a/endpoints/aircraft/index.js +++ b/endpoints/aircraft/index.js @@ -23,17 +23,16 @@ const lookupAircraft = searchStr => new Promise((resolve, reject) => { data.find('.vehicleinfo ul').each((index, element) => { const fields = [] $(element).find('li').each((i, el) => { - let val; + let val if (i < 7) { val = $(el).find('span').text() - - } else { + } else { // i === 7 contains info about aircraft owner // i === 8 contains info about aircraft operator // We'll parse these fields separately - const text = $(el).find('span').text(); - const info = text.split(/\s{3,}/g); + const text = $(el).find('span').text() + const info = text.split(/\s{3,}/g) val = { name: info[1], @@ -45,7 +44,7 @@ const lookupAircraft = searchStr => new Promise((resolve, reject) => { fields.push(val) }) - + if (fields.length > 0) { fieldList.push(fields) } @@ -55,12 +54,12 @@ const lookupAircraft = searchStr => new Promise((resolve, reject) => { resolve(fieldList.map((fields) => { return { id: fields[0], - registrationNumber: parseInt(fields[1]), + registrationNumber: parseInt(fields[1], 10), type: fields[2], - buildYear: parseInt(fields[3]), - serialNumber: parseInt(fields[4]), - maxWeight: parseInt(fields[5]), - passengers: parseInt(fields[6]), + buildYear: parseInt(fields[3], 10), + serialNumber: parseInt(fields[4], 10), + maxWeight: parseInt(fields[5], 10), + passengers: parseInt(fields[6], 10), owner: fields[7], operator: fields[8], }