Enforce callback error handling

This commit is contained in:
Daniel García Aubert
2019-10-24 18:38:37 +02:00
parent d5406d5b50
commit d5218a86f6
26 changed files with 89 additions and 2 deletions
+2
View File
@@ -53,6 +53,7 @@ AnalysisBackend.prototype.create = function (analysisConfiguration, analysisDefi
};
this.getAnalysesLimits(analysisConfiguration.user, function (err, limits) {
if (err) {}
analysisConfiguration.limits = limits || {};
camshaft.create(analysisConfiguration, analysisDefinition, callback);
});
@@ -76,6 +77,7 @@ AnalysisBackend.prototype.getAnalysesLimits = function (username, callback) {
var analysesLimitsKey = REDIS_LIMITS.PREFIX + username;
this.metadataBackend.redisCmd(REDIS_LIMITS.DB, 'HGETALL', [analysesLimitsKey], function (err, analysesTimeouts) {
if (err) {}
// analysesTimeouts wil be something like: { moran: 3000, intersection: 5000 }
analysesTimeouts = analysesTimeouts || {};
@@ -142,6 +142,7 @@ describe('analysis-filters-params', () => {
});
testClient.getDataview('pop_max_histogram', testParams, (err, dataview) => {
assert.ifError(err);
assert.deepStrictEqual(dataview, expectedError);
testClient.drain(done);
+7 -1
View File
@@ -220,12 +220,13 @@ describe('get requests with cache headers', function () {
it('/api/v1/map Map instantiation', function (done) {
var testFn = validateCacheHeaders(done, expectedCacheHeaders);
withLayergroupId(mapConfig, function (err, layergroupId, res) {
testFn(res);
testFn(res, err);
});
});
it('/api/v1/map/:token/:z/:x/:y@:scale_factor?x.:format Mapnik retina tiles', function (done) {
withLayergroupId(mapConfig, function (err, layergroupId) {
assert.ifError(err);
assert.response(
server,
getRequest('/api/v1/map/' + layergroupId + '/0/0/0@2x.png', true),
@@ -236,6 +237,7 @@ describe('get requests with cache headers', function () {
it('/api/v1/map/:token/:z/:x/:y@:scale_factor?x.:format Mapnik tiles', function (done) {
withLayergroupId(mapConfig, function (err, layergroupId) {
assert.ifError(err);
assert.response(
server,
getRequest('/api/v1/map/' + layergroupId + '/0/0/0.png', true),
@@ -246,6 +248,7 @@ describe('get requests with cache headers', function () {
it('/api/v1/map/:token/:layer/:z/:x/:y.(:format) Per :layer rendering', function (done) {
withLayergroupId(mapConfig, function (err, layergroupId) {
assert.ifError(err);
assert.response(
server,
getRequest('/api/v1/map/' + layergroupId + '/0/0/0/0.png', true),
@@ -256,6 +259,7 @@ describe('get requests with cache headers', function () {
it('/api/v1/map/:token/:layer/attributes/:fid endpoint for info windows', function (done) {
withLayergroupId(mapConfig, function (err, layergroupId) {
assert.ifError(err);
assert.response(
server,
getRequest('/api/v1/map/' + layergroupId + '/0/attributes/1', true),
@@ -266,6 +270,7 @@ describe('get requests with cache headers', function () {
it('/api/v1/map/static/center/:token/:z/:lat/:lng/:width/:height.:format static maps', function (done) {
withLayergroupId(mapConfig, function (err, layergroupId) {
assert.ifError(err);
assert.response(
server,
getRequest('/api/v1/map/static/center/' + layergroupId + '/0/0/0/400/300.png', true),
@@ -276,6 +281,7 @@ describe('get requests with cache headers', function () {
it('/api/v1/map/static/bbox/:token/:bbox/:width/:height.:format static maps', function (done) {
withLayergroupId(mapConfig, function (err, layergroupId) {
assert.ifError(err);
assert.response(
server,
getRequest('/api/v1/map/static/bbox/' + layergroupId + '/-45,-45,45,45/400/300.png', true),
+6 -1
View File
@@ -1,6 +1,5 @@
'use strict';
/* eslint-env mocha */
const assert = require('assert');
const TestClient = require('../support/test-client');
const mapConfigFactory = require('../fixtures/test_mapconfigFactory');
@@ -23,6 +22,7 @@ describe_mvt('date-wrapping', () => {
it('should return date columns casted as numbers', done => {
testClient.getTile(0, 0, 0, { format: 'mvt' }, (err, res, mvt) => {
assert.ifError(err);
const expected = [
{
type: 'Feature',
@@ -63,6 +63,7 @@ describe_mvt('date-wrapping', () => {
it('should return date columns as dates', done => {
testClient.getTile(0, 0, 0, { format: 'mvt' }, (err, res, mvt) => {
assert.ifError(err);
const expected = [
{
type: 'Feature',
@@ -109,6 +110,7 @@ describe_mvt('date-wrapping', () => {
});
testClient.getTile(0, 0, 0, { format: 'mvt' }, (err, res, mvt) => {
assert.ifError(err);
const expected0 = [
{
type: 'Feature',
@@ -167,6 +169,7 @@ describe_mvt('date-wrapping', () => {
});
testClient.getTile(0, 0, 0, { format: 'mvt' }, (err, res, mvt) => {
assert.ifError(err);
const expected0 = [
{
type: 'Feature',
@@ -225,6 +228,7 @@ describe_mvt('date-wrapping', () => {
});
testClient.getTile(0, 0, 0, { format: 'mvt' }, (err, res, mvt) => {
assert.ifError(err);
const expected0 = [
{
type: 'Feature',
@@ -289,6 +293,7 @@ describe_mvt('date-wrapping', () => {
it('should return correct tiles', done => {
testClient.getTile(0, 0, 0, { format: 'mvt' }, (err, res, mvt) => {
assert.ifError(err);
const expected = [
{
type: 'Feature',
+1
View File
@@ -63,6 +63,7 @@ describe('CartoCSS wrap', function () {
it('Label should be text-wrapped', function (done) {
this.testClient = new TestClient(mapConfig);
this.testClient.getTile(1, 0, 1, { layers: [0] }, (err, res, body) => {
assert.ifError(err);
var textWrapPath = './test/fixtures/text_wrap.png';
assert.imageIsSimilarToFile(body, textWrapPath, IMAGE_TOLERANCE, done);
});
+1
View File
@@ -231,6 +231,7 @@ var QueryTables = require('cartodb-query-tables').queryTables;
}, {}, function (res, err) { next(err, res); });
},
function do_check_create (err, res) {
assert.ifError(err);
var parsed = JSON.parse(res.body);
keysToDelete['map_cfg|' + LayergroupToken.parse(parsed.layergroupid).token] = 0;
keysToDelete['user:localhost:mapviews:global'] = 5;
@@ -18,6 +18,10 @@ describe('blend layer filtering', function () {
httpRendererResourcesServer = http.createServer(function (request, response) {
var filename = path.join(__dirname, '/../../fixtures/http/light_nolabels-1-0-0.png');
fs.readFile(filename, { encoding: 'binary' }, function (err, file) {
if (err) {
return done(err);
}
response.writeHead(200);
response.write(file, 'binary');
response.end();
@@ -150,6 +154,7 @@ describe('blend layer filtering', function () {
it('should filter on ' + layerFilter + '/1/0/0.png', function (done) {
testClient.getTileLayer(mapConfig, tileRequest, function (err, res) {
assert.ifError(err);
assert.imageBufferIsSimilarToFile(res.body, blendPngFixture(filteredLayers), IMG_TOLERANCE_PER_MIL,
function (err) {
assert.ok(!err);
@@ -25,6 +25,9 @@ describe('blend http fallback', function () {
filename = path.join(__dirname, '/../../fixtures/http/dark_nolabels-1-0-0.png');
}
fs.readFile(filename, { encoding: 'binary' }, function (err, file) {
if (err) {
return done(err);
}
response.writeHead(200);
response.write(file, 'binary');
response.end();
@@ -106,6 +109,7 @@ describe('blend http fallback', function () {
it('should fallback on http error while blending layers ' + layerFilter + '/1/0/0.png', function (done) {
testClient.getTileLayer(mapConfig, tileRequest, function (err, res) {
assert.ifError(err);
assert.imageBufferIsSimilarToFile(res.body, blendPngFixture(filteredLayers), IMG_TOLERANCE_PER_MIL,
function (err) {
assert.ok(!err, err);
@@ -46,6 +46,10 @@ describe.skip('blend http client timeout', function () {
setTimeout(function () {
var filename = path.join(__dirname, '/../fixtures/http/light_nolabels-1-0-0.png');
fs.readFile(filename, { encoding: 'binary' }, function (err, file) {
if (err) {
return done(err);
}
response.writeHead(200);
response.write(file, 'binary');
response.end();
@@ -67,6 +71,7 @@ describe.skip('blend http client timeout', function () {
serverOptions: serverOptions
};
testClient.withLayergroup(mapConfig, options, function (err, requestTile, finish) {
assert.ifError(err);
var tileUrl = '/all/0/0/0.png';
requestTile(tileUrl, options, function (err, res) {
assert.ok(!err);
+1
View File
@@ -83,6 +83,7 @@ describe('blend png renderer', function () {
var zxy = [tileRequest.z, tileRequest.x, tileRequest.y];
it('tile all/' + zxy.join('/') + '.png', function (done) {
testClient.getTileLayer(plainTorqueMapConfig(testScenario.plainColor), tileRequest, function (err, res) {
assert.ifError(err);
assert.imageBufferIsSimilarToFile(res.body, blendPngFixture(zxy), IMAGE_TOLERANCE_PER_MIL,
function (err) {
assert.ok(!err);
@@ -119,6 +119,7 @@ describe('external resources', function () {
var mapConfig = testClient.defaultTableMapConfig('test_table_3', style);
testClient.createLayergroup(mapConfig, { statusCode: 400 }, function (err, res) {
assert.ifError(err);
assert.deepStrictEqual(JSON.parse(res.body).errors, [
"Unable to download '" + url + "' for 'style0' (server returned 404)"]
);
+8
View File
@@ -41,6 +41,7 @@ describe.skip('render limits', function () {
serverOptions: serverOptions
};
testClient.createLayergroup(slowQueryMapConfig, options, function (err, res) {
assert.ifError(err);
assert.deepStrictEqual(JSON.parse(res.body), { errors: ['Render timed out'] });
done();
});
@@ -48,8 +49,10 @@ describe.skip('render limits', function () {
it('uses onTileErrorStrategy to handle error and modify response', function (done) {
serverOptions.renderer.onTileErrorStrategy = function (err, tile, headers, stats, format, callback) {
assert.ifError(err);
var fixture = path.join(__dirname, '/../../fixtures/limits/fallback.png');
fs.readFile(fixture, { encoding: 'binary' }, function (err, img) {
assert.ifError(err);
callback(null, img, { 'Content-Type': 'image/png' }, {});
});
};
@@ -59,6 +62,7 @@ describe.skip('render limits', function () {
serverOptions: serverOptions
};
testClient.createLayergroup(slowQueryMapConfig, options, function (err, res) {
assert.ifError(err);
var parsed = JSON.parse(res.body);
assert.ok(parsed.layergroupid);
done();
@@ -68,7 +72,9 @@ describe.skip('render limits', function () {
it('returns a fallback tile that was modified via onTileErrorStrategy', function (done) {
var fixtureImage = './test/fixtures/limits/fallback.png';
serverOptions.renderer.onTileErrorStrategy = function (err, tile, headers, stats, format, callback) {
assert.ifError(err);
fs.readFile(fixtureImage, { encoding: null }, function (err, img) {
assert.ifError(err);
callback(null, img, { 'Content-Type': 'image/png' }, {});
});
};
@@ -78,8 +84,10 @@ describe.skip('render limits', function () {
serverOptions: serverOptions
};
testClient.withLayergroup(slowQueryMapConfig, options, function (err, requestTile, finish) {
assert.ifError(err);
var tileUrl = '/0/0/0.png';
requestTile(tileUrl, options, function (err, res) {
assert.ifError(err);
assert.imageBufferIsSimilarToFile(res.body, fixtureImage, IMAGE_EQUALS_TOLERANCE_PER_MIL,
function (err) {
finish(function (finishErr) {
@@ -326,6 +326,7 @@ describe('multilayer error cases', function () {
it('bogus sql raises 400 status code', function (done) {
var bogusSqlMapConfig = testClient.singleLayerMapConfig('BOGUS FROM test_table');
testClient.createLayergroup(bogusSqlMapConfig, { statusCode: 400 }, function (err, res) {
assert.ifError(err);
assert.ok(/syntax error/.test(res.body), 'Unexpected error: ' + res.body);
done();
});
@@ -341,6 +342,7 @@ describe('multilayer error cases', function () {
}
};
testClient.createLayergroup(bogusSqlMapConfig, options, function (err, res) {
assert.ifError(err);
assert.ok(
/^\/\*\*\/ typeof test === 'function' && test\(/.test(res.body),
'Body start expected callback name: ' + res.body
@@ -360,6 +362,7 @@ describe('multilayer error cases', function () {
}
};
testClient.createLayergroup(noGeomMapConfig, options, function (err, res) {
assert.ifError(err);
assert.ok(
/^\/\*\*\/ typeof test === 'function' && test\(/.test(res.body),
'Body start expected callback name: ' + res.body
@@ -372,6 +375,7 @@ describe('multilayer error cases', function () {
it('query with no geometry field returns 400 status', function (done) {
var noGeometrySqlMapConfig = testClient.singleLayerMapConfig('SELECT 1');
testClient.createLayergroup(noGeometrySqlMapConfig, { statusCode: 400 }, function (err, res) {
assert.ifError(err);
assert.ok(/column.*does not exist/.test(res.body), 'Unexpected error: ' + res.body);
done();
});
@@ -393,6 +397,7 @@ describe('multilayer error cases', function () {
var mapConfig = testClient.singleLayerMapConfig('select * from test_table', null, null, 'name');
testClient.getGrid(mapConfig, 1, 13, 4011, 3088, defaultErrorExpectedResponse, function (err, res) {
assert.ifError(err);
assert.deepStrictEqual(JSON.parse(res.body).errors, ["Layer '1' not found in layergroup"]);
done();
});
@@ -28,6 +28,7 @@ describe('regressions', function () {
};
testClient.getTile(writeSqlMapConfig, 0, 0, 0, expectedResponse, function (err, res) {
assert.ifError(err);
var parsedBody = JSON.parse(res.body);
assert.ok(parsedBody.errors);
assert.strictEqual(parsedBody.errors.length, 1);
@@ -51,19 +51,23 @@ describe('server_gettile', function () {
var lastXwc;
var mapConfig = testClient.defaultTableMapConfig('test_table');
testClient.withLayergroup(mapConfig, function (err, requestTile, finish) {
assert.ifError(err);
requestTile(tileUrl, function (err, res) {
assert.ifError(err);
var xwc = parseInt(res.headers['x-windshaft-cache'], 10);
assert.ok(xwc);
assert.ok(xwc > 0);
lastXwc = xwc;
requestTile(tileUrl, function (err, res) {
assert.ifError(err);
var xwc = parseInt(res.headers['x-windshaft-cache'], 10);
assert.ok(xwc);
assert.ok(xwc > 0);
assert.ok(xwc >= lastXwc);
requestTile(tileUrl, { cache_buster: 'wadus' }, function (err, res) {
assert.ifError(err);
var xwc = parseInt(res.headers['x-windshaft-cache'], 10);
assert.ok(!xwc);
@@ -102,11 +106,14 @@ describe('server_gettile', function () {
}
testClient.withLayergroup(mapConfig, validateLayergroup, function (err, requestTile, finish) {
assert.ifError(err);
requestTile(tileUrl, function (err, res) {
assert.ifError(err);
var xwc = parseInt(res.headers['x-windshaft-cache'], 10);
assert.ok(!xwc);
requestTile(tileUrl, function (err, res) {
assert.ifError(err);
assert.ok(
Object.prototype.hasOwnProperty.call(res.headers, 'x-windshaft-cache'),
'Did not hit renderer cache on second time'
@@ -155,6 +162,7 @@ describe('server_gettile', function () {
"#test_table{point-transform: 'scale(100)';}"
);
testClient.withLayergroup(nonStrictMapConfig, function (err, requestTile, finish) {
assert.ifError(err);
var options = {
statusCode: 400,
contentType: 'application/json; charset=utf-8'
@@ -256,6 +264,7 @@ describe('server_gettile', function () {
};
testClient.createLayergroup(mapConfig, options, function (err, res, parsedBody) {
assert.ifError(err);
assert.ok(parsedBody.errors);
// more assertions when errors is populated with better format
done();
+8
View File
@@ -67,6 +67,7 @@ describe('server', function () {
it('grid jsonp', function (done) {
var mapConfig = testClient.singleLayerMapConfig('select * from test_table', null, null, 'name');
testClient.getGridJsonp(mapConfig, 0, 13, 4011, 3088, 'jsonp_test', function (err, res) {
assert.ifError(err);
assert.strictEqual(res.statusCode, 200, res.body);
assert.deepStrictEqual(res.headers['content-type'], 'text/javascript; charset=utf-8');
var didRunJsonCallback = false;
@@ -86,6 +87,7 @@ describe('server', function () {
it("get'ing a json with default style and single interactivity should return a grid", function (done) {
var mapConfig = testClient.singleLayerMapConfig('select * from test_table', null, null, 'name');
testClient.getGrid(mapConfig, 0, 13, 4011, 3088, function (err, res) {
assert.ifError(err);
var expected_json = {
1: { name: 'Hawai' },
2: { name: 'El Estocolmo' },
@@ -107,6 +109,7 @@ describe('server', function () {
}
};
testClient.getGrid(mapConfig, 0, 13, 4011, 3088, expectedResponse, function (err, res) {
assert.ifError(err);
assert.deepStrictEqual(JSON.parse(res.body).errors, ['Tileset has no interactivity']);
done();
});
@@ -121,6 +124,7 @@ describe('server', function () {
}
};
testClient.getGridJsonp(mapConfig, 0, 13, 4011, 3088, 'test', expectedResponse, function (err, res) {
assert.ifError(err);
assert.ok(res.body.match(/"errors":/), 'missing error in response: ' + res.body);
done();
});
@@ -131,6 +135,7 @@ describe('server', function () {
var query = 'select * from test_table limit 0';
var mapConfig = testClient.singleLayerMapConfig(query, null, null, 'name');
testClient.getGrid(mapConfig, 0, 13, 4011, 3088, function (err, res) {
assert.ifError(err);
assert.utfgridEqualsFile(res.body, './test/fixtures/test_table_13_4011_3088_empty.grid.json', 2, done);
});
});
@@ -140,6 +145,7 @@ describe('server', function () {
var query = 'SELECT * FROM test_table limit 0';
var mapConfig = testClient.singleLayerMapConfig(query, null, null, 'cartodb_id');
testClient.getGrid(mapConfig, 0, 13, 4011, 3088, function (err, res) {
assert.ifError(err);
assert.utfgridEqualsFile(res.body, './test/fixtures/test_table_13_4011_3088_empty.grid.json', 2, done);
});
});
@@ -150,11 +156,13 @@ describe('server', function () {
var style211 = '#test_big_poly{polygon-fill:blue;}'; // for solid
var mapConfigName = testClient.singleLayerMapConfig(query, style211, null, 'name');
testClient.getGrid(mapConfigName, 0, 3, 2, 2, function (err, res) {
assert.ifError(err);
var expected_data = { 1: { name: 'west' } };
assert.deepStrictEqual(JSON.parse(res.body).data, expected_data);
var mapConfigCartodbId = testClient.singleLayerMapConfig(query, style211, null, 'cartodb_id');
testClient.getGrid(mapConfigCartodbId, 0, 3, 2, 2, function (err, res) {
assert.ifError(err);
var expected_data = { 1: { cartodb_id: 1 } };
assert.deepStrictEqual(JSON.parse(res.body).data, expected_data);
done();
@@ -19,6 +19,9 @@ describe('static_maps', function () {
httpRendererResourcesServer = http.createServer(function (request, response) {
var filename = path.join(__dirname, '/../../fixtures/http/basemap.png');
fs.readFile(filename, { encoding: 'binary' }, function (err, file) {
if (err) {
return done(err);
}
response.writeHead(200);
response.write(file, 'binary');
response.end();
@@ -71,6 +71,7 @@ describe('torque png renderer', function () {
var zxy = [z, x, y];
it('tile ' + zxy.join('/') + '.torque.png', function (done) {
testClient.getTileLayer(torquePngPointsMapConfig, tileRequest, function (err, res) {
assert.ifError(err);
assert.imageBufferIsSimilarToFile(res.body, torquePngFixture(zxy), IMAGE_TOLERANCE_PER_MIL,
function (err) {
assert.ok(!err);
+1
View File
@@ -95,6 +95,7 @@ describe('wrap x coordinate', function () {
var fixtureZxy = [testScenario.fixture.z, testScenario.fixture.x, testScenario.fixture.y];
it('tile all/' + zxy.join('/') + '.png', function (done) {
testClient.getTileLayer(plainTorqueMapConfig(testScenario.plainColor), tileRequest, function (err, res) {
assert.ifError(err);
assert.imageBufferIsSimilarToFile(res.body, blendPngFixture(fixtureZxy), IMG_TOLERANCE_PER_MIL,
function (err) {
assert.ok(!err);
+3
View File
@@ -42,6 +42,9 @@ describe('template_api', function () {
httpRendererResourcesServer = http.createServer(function (request, response) {
var filename = path.join(__dirname, '/../fixtures/http/light_nolabels-1-0-0.png');
fs.readFile(filename, { encoding: 'binary' }, function (err, file) {
if (err) {
return done();
}
response.writeHead(200);
response.write(file, 'binary');
response.end();
@@ -157,6 +157,7 @@ describe('user database timeout limit', function () {
};
this.testClient.getLayergroup({ response: expectedResponse }, (err, timeoutError) => {
assert.ifError(err);
assert.deepStrictEqual(timeoutError, {
errors: [db_limit_error_message],
errors_with_context: [{
@@ -379,6 +380,7 @@ describe('user database timeout limit', function () {
};
this.testClient.getLayergroup({ response: expectedResponse }, (err, timeoutError) => {
assert.ifError(err);
assert.deepStrictEqual(timeoutError, {
errors: [db_limit_error_message],
errors_with_context: [{
@@ -497,6 +499,7 @@ describe('user database timeout limit', function () {
};
this.testClient.getLayergroup({ response: expectedResponse }, (err, timeoutError) => {
assert.ifError(err);
assert.deepStrictEqual(timeoutError, {
errors: [db_limit_error_message],
errors_with_context: [{
@@ -601,6 +604,7 @@ describe('user database timeout limit', function () {
};
this.testClient.getLayergroup({ response: expectedResponse }, (err, timeoutError) => {
assert.ifError(err);
assert.deepStrictEqual(timeoutError, {
errors: [db_limit_error_message],
errors_with_context: [{
@@ -732,6 +736,7 @@ describe('user database timeout limit', function () {
};
this.testClient.getLayergroup({ response: expectedResponse }, (err, timeoutError) => {
assert.ifError(err);
assert.deepStrictEqual(timeoutError, {
errors: [db_limit_error_message],
errors_with_context: [{
+4
View File
@@ -787,6 +787,10 @@ TestClient.prototype.getTile = function (z, x, y, params, callback) {
function createLayergroup (err, templateId) {
var next = this;
if (err) {
return next(err);
}
if (layergroupId) {
return next(null, layergroupId);
}
+1
View File
@@ -160,6 +160,7 @@ function deleteRedisKeys (keysToDelete, callback) {
var redisClient = redis.createClient(global.environment.redis.port);
redisClient.select(keysToDelete[k], function () {
redisClient.del(k, function (err, deletedKeysCount) {
assert.ifError(err);
redisClient.quit();
assert.notStrictEqual(deletedKeysCount, 0, 'No KEYS deleted for: [db=' + keysToDelete[k] + ']' + k);
taskDone(k);
@@ -33,6 +33,7 @@ describe('turbo-carto-postgres-datasource', function () {
var buckets = 4;
var method = 'equal';
this.datasource.getRamp(column, buckets, method, function (err, result) {
assert.ifError(err);
var expected_result = {
ramp: [252, 501, 750, 999],
stats: { min_val: 3, max_val: 999, avg_val: 501 },
+4
View File
@@ -13,6 +13,10 @@ describe('lzma-middleware', function () {
}
};
testHelper.lzma_compress_to_base64(JSON.stringify(qo), 1, function (err, data) {
if (err) {
return done(err);
}
const lzma = lzmaMiddleware();
var req = {
headers: {
@@ -250,6 +250,7 @@ describe('dataviews-widgets-adapter', function () {
widgetsMapConfigs.forEach(function (mapConfig, index) {
it('should adapt widgets ' + index, function (done) {
dataviewsMapConfigAdapter.getMapConfig(user, mapConfig.input, params(), context(), function (err, result) {
assert.ifError(err);
assert.deepStrictEqual(result, mapConfig.expected);
done();
});