Skip to content

Commit e6ce728

Browse files
authored
Merge pull request #2 from conveyal/unfound-bulk
Gracefully handle unfound bulk result
2 parents 90cfdad + b00a611 commit e6ce728

File tree

4 files changed

+97
-28
lines changed

4 files changed

+97
-28
lines changed

__tests__/__snapshots__/index.js.snap

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -96,8 +96,6 @@ Object {
9696
}
9797
`;
9898

99-
exports[`basic bulk request uri 1`] = `"/arcgis/rest/services/World/GeocodeServer/geocodeAddresses"`;
100-
10199
exports[`basic reverse g-a-g response 1`] = `
102100
Object {
103101
"features": Array [
@@ -251,3 +249,37 @@ Object {
251249
`;
252250

253251
exports[`basic search request uri 1`] = `"/arcgis/rest/services/World/GeocodeServer/findAddressCandidates?outFields=*&maxLocations=10&SingleLine=123%20main%20st&f=json"`;
252+
253+
exports[`bulk g-a-g response with no address found 1`] = `
254+
Object {
255+
"features": Array [
256+
Object {
257+
"geometry": Object {
258+
"coordinates": Array [
259+
0,
260+
0,
261+
],
262+
"type": "point",
263+
},
264+
"properties": Object {
265+
"confidence": 0,
266+
"country": "",
267+
"country_a": "",
268+
"county": "",
269+
"label": "Address not found",
270+
"locality": "",
271+
"name": "",
272+
"neighbourhood": "",
273+
"region": "",
274+
"resultId": 0,
275+
},
276+
"type": "feature",
277+
},
278+
],
279+
"query": Object {
280+
"addresses": Array [
281+
"aefgjil",
282+
],
283+
},
284+
}
285+
`;

__tests__/index.js

Lines changed: 40 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -5,19 +5,36 @@ import nock from 'nock'
55
import {autocomplete, bulk, reverse, search} from '../index'
66

77
const mockBulkResult = require('./mock-bulk-result.json')
8+
const mockBulkResultWithBadAddress = require('./mock-bulk-result-with-bad-address.json')
89
const mockReverseResult = require('./mock-reverse-result.json')
910
const mockSearchResult = require('./mock-search-result.json')
1011
const mockSuggestResult = require('./mock-suggest-result.json')
1112

13+
const ARCGIS_GEOCODE_URL = 'https://geocode.arcgis.com/'
14+
const BULK_URL = /arcgis\/rest\/services\/World\/GeocodeServer\/geocodeAddresses/
15+
const REVERSE_URL = /arcgis\/rest\/services\/World\/GeocodeServer\/reverseGeocode/
16+
const SEARCH_URL = /arcgis\/rest\/services\/World\/GeocodeServer\/findAddressCandidates/
17+
const SUGGEST_URL = /arcgis\/rest\/services\/World\/GeocodeServer\/suggest/
18+
19+
function nockArcGet (url: RegExp) {
20+
return nock(ARCGIS_GEOCODE_URL).get(url)
21+
}
22+
23+
function nockArcPost (url: RegExp) {
24+
return nock(ARCGIS_GEOCODE_URL).post(url)
25+
}
26+
27+
function snapshotUri (type: string, response: Object) {
28+
return (uri, requestBody) => {
29+
expect(uri).toMatchSnapshot(`basic ${type} request uri`)
30+
return response
31+
}
32+
}
33+
1234
describe('geocoder-arcgis-geojson', () => {
1335
describe('autocomplete', () => {
1436
it('should make basic autocomplete query', async () => {
15-
nock('https://geocode.arcgis.com/')
16-
.get(/arcgis\/rest\/services\/World\/GeocodeServer\/suggest/)
17-
.reply(200, (uri, requestBody) => {
18-
expect(uri).toMatchSnapshot('basic autocomplete request uri')
19-
return mockSuggestResult
20-
})
37+
nockArcGet(SUGGEST_URL).reply(200, snapshotUri('autocomplete', mockSuggestResult))
2138

2239
const result = await autocomplete({
2340
text: '123 main st'
@@ -27,19 +44,15 @@ describe('geocoder-arcgis-geojson', () => {
2744
})
2845

2946
describe('bulk', () => {
30-
it('should make basic bulk query', async () => {
47+
beforeEach(() => {
3148
// nock for auth token
3249
nock('https://www.arcgis.com/')
3350
.post(/sharing\/oauth2\/token/)
3451
.reply(200, { access_token: 'test', expires_in: 86400 })
52+
})
3553

36-
// nock for bulk geocode reqeust
37-
nock('https://geocode.arcgis.com/')
38-
.post(/arcgis\/rest\/services\/World\/GeocodeServer\/geocodeAddresses/)
39-
.reply(200, (uri, requestBody) => {
40-
expect(uri).toMatchSnapshot('basic bulk request uri')
41-
return mockBulkResult
42-
})
54+
it('should make basic bulk query', async () => {
55+
nockArcPost(BULK_URL).reply(200, mockBulkResult)
4356

4457
const result = await bulk({
4558
addresses: ['123 main st'],
@@ -48,16 +61,22 @@ describe('geocoder-arcgis-geojson', () => {
4861
})
4962
expect(result).toMatchSnapshot('basic bulk g-a-g response')
5063
})
64+
65+
it('should handle bulk query resulting in no address found', async () => {
66+
nockArcPost(BULK_URL).reply(200, mockBulkResultWithBadAddress)
67+
68+
const result = await bulk({
69+
addresses: ['aefgjil'],
70+
clientId: 'test',
71+
clientSecret: 'test'
72+
})
73+
expect(result).toMatchSnapshot('bulk g-a-g response with no address found')
74+
})
5175
})
5276

5377
describe('reverse', () => {
5478
it('should make basic reverse query', async () => {
55-
nock('https://geocode.arcgis.com/')
56-
.get(/arcgis\/rest\/services\/World\/GeocodeServer\/reverseGeocode/)
57-
.reply(200, (uri, requestBody) => {
58-
expect(uri).toMatchSnapshot('basic reverse request uri')
59-
return mockReverseResult
60-
})
79+
nockArcGet(REVERSE_URL).reply(200, snapshotUri('reverse', mockReverseResult))
6180

6281
const result = await reverse({
6382
point: {
@@ -71,12 +90,7 @@ describe('geocoder-arcgis-geojson', () => {
7190

7291
describe('search', () => {
7392
it('should make basic search query', async () => {
74-
nock('https://geocode.arcgis.com/')
75-
.get(/arcgis\/rest\/services\/World\/GeocodeServer\/findAddressCandidates/)
76-
.reply(200, (uri, requestBody) => {
77-
expect(uri).toMatchSnapshot('basic search request uri')
78-
return mockSearchResult
79-
})
93+
nockArcGet(SEARCH_URL).reply(200, snapshotUri('search', mockSearchResult))
8094

8195
const result = await search({
8296
text: '123 main st'
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{"spatialReference":{"wkid":4326,"latestWkid":4326},"locations":[{"address":"","score":0,"attributes":{"ResultID":0,"Loc_name":"","Status":"U","Score":0,"Match_addr":"","LongLabel":"","ShortLabel":"","Addr_type":"","Type":"","PlaceName":"","Place_addr":"","Phone":"","URL":"","Rank":0,"AddBldg":"","AddNum":"","AddNumFrom":"","AddNumTo":"","AddRange":"","Side":"","StPreDir":"","StPreType":"","StName":"","StType":"","StDir":"","BldgType":"","BldgName":"","LevelType":"","LevelName":"","UnitType":"","UnitName":"","SubAddr":"","StAddr":"","Block":"","Sector":"","Nbrhd":"","District":"","City":"","MetroArea":"","Subregion":"","Region":"","RegionAbbr":"","Territory":"","Zone":"","Postal":"","PostalExt":"","Country":"","LangCode":"","Distance":0,"X":0,"Y":0,"DisplayX":0,"DisplayY":0,"Xmin":0,"Xmax":0,"Ymin":0,"Ymax":0,"ExInfo":""}}]}

index.js

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,28 @@ function getGeocoder (clientId: ?string, clientSecret: ?string, endpoint: ?strin
5555
* Translate arcgis candidate json to geojson
5656
*/
5757
function candidateToGeojson (candidate) {
58+
if (!candidate.location) {
59+
// no result found for this candidate
60+
return {
61+
geometry: {
62+
coordinates: [0, 0],
63+
type: 'point'
64+
},
65+
properties: {
66+
confidence: 0,
67+
country: '',
68+
country_a: '',
69+
county: '',
70+
label: 'Address not found',
71+
locality: '',
72+
name: '',
73+
neighbourhood: '',
74+
region: '',
75+
resultId: candidate.attributes.ResultID // this only appears in bulk geocode results
76+
},
77+
type: 'feature'
78+
}
79+
}
5880
return {
5981
geometry: {
6082
coordinates: lonlat.toCoordinates(candidate.location),

0 commit comments

Comments
 (0)