New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

featureservice

Package Overview
Dependencies
Maintainers
3
Versions
43
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

featureservice - npm Package Compare versions

Comparing version 1.0.0 to 1.1.0

test/fixtures/count.json

16

CHANGELOG.md

@@ -5,2 +5,17 @@ # Change Log

## [1.1.0] - 2015-08-10
### Added
* New fixtures and integration tests for paging
* Support for paging layers from server version 10.0
* New fixtures and tests for decoding
### Changed
* Refactored paging strategy
* Moved feature request decoding into isolated function
### Fixed
* Catch errors that come on 200 responses
* Errors are reported correctly up the chain
* Retries for all errors
## [1.0.0] - 2015-08-07

@@ -55,2 +70,3 @@ ### Added

[1.1.0]: https://github.com/chelm/featureservice/ompare/v1.0.0...v1.1.0
[1.0.0]: https://github.com/chelm/featureservice/ompare/v0.2.0...v1.0.0

@@ -57,0 +73,0 @@ [0.2.0]: https://github.com/chelm/featureservice/ompare/v0.1.0...v0.2.0

317

index.js

@@ -24,4 +24,6 @@ var queue = require('async').queue

// protects us from urls registered with layers already in the url
var layer = url.split('/').pop()
if (parseInt(layer, 0) >= 0) {
var end = url.split('/').pop()
var layer
if (parseInt(end, 10) >= 0) {
layer = end
var len = ('' + layer).length

@@ -32,4 +34,4 @@ url = url.substring(0, url.length - ((len || 2) + 1))

this.url = url
this.options = options
this.layer = options.layer || 0
this.options = options || {}
this.layer = layer || this.options.layer || 0
this.timeOut = 1.5 * 60 * 1000

@@ -169,2 +171,5 @@ var concurrency = this.url.split('//')[1].match(/^service/) ? 16 : 4

this.request(this.url + '/' + this.layer + '/query?where=1=1&returnIdsOnly=true&f=json', function (err, json) {
if (err || !json.objectIds) return callback(new Error('Request for object ids failed' + err))
// TODO: is this really necessary
json.objectIds.sort(function (a, b) { return a - b })
callback(err, json.objectIds)

@@ -175,2 +180,28 @@ })

/**
* Gets and derives layer metadata from two sources
* @param {function} callback - called with an error or a metadata object
*/
FeatureService.prototype.metadata = function (callback) {
// TODO memoize this
this.layerInfo(function (err, layer) {
if (err) return callback(new Error(err || 'Unable to get layer metadata'))
var oid = this.getObjectIdField(layer)
var size = layer.maxRecordCount
// TODO flatten this
var metadata = {layer: layer, oid: oid, size: size}
// 10.0 servers don't support count requests
// they also do not show current version on the layer
if (!layer.currentVersion) return callback(null, metadata)
this.featureCount(function (err, json) {
if (err) return callback(err)
if (json.count < 1) return callback(new Error('Service returned count of 0'))
metadata.count = json.count
callback(null, metadata)
})
}.bind(this))
}
/**
* Build an array pages that will cover every feature in the service

@@ -180,90 +211,52 @@ * @param {object} callback - called when the service info comes back

FeatureService.prototype.pages = function (callback) {
this.featureCount(function (err, json) {
if (err) {
return callback(err)
}
this.metadata(function (err, meta) {
if (err) return callback(err)
var size = meta.size
var layer = meta.layer
this.options.objectIdField = meta.oid
size = Math.min(parseInt(size, 10), 1000) || 1000
var nPages = Math.ceil(meta.count / size)
var count = json.count
// if the service supports paging, we can use offset to build pages
var canPage = layer.advancedQueryCapabilities && layer.advancedQueryCapabilities.supportsPagination
if (canPage) return callback(null, this._offsetPages(nPages, size))
if (count === 0) {
return callback('Service returned a count of zero')
// if the service supports statistics, we can request the maximum and minimum id to build pages
if (layer.supportsStatistics) {
this._getIdRangeFromStats(meta, function (err, stats) {
// if this worked then we can pagination using where clauses
if (!err) return callback(null, this._rangePages(stats, size))
// if it failed, try to request all the ids and split them into pages
this.layerIds(function (err, ids) {
// either this works or we give up
if (err) return callback(err)
return callback(null, this._idPages(ids, size))
}.bind(this))
}.bind(this))
} else {
// this is the last thing we can try
this.layerIds(function (err, ids) {
if (err) return callback(err)
callback(null, this._idPages(ids, size))
}.bind(this))
}
}.bind(this))
}
// get layer info
this.layerInfo(function (err, serviceInfo) {
if (err || !serviceInfo) {
return callback(err || 'Unable to get layer metadata')
}
/**
* Get the max and min object id
* @param {object} meta - layer metadata, holds information needed to request oid stats
* @param {function} callback - returns with an error or objectID stats
*/
FeatureService.prototype._getIdRangeFromStats = function (meta, callback) {
this.options.objectIdField = this.getObjectIdField(serviceInfo)
// figure out what kind of pages we can build
var maxCount = Math.min(parseInt(serviceInfo.maxRecordCount, 0), 1000) || 1000
// build legit offset based page requests
if (serviceInfo.advancedQueryCapabilities &&
serviceInfo.advancedQueryCapabilities.supportsPagination) {
var nPages = Math.ceil(count / maxCount)
return callback(null, this._offsetPages(nPages, maxCount))
}
// build where clause based pages
if (serviceInfo.supportsStatistics) {
this.statistics(serviceInfo.objectIdField, ['min', 'max'], function (err, stats) {
if (err) {
return callback(err)
}
try {
if (stats.error) {
try {
var idUrl = this.url + '/' + (this.layer || 0) + '/query?where=1=1&returnIdsOnly=true&f=json'
this.request(idUrl, function (err, idJson) {
if (err) {
return callback(err)
}
var minID, maxID
if (idJson.error) {
// DMF: if grabbing objectIDs fails fall back to guessing based on 0 and count
minID = 0
maxID = count
} else {
idJson.objectIds.sort(function (a, b) { return a - b })
minID = idJson.objectIds[0]
maxID = idJson.objectIds[idJson.objectIds.length - 1]
}
return callback(null, this._objectIdPages(minID, maxID, maxCount))
}.bind(this))
} catch (e) {
return callback(e)
}
} else {
var names, minId, maxId
var attrs = stats.features[0].attributes
if (stats && stats.fieldAliases) {
names = Object.keys(stats.fieldAliases)
}
minId = attrs.min_oid || attrs.MIN_OID || attrs[names[0]]
maxId = attrs.max_oid || attrs.MAX_OID || attrs[names[1]]
return callback(null, this._objectIdPages(minId, maxId, maxCount))
}
} catch (e) {
return callback(e)
}
}.bind(this))
} else {
if (count < 1000000) {
this.layerIds(function (err, ids) {
callback(err, this._idPages(ids, 250))
}.bind(this))
} else {
// default to sequential objectID paging starting from zero
return callback(null, this._objectIdPages(0, count, maxCount))
}
}
}.bind(this))
}.bind(this))
this.statistics(meta.oid, ['min', 'max'], function (reqErr, stats) {
if (reqErr || stats.error) return callback(new Error('statistics request failed'))
var attrs = stats.features[0].attributes
// dmf: what's up with this third strategy?
var names = stats && stats.fieldAliases ? Object.keys(stats.fieldAliases) : null
var min = attrs.min || attrs.MIN || attrs[names[0]]
var max = attrs.max || attrs.MAX || attrs[names[1]]
callback(null, {min: min, max: max})
})
}

@@ -276,13 +269,9 @@

FeatureService.prototype.featureCount = function (callback) {
var countUrl = this.url + '/' + (this.options.layer || 0)
countUrl += '/query?where=1=1&returnIdsOnly=true&returnCountOnly=true&f=json'
var countUrl = this.url + '/' + (this.layer || 0)
countUrl += '/query?where=1=1&returnCountOnly=true&f=json'
this.request(countUrl, function (err, json) {
if (err) {
return callback(err)
}
if (err) return callback(err)
if (json.error) {
return callback(json.error.message + ': ' + countUrl, null)
}
if (json.error) return callback(json.error.message + ': ' + countUrl, null)

@@ -322,15 +311,15 @@ callback(null, json)

*/
FeatureService.prototype._idPages = function (ids, maxCount) {
FeatureService.prototype._idPages = function (ids, size) {
var reqs = []
var where
var pageUrl
var oidField = this.options.objectIdField || 'objectId'
var pages = (ids.length / size)
var objId = this.options.objectIdField || 'objectId'
var pages = (ids.length / maxCount)
for (var i = 0; i < pages + 1; i++) {
var pageIds = ids.splice(0, maxCount)
var pageIds = ids.splice(0, size)
if (pageIds.length) {
where = objId + ' in (' + pageIds.join(',') + ')'
pageUrl = this.url + '/' + (this.options.layer || 0) + '/query?outSR=4326&where=' + where + '&f=json&outFields=*'
var pageMin = pageIds[0]
pageMin = pageMin === 0 ? pageMin : pageMin - 1
var pageMax = pageIds.pop()
var where = [oidField, ' > ', pageMin, ' AND ', 'oidField', '<=', pageMax].join('')
var pageUrl = this.url + '/' + (this.options.layer || 0) + '/query?outSR=4326&where=' + where + '&f=json&outFields=*'
pageUrl += '&geometry=&returnGeometry=true&geometryPrecision=10'

@@ -352,3 +341,3 @@ reqs.push({req: pageUrl})

*/
FeatureService.prototype._objectIdPages = function (min, max, maxRecordCount) {
FeatureService.prototype._rangePages = function (stats, size) {
var reqs = []

@@ -362,3 +351,3 @@ var pageUrl

var url = this.url
var pages = Math.max((max === maxRecordCount) ? max : Math.ceil((max - min) / maxRecordCount), 1)
var pages = Math.max((stats.max === size) ? stats.max : Math.ceil((stats.max - stats.min) / size), 1)

@@ -369,7 +358,7 @@ for (var i = 0; i < pages; i++) {

if (i === pages - 1) {
pageMax = max
pageMax = stats.max
} else {
pageMax = min + (maxRecordCount * (i + 1)) - 1
pageMax = stats.min + (size * (i + 1)) - 1
}
pageMin = min + (maxRecordCount * i)
pageMin = stats.min + (size * i)
where = objId + '<=' + pageMax + '+AND+' + objId + '>=' + pageMin

@@ -420,3 +409,3 @@ pageUrl = url + '/' + (this.options.layer || 0) + '/query?outSR=4326&where=' + where + '&f=json&outFields=*'

// make an http or https request based on the protocol
// make an http or https request based on the protocol
var req = ((url_parts.protocol === 'https:') ? https : http).request(opts, function (response) {

@@ -429,35 +418,11 @@ var data = []

response.on('error', function (err) {
catchErrors(task, err, uri, cb)
self._catchErrors(task, err, uri, cb)
})
response.on('end', function () {
try {
var json
var buffer = Buffer.concat(data)
var encoding = response.headers['content-encoding']
// TODO all this shit is ugly -- make it less shitty (less try/catch)
if (encoding === 'gzip') {
zlib.gunzip(buffer, function (e, result) {
try {
json = JSON.parse(result.toString().replace(/NaN/g, 'null'))
cb(null, json)
} catch (e) {
catchErrors(task, e, uri, cb)
}
})
} else if (encoding === 'deflate') {
try {
json = JSON.parse(zlib.inflateSync(buffer).toString())
cb(null, json)
} catch (e) {
catchErrors(task, e, uri, cb)
}
} else {
json = JSON.parse(buffer.toString().replace(/NaN/g, 'null'))
cb(null, json)
}
} catch(e) {
catchErrors(task, e, uri, cb)
}
// TODO: move this into a function call decode
self._decode(response, data, function (err, json) {
if (err) return self._catchErrors(task, err, uri, cb)
cb(null, json)
})
})

@@ -470,3 +435,3 @@ })

var err = JSON.stringify({message: 'The request timed out after ' + self.timeOut / 1000 + ' seconds.'})
catchErrors(task, err, uri, cb)
self._catchErrors(task, err, uri, cb)
})

@@ -476,3 +441,3 @@

req.on('error', function (err) {
catchErrors(task, err, uri, cb)
self._catchErrors(task, err, uri, cb)
})

@@ -482,32 +447,58 @@

} catch(e) {
catchErrors(task, e, uri, cb)
self._catchErrors(task, e, uri, cb)
}
}
// Catch any errors and either retry the request or fail it
var catchErrors = function (task, e, url, cb) {
if (task.retry && task.retry === 3) {
try {
var jsonErr = JSON.parse(e)
this._abortPaging('Failed to request a page of features', url, jsonErr.message, jsonErr.code, cb)
} catch (parseErr) {
this._abortPaging('Failed to request a page of features', url, parseErr, null, cb)
}
return
}
// immediately kill
if (!task.retry) {
task.retry = 1
/* Decodes a response for features
* @param {object} res - the response received from the GIS Server
* @param {array} data - an array of chunks received from the server
* @param {function} callback - calls back with either an error or the decoded feature json
*/
FeatureService.prototype._decode = function (res, data, callback) {
var json
var encoding = res.headers['content-encoding']
if (!data.length > 0) return callback(new Error('Empty reply from the server'))
try {
var buffer = Buffer.concat(data)
if (encoding === 'gzip') {
json = JSON.parse(zlib.gunzipSync(buffer).toString().replace(/NaN/g, 'null'))
} else if (encoding === 'deflate') {
json = JSON.parse(zlib.inflateSync(buffer).toString())
} else {
task.retry++
json = JSON.parse(buffer.toString().replace(/NaN/g, 'null'))
}
} catch (e) {
callback(e)
}
// ArcGIS Server responds 200 on errors so we have to inspect the payload
if (json.error) return callback(json.error)
// everything has worked so callback with the decoded JSON
callback(null, json)
}
console.log('Re-requesting page', task.req, task.retry)
/* Catches an errors during paging and handles retry logic
* @param {object} task - the currently executing job
* @param {object} e - the error in application logic or from a failed request to a server
* @param {string} url - the url of the last request for pages
* @param {function} cb - callback passed through to the abort paging function
*/
FeatureService.prototype._catchErrors = function (task, e, url, cb) {
if (!e.message) e.message = e.toString()
if (task.retry && task.retry === 3) return this._abortPaging('Failed to request a page of features', url, e.message, e.code, cb)
setTimeout(function () {
this._requestFeatures(task, cb)
}.bind(this), task.retry * 1000)
// initiate the count or increment it
if (!task.retry) {
task.retry = 1
} else {
task.retry++
}
}.bind(this)
console.log('Re-requesting page', task.req, task.retry)
setTimeout(function () {
this._requestFeatures(task, cb)
}.bind(this), task.retry * 1000)
}
module.exports = FeatureService
{
"name": "featureservice",
"description": "Get all features from an Esri Feature Service",
"version": "1.0.0",
"version": "1.1.0",
"author": "Chris Helm",

@@ -6,0 +6,0 @@ "bugs": {

@@ -6,2 +6,3 @@ var sinon = require('sinon')

var fs = require('fs')
var zlib = require('zlib')

@@ -11,2 +12,5 @@ var service = new FeatureService('http://koop.dc.esri.com/socrata/seattle/2tje-83f6/FeatureServer/0', {})

var layerInfo = JSON.parse(fs.readFileSync('./test/fixtures/layerInfo.json'))
var layerFixture = JSON.parse(fs.readFileSync('./test/fixtures/layer.json'))
var idFixture = JSON.parse(fs.readFileSync('./test/fixtures/objectIds.json'))
var countFixture = JSON.parse(fs.readFileSync('./test/fixtures/count.json'))

@@ -22,7 +26,6 @@ test('get the objectId', function (t) {

var pages
var min = 0
var max = 2000
pages = service._objectIdPages(min, max, max / 2)
var stats = {min: 0, max: 2000}
pages = service._rangePages(stats, stats.max / 2)
t.equal(pages.length, 2)
pages = service._objectIdPages(min, max, max / 4)
pages = service._rangePages(stats, stats.max / 4)
t.equal(pages.length, 4)

@@ -55,23 +58,10 @@ t.end()

test('builds pages for the service', function (t) {
var url = 'http://maps.indiana.edu/ArcGIS/rest/services/Infrastructure/Railroads_Rail_Crossings_INDOT/MapServer'
var indiana = new FeatureService(url, {})
indiana.pages(function (err, pages) {
t.equal(err, null)
t.equal(pages.length, 156)
t.end()
})
})
test('stub setup', function (t) {
test('get the metadata for a layer on the service', function (t) {
sinon.stub(service, 'request', function (url, callback) {
callback(null, {body: '{}'})
callback(null, layerFixture)
})
t.end()
})
test('get the metadata for a layer on the service', function (t) {
service.layerInfo(function (err, metadata) {
t.equal(err, null)
t.equal(service.request.calledWith('http://koop.dc.esri.com/socrata/seattle/2tje-83f6/FeatureServer/0?f=json'), true)
service.request.restore()
t.end()

@@ -82,2 +72,5 @@ })

test('get all the object ids for a layer on the service', function (t) {
sinon.stub(service, 'request', function (url, callback) {
callback(null, idFixture)
})
service.layerIds(function (err, metadata) {

@@ -87,2 +80,3 @@ t.equal(err, null)

t.equal(service.request.calledWith(expected), true)
service.request.restore()
t.end()

@@ -93,6 +87,10 @@ })

test('get all feature count for a layer on the service', function (t) {
sinon.stub(service, 'request', function (url, callback) {
callback(null, countFixture)
})
service.featureCount(function (err, metadata) {
t.equal(err, null)
var expected = 'http://koop.dc.esri.com/socrata/seattle/2tje-83f6/FeatureServer/0/query?where=1=1&returnIdsOnly=true&returnCountOnly=true&f=json'
var expected = 'http://koop.dc.esri.com/socrata/seattle/2tje-83f6/FeatureServer/0/query?where=1=1&returnCountOnly=true&f=json'
t.equal(service.request.calledWith(expected), true)
service.request.restore()
t.end()

@@ -116,5 +114,208 @@ })

test('teardown', function (t) {
service.request.restore()
t.end()
test('decoding something that is gzipped', function (t) {
var json = JSON.stringify(JSON.parse(fs.readFileSync('./test/fixtures/uncompressed.json')))
var gzipped = zlib.gzipSync(json)
var data = [gzipped]
var res = {headers: {'content-encoding': 'gzip'}}
var service = new FeatureService('http://service.com/mapserver/2')
service._decode(res, data, function (err, json) {
t.equal(json.features.length, 2000)
t.end()
})
})
test('decoding something that is deflated', function (t) {
var json = JSON.stringify(JSON.parse((fs.readFileSync('./test/fixtures/uncompressed.json'))))
var deflated = zlib.deflateSync(json)
var data = [deflated]
var res = {headers: {'content-encoding': 'deflate'}}
var service = new FeatureService('http://service.com/mapserver/2')
service._decode(res, data, function (err, json) {
t.equal(json.features.length, 2000)
t.end()
})
})
test('decoding something that is not compressed', function (t) {
var uncompressed = JSON.stringify(JSON.parse(fs.readFileSync('./test/fixtures/uncompressed.json')))
var data = [new Buffer(uncompressed)]
var res = {headers: {}}
var service = new FeatureService('http://service.com/mapserver/2')
service._decode(res, data, function (err, json) {
t.equal(json.features.length, 2000)
t.end()
})
})
test('decoding an empty response', function (t) {
var empty = []
var res = {headers: {'content-encoding': 'gzip'}}
var service = new FeatureService('http://service.com/mapserver/2')
service._decode(res, empty, function (err, json) {
t.notEqual(typeof err, 'undefined')
t.end()
})
})
test('should callback with an error when decoding json with an error in the response', function (t) {
var data = {
error: {
code: 400,
message: 'Invalid or missing input parameters.',
details: []
}
}
var res = {headers: {}}
var service = new FeatureService('http://service.com/mapserver/2')
service._decode(res, [new Buffer(JSON.stringify(data))], function (err, json) {
t.notEqual(typeof err, 'undefined')
t.equal(err.code, 400)
t.equal(err.message, 'Invalid or missing input parameters.')
t.end()
})
})
test('catching errors with a json payload', function (t) {
var service = new FeatureService('http://service.com/mapserver/2')
var task = {retry: 3}
var error = {
code: 400,
message: 'Invalid or missing input parameters.',
details: []
}
var url = 'http://url.com'
sinon.stub(service, '_abortPaging', function (msg, url, eMsg, eCode, cb) {
var info = {
message: msg,
request: url,
response: eMsg,
code: eCode
}
cb(info)
})
service._catchErrors(task, error, url, function (info) {
t.equal(info.message, 'Failed to request a page of features')
t.equal(info.code, error.code)
t.equal(info.request, url)
t.equal(info.response, error.message)
service._abortPaging.restore()
t.end()
})
})
// feature request integration tests
test('requesting a page of features', function (t) {
var page = fs.readFileSync('./test/fixtures/page.json')
var fixture = nock('http://servicesqa.arcgis.com')
fixture.get('/97KLIFOSt5CxbiRI/arcgis/rest/services/QA_data_simple_point_5000/FeatureServer/0/query?outSR=4326&f=json&outFields=*&where=1=1&resultOffset=1000&resultRecordCount=1000&geometry=&returnGeometry=true&geometryPrecision=')
.reply(200, page)
var service = new FeatureService('http://servicesqa.arcgis.com/97KLIFOSt5CxbiRI/arcgis/rest/services/QA_data_simple_point_5000/FeatureServer/0')
var task = {req: 'http://servicesqa.arcgis.com/97KLIFOSt5CxbiRI/arcgis/rest/services/QA_data_simple_point_5000/FeatureServer/0/query?outSR=4326&f=json&outFields=*&where=1=1&resultOffset=1000&resultRecordCount=1000&geometry=&returnGeometry=true&geometryPrecision='}
service._requestFeatures(task, function (err, json) {
t.equal(json.features.length, 1000)
t.end()
})
})
// paging integration tests
test('building pages for a service that supports pagination', function (t) {
var countPaging = JSON.parse(fs.readFileSync('./test/fixtures/countPaging.json'))
var layerPaging = JSON.parse(fs.readFileSync('./test/fixtures/layerPaging.json'))
var fixture = nock('http://maps.indiana.edu')
fixture.get('/ArcGIS/rest/services/Infrastructure/Railroads_Rail_Crossings_INDOT/MapServer/0/query?where=1=1&returnCountOnly=true&f=json')
.reply(200, countPaging)
fixture.get('/ArcGIS/rest/services/Infrastructure/Railroads_Rail_Crossings_INDOT/MapServer/0?f=json')
.reply(200, layerPaging)
var service = new FeatureService('http://maps.indiana.edu/ArcGIS/rest/services/Infrastructure/Railroads_Rail_Crossings_INDOT/MapServer/0', {})
service.pages(function (err, pages) {
t.equal(err, null)
t.equal(pages.length, 156)
t.end()
})
})
test('building pages from a layer that does not support pagination', function (t) {
var layerNoPaging = JSON.parse(fs.readFileSync('./test/fixtures/layerNoPaging.json'))
var countNoPaging = JSON.parse(fs.readFileSync('./test/fixtures/countNoPaging.json'))
var statsNoPaging = JSON.parse(fs.readFileSync('./test/fixtures/statsNoPaging.json'))
var fixture = nock('http://maps2.dcgis.dc.gov')
fixture.get('/dcgis/rest/services/DCGIS_DATA/Transportation_WebMercator/MapServer/50/query?where=1=1&returnCountOnly=true&f=json')
.reply(200, countNoPaging)
fixture.get('/dcgis/rest/services/DCGIS_DATA/Transportation_WebMercator/MapServer/50?f=json')
.reply(200, layerNoPaging)
fixture.get('/dcgis/rest/services/DCGIS_DATA/Transportation_WebMercator/MapServer/50/query?f=json&outFields=&outStatistics=%5B%7B%22statisticType%22:%22min%22,%22onStatisticField%22:%22OBJECTID_1%22,%22outStatisticFieldName%22:%22min_OBJECTID_1%22%7D,%7B%22statisticType%22:%22max%22,%22onStatisticField%22:%22OBJECTID_1%22,%22outStatisticFieldName%22:%22max_OBJECTID_1%22%7D%5D')
.reply(200, statsNoPaging)
var service = new FeatureService('http://maps2.dcgis.dc.gov/dcgis/rest/services/DCGIS_DATA/Transportation_WebMercator/MapServer/50')
service.pages(function (err, pages) {
t.equal(err, null)
t.equal(pages.length, 1)
t.end()
})
})
test('building pages from a layer where statistics fail', function (t) {
var layerStatsFail = JSON.parse(fs.readFileSync('./test/fixtures/layerStatsFail.json'))
var countStatsFail = JSON.parse(fs.readFileSync('./test/fixtures/countStatsFail.json'))
var idsStatsFail = JSON.parse(fs.readFileSync('./test/fixtures/idsStatsFail.json'))
var statsFail = JSON.parse(fs.readFileSync('./test/fixtures/statsFail.json'))
var fixture = nock('http://maps2.dcgis.dc.gov')
fixture.get('/dcgis/rest/services/FEEDS/CDW_Feeds/MapServer/8/query?where=1=1&returnIdsOnly=true&f=json')
.reply(200, idsStatsFail)
fixture.get('/dcgis/rest/services/FEEDS/CDW_Feeds/MapServer/8/query?where=1=1&returnCountOnly=true&f=json')
.reply(200, countStatsFail)
fixture.get('/dcgis/rest/services/FEEDS/CDW_Feeds/MapServer/8?f=json')
.reply(200, layerStatsFail)
fixture.get('/dcgis/rest/services/FEEDS/CDW_Feeds/MapServer/8/query?f=json&outFields=&outStatistics=%5B%7B%22statisticType%22:%22min%22,%22onStatisticField%22:%22ESRI_OID%22,%22outStatisticFieldName%22:%22min_ESRI_OID%22%7D,%7B%22statisticType%22:%22max%22,%22onStatisticField%22:%22ESRI_OID%22,%22outStatisticFieldName%22:%22max_ESRI_OID%22%7D%5D')
.reply(200, statsFail)
var service = new FeatureService('http://maps2.dcgis.dc.gov/dcgis/rest/services/FEEDS/CDW_Feeds/MapServer/8')
service.pages(function (err, pages) {
t.equal(err, null)
t.equal(pages.length, 4)
t.end()
})
})
test('building pages for a version 10.0 server', function (t) {
var layer10 = JSON.parse(fs.readFileSync('./test/fixtures/layer10.0.json'))
var ids10 = JSON.parse(fs.readFileSync('./test/fixtures/ids10.0.json'))
var fixture = nock('http://sampleserver3.arcgisonline.com')
fixture.get('/ArcGIS/rest/services/Fire/Sheep/FeatureServer/2?f=json').reply(200, layer10)
fixture.get('/ArcGIS/rest/services/Fire/Sheep/FeatureServer/2/query?where=1=1&returnIdsOnly=true&f=json').reply(200, ids10)
var service = new FeatureService('http://sampleserver3.arcgisonline.com/ArcGIS/rest/services/Fire/Sheep/FeatureServer/2')
service.pages(function (err, pages) {
t.equal(err, null)
t.equal(pages.length, 1)
t.end()
})
})
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc