2018-10-24 00:39:02 +08:00
|
|
|
'use strict';
|
|
|
|
|
2019-10-07 16:44:45 +08:00
|
|
|
var testHelper = require('../../support/test-helper');
|
2015-04-10 19:39:20 +08:00
|
|
|
|
2017-03-14 01:36:13 +08:00
|
|
|
var assert = require('../../support/assert');
|
2015-04-10 19:39:20 +08:00
|
|
|
var qs = require('querystring');
|
|
|
|
|
2019-10-07 15:40:50 +08:00
|
|
|
var CartodbWindshaft = require('../../../lib/server');
|
2019-10-07 16:10:51 +08:00
|
|
|
var serverOptions = require('../../../lib/server-options');
|
2015-04-10 19:39:20 +08:00
|
|
|
|
2019-10-07 15:40:50 +08:00
|
|
|
var LayergroupToken = require('../../../lib/models/layergroup-token');
|
2015-09-25 23:08:38 +08:00
|
|
|
|
2019-10-22 01:07:24 +08:00
|
|
|
describe('get requests with cache headers', function () {
|
2018-04-16 22:16:23 +08:00
|
|
|
var server;
|
|
|
|
|
|
|
|
before(function () {
|
|
|
|
server = new CartodbWindshaft(serverOptions);
|
|
|
|
server.setMaxListeners(0);
|
|
|
|
});
|
|
|
|
|
2015-09-25 23:08:38 +08:00
|
|
|
var keysToDelete;
|
2019-10-22 01:07:24 +08:00
|
|
|
beforeEach(function () {
|
2015-09-26 00:37:21 +08:00
|
|
|
keysToDelete = {};
|
2015-09-25 23:08:38 +08:00
|
|
|
});
|
|
|
|
|
2019-10-22 01:07:24 +08:00
|
|
|
afterEach(function (done) {
|
2015-09-25 23:08:38 +08:00
|
|
|
testHelper.deleteRedisKeys(keysToDelete, done);
|
|
|
|
});
|
|
|
|
|
2015-04-10 19:39:20 +08:00
|
|
|
var statusOkResponse = {
|
|
|
|
status: 200
|
|
|
|
};
|
|
|
|
|
2017-03-11 00:22:07 +08:00
|
|
|
var mapConfigs = [
|
|
|
|
{
|
2019-10-22 01:07:24 +08:00
|
|
|
description: 'cache headers should be present',
|
|
|
|
cache_headers: {
|
|
|
|
x_cache_channel: {
|
|
|
|
db_name: 'test_windshaft_cartodb_user_1_db',
|
|
|
|
tables: ['public.test_table']
|
2017-03-14 21:32:36 +08:00
|
|
|
},
|
2019-10-22 01:07:24 +08:00
|
|
|
surrogate_keys: 't:77pJnX'
|
2017-03-14 01:36:13 +08:00
|
|
|
},
|
2019-10-22 01:07:24 +08:00
|
|
|
data:
|
2017-03-11 00:22:07 +08:00
|
|
|
{
|
2017-03-14 01:36:13 +08:00
|
|
|
version: '1.5.0',
|
2017-03-11 00:22:07 +08:00
|
|
|
layers: [
|
|
|
|
{
|
|
|
|
options: {
|
|
|
|
source: {
|
2019-10-22 01:07:24 +08:00
|
|
|
id: '2570e105-7b37-40d2-bdf4-1af889598745'
|
2017-03-11 00:22:07 +08:00
|
|
|
},
|
|
|
|
sql: 'select * from test_table limit 2',
|
|
|
|
cartocss: '#layer { marker-fill:red; }',
|
|
|
|
cartocss_version: '2.3.0',
|
|
|
|
attributes: {
|
2019-10-22 01:07:24 +08:00
|
|
|
id: 'cartodb_id',
|
2017-03-11 00:22:07 +08:00
|
|
|
columns: [
|
|
|
|
'name',
|
|
|
|
'address'
|
|
|
|
]
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
],
|
|
|
|
analyses: [
|
|
|
|
{
|
2019-10-22 01:07:24 +08:00
|
|
|
id: '2570e105-7b37-40d2-bdf4-1af889598745',
|
|
|
|
type: 'source',
|
|
|
|
params: {
|
|
|
|
query: 'select * from test_table limit 2'
|
2017-03-11 00:22:07 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
]
|
2019-10-22 01:07:24 +08:00
|
|
|
}
|
2017-03-11 00:22:07 +08:00
|
|
|
},
|
|
|
|
{
|
2019-10-22 01:07:24 +08:00
|
|
|
description: 'cache headers should be present and be composed with source table name',
|
|
|
|
cache_headers: {
|
|
|
|
x_cache_channel: {
|
|
|
|
db_name: 'test_windshaft_cartodb_user_1_db',
|
|
|
|
tables: ['public.analysis_2f13a3dbd7_9eb239903a1afd8a69130d1ece0fc8b38de8592d',
|
|
|
|
'public.test_table']
|
2017-03-14 21:32:36 +08:00
|
|
|
},
|
2019-10-22 01:07:24 +08:00
|
|
|
surrogate_keys: 't:77pJnX t:iL4eth'
|
2017-03-14 01:36:13 +08:00
|
|
|
},
|
2019-10-22 01:07:24 +08:00
|
|
|
data:
|
2015-04-10 19:39:20 +08:00
|
|
|
{
|
2017-03-11 00:22:07 +08:00
|
|
|
version: '1.5.0',
|
|
|
|
layers: [
|
|
|
|
{
|
|
|
|
options: {
|
|
|
|
source: {
|
2019-10-22 01:07:24 +08:00
|
|
|
id: '2570e105-7b37-40d2-bdf4-1af889598745'
|
2017-03-11 00:22:07 +08:00
|
|
|
},
|
|
|
|
sql: 'select * from test_table limit 2',
|
|
|
|
cartocss: '#layer { marker-fill:red; }',
|
|
|
|
cartocss_version: '2.3.0',
|
|
|
|
attributes: {
|
2019-10-22 01:07:24 +08:00
|
|
|
id: 'cartodb_id',
|
2017-03-11 00:22:07 +08:00
|
|
|
columns: [
|
|
|
|
'name',
|
|
|
|
'address'
|
|
|
|
]
|
|
|
|
}
|
|
|
|
}
|
2015-04-10 19:39:20 +08:00
|
|
|
}
|
2017-03-11 00:22:07 +08:00
|
|
|
],
|
|
|
|
analyses: [
|
|
|
|
{
|
2019-10-22 01:07:24 +08:00
|
|
|
id: '2570e105-7b37-40d2-bdf4-1af889598745',
|
|
|
|
type: 'buffer',
|
|
|
|
params: {
|
|
|
|
source: {
|
|
|
|
type: 'source',
|
|
|
|
params: {
|
|
|
|
query: 'select * from test_table limit 2'
|
2017-03-11 00:22:07 +08:00
|
|
|
}
|
|
|
|
},
|
2019-10-22 01:07:24 +08:00
|
|
|
radius: 50000
|
2017-03-11 00:22:07 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
]
|
2015-04-10 19:39:20 +08:00
|
|
|
}
|
2017-03-11 00:22:07 +08:00
|
|
|
}];
|
2015-04-10 19:39:20 +08:00
|
|
|
|
2019-10-22 01:07:24 +08:00
|
|
|
var layergroupRequest = function (mapConfig) {
|
2017-03-11 00:22:07 +08:00
|
|
|
return {
|
|
|
|
url: '/api/v1/map?api_key=1234&config=' + encodeURIComponent(JSON.stringify(mapConfig)),
|
|
|
|
method: 'GET',
|
|
|
|
headers: {
|
|
|
|
host: 'localhost'
|
|
|
|
}
|
|
|
|
};
|
2015-04-10 19:39:20 +08:00
|
|
|
};
|
|
|
|
|
2019-10-22 01:07:24 +08:00
|
|
|
function getRequest (url, addApiKey, callbackName) {
|
2015-04-10 19:39:20 +08:00
|
|
|
var params = {};
|
2019-10-22 01:07:24 +08:00
|
|
|
if (addApiKey) {
|
2015-04-10 19:39:20 +08:00
|
|
|
params.api_key = '1234';
|
|
|
|
}
|
2019-10-22 01:07:24 +08:00
|
|
|
if (callbackName) {
|
2015-04-10 19:39:20 +08:00
|
|
|
params.callback = callbackName;
|
|
|
|
}
|
|
|
|
|
|
|
|
return {
|
|
|
|
url: url + '?' + qs.stringify(params),
|
|
|
|
method: 'GET',
|
|
|
|
headers: {
|
|
|
|
host: 'localhost',
|
|
|
|
'Content-Type': 'application/json'
|
|
|
|
}
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2019-10-22 01:07:24 +08:00
|
|
|
function validateCacheHeaders (done, expectedCacheHeaders) {
|
|
|
|
return function (res, err) {
|
2015-04-10 19:39:20 +08:00
|
|
|
if (err) {
|
|
|
|
return done(err);
|
|
|
|
}
|
|
|
|
|
|
|
|
assert.ok(res.headers['x-cache-channel']);
|
2017-03-14 01:36:13 +08:00
|
|
|
assert.ok(res.headers['surrogate-key']);
|
2019-10-22 01:41:03 +08:00
|
|
|
assert.strictEqual(res.headers.vary, 'Authorization');
|
2017-03-14 01:36:13 +08:00
|
|
|
if (expectedCacheHeaders) {
|
2017-03-14 21:32:36 +08:00
|
|
|
validateXChannelHeaders(res.headers, expectedCacheHeaders);
|
2019-10-22 01:41:03 +08:00
|
|
|
assert.strictEqual(res.headers['surrogate-key'], expectedCacheHeaders.surrogate_keys);
|
2015-04-10 19:39:20 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
done();
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2019-10-22 01:07:24 +08:00
|
|
|
function validateXChannelHeaders (headers, expectedCacheHeaders) {
|
2017-03-14 21:32:36 +08:00
|
|
|
var dbName = headers['x-cache-channel'].split(':')[0];
|
|
|
|
var tables = headers['x-cache-channel'].split(':')[1].split(',').sort();
|
2019-10-22 01:41:03 +08:00
|
|
|
assert.strictEqual(dbName, expectedCacheHeaders.x_cache_channel.db_name);
|
2019-10-22 01:52:51 +08:00
|
|
|
assert.deepStrictEqual(tables, expectedCacheHeaders.x_cache_channel.tables.sort());
|
2017-03-14 21:32:36 +08:00
|
|
|
}
|
|
|
|
|
2019-10-22 01:07:24 +08:00
|
|
|
function noCacheHeaders (done) {
|
|
|
|
return function (res, err) {
|
2015-04-10 19:39:20 +08:00
|
|
|
if (err) {
|
|
|
|
return done(err);
|
|
|
|
}
|
|
|
|
|
|
|
|
assert.ok(
|
|
|
|
!res.headers['x-cache-channel'],
|
|
|
|
'did not expect x-cache-channel header, got: `' + res.headers['x-cache-channel'] + '`'
|
|
|
|
);
|
2017-03-14 01:36:13 +08:00
|
|
|
assert.ok(
|
|
|
|
!res.headers['surrogate-key'],
|
|
|
|
'did not expect surrogate-key header, got: `' + res.headers['surrogate-key'] + '`'
|
|
|
|
);
|
2015-04-10 19:39:20 +08:00
|
|
|
done();
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2019-10-22 01:07:24 +08:00
|
|
|
function withLayergroupId (mapConfig, callback) {
|
2015-04-10 19:39:20 +08:00
|
|
|
assert.response(
|
|
|
|
server,
|
2017-03-11 00:22:07 +08:00
|
|
|
layergroupRequest(mapConfig),
|
2015-04-10 19:39:20 +08:00
|
|
|
statusOkResponse,
|
2019-10-22 01:07:24 +08:00
|
|
|
function (res, err) {
|
2015-04-10 19:39:20 +08:00
|
|
|
if (err) {
|
|
|
|
return callback(err);
|
|
|
|
}
|
2015-09-25 23:08:38 +08:00
|
|
|
var layergroupId = JSON.parse(res.body).layergroupid;
|
|
|
|
keysToDelete['map_cfg|' + LayergroupToken.parse(layergroupId).token] = 0;
|
2015-09-26 00:37:21 +08:00
|
|
|
keysToDelete['user:localhost:mapviews:global'] = 5;
|
|
|
|
callback(null, layergroupId, res);
|
2015-04-10 19:39:20 +08:00
|
|
|
}
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2019-10-22 01:07:24 +08:00
|
|
|
mapConfigs.forEach(function (mapConfigData) {
|
|
|
|
describe(mapConfigData.description, function () {
|
2017-03-11 00:22:07 +08:00
|
|
|
var mapConfig = mapConfigData.data;
|
2017-03-14 01:36:13 +08:00
|
|
|
var expectedCacheHeaders = mapConfigData.cache_headers;
|
2019-10-22 01:07:24 +08:00
|
|
|
it('/api/v1/map Map instantiation', function (done) {
|
2017-03-14 01:36:13 +08:00
|
|
|
var testFn = validateCacheHeaders(done, expectedCacheHeaders);
|
2019-10-22 01:07:24 +08:00
|
|
|
withLayergroupId(mapConfig, function (err, layergroupId, res) {
|
2019-10-25 00:38:37 +08:00
|
|
|
testFn(res, err);
|
2017-03-11 00:22:07 +08:00
|
|
|
});
|
2015-09-26 00:37:21 +08:00
|
|
|
});
|
2015-04-10 19:39:20 +08:00
|
|
|
|
2019-10-22 01:07:24 +08:00
|
|
|
it('/api/v1/map/:token/:z/:x/:y@:scale_factor?x.:format Mapnik retina tiles', function (done) {
|
|
|
|
withLayergroupId(mapConfig, function (err, layergroupId) {
|
2019-10-25 00:38:37 +08:00
|
|
|
assert.ifError(err);
|
2017-03-11 00:22:07 +08:00
|
|
|
assert.response(
|
|
|
|
server,
|
2017-03-14 00:28:29 +08:00
|
|
|
getRequest('/api/v1/map/' + layergroupId + '/0/0/0@2x.png', true),
|
2017-03-14 01:36:13 +08:00
|
|
|
validateCacheHeaders(done, expectedCacheHeaders)
|
2017-03-11 00:22:07 +08:00
|
|
|
);
|
|
|
|
});
|
2015-04-10 19:39:20 +08:00
|
|
|
});
|
|
|
|
|
2019-10-22 01:07:24 +08:00
|
|
|
it('/api/v1/map/:token/:z/:x/:y@:scale_factor?x.:format Mapnik tiles', function (done) {
|
|
|
|
withLayergroupId(mapConfig, function (err, layergroupId) {
|
2019-10-25 00:38:37 +08:00
|
|
|
assert.ifError(err);
|
2017-03-11 00:22:07 +08:00
|
|
|
assert.response(
|
|
|
|
server,
|
2017-03-14 00:28:29 +08:00
|
|
|
getRequest('/api/v1/map/' + layergroupId + '/0/0/0.png', true),
|
2017-03-14 01:36:13 +08:00
|
|
|
validateCacheHeaders(done, expectedCacheHeaders)
|
2017-03-11 00:22:07 +08:00
|
|
|
);
|
|
|
|
});
|
2015-04-10 19:39:20 +08:00
|
|
|
});
|
|
|
|
|
2019-10-22 01:07:24 +08:00
|
|
|
it('/api/v1/map/:token/:layer/:z/:x/:y.(:format) Per :layer rendering', function (done) {
|
|
|
|
withLayergroupId(mapConfig, function (err, layergroupId) {
|
2019-10-25 00:38:37 +08:00
|
|
|
assert.ifError(err);
|
2017-03-11 00:22:07 +08:00
|
|
|
assert.response(
|
|
|
|
server,
|
2017-03-14 00:28:29 +08:00
|
|
|
getRequest('/api/v1/map/' + layergroupId + '/0/0/0/0.png', true),
|
2017-03-14 01:36:13 +08:00
|
|
|
validateCacheHeaders(done, expectedCacheHeaders)
|
2017-03-11 00:22:07 +08:00
|
|
|
);
|
|
|
|
});
|
2015-04-10 19:39:20 +08:00
|
|
|
});
|
|
|
|
|
2019-10-22 01:07:24 +08:00
|
|
|
it('/api/v1/map/:token/:layer/attributes/:fid endpoint for info windows', function (done) {
|
|
|
|
withLayergroupId(mapConfig, function (err, layergroupId) {
|
2019-10-25 00:38:37 +08:00
|
|
|
assert.ifError(err);
|
2017-03-11 00:22:07 +08:00
|
|
|
assert.response(
|
|
|
|
server,
|
2017-03-14 00:28:29 +08:00
|
|
|
getRequest('/api/v1/map/' + layergroupId + '/0/attributes/1', true),
|
2017-03-14 01:36:13 +08:00
|
|
|
validateCacheHeaders(done, expectedCacheHeaders)
|
2017-03-11 00:22:07 +08:00
|
|
|
);
|
|
|
|
});
|
2015-04-10 19:39:20 +08:00
|
|
|
});
|
|
|
|
|
2019-10-22 01:07:24 +08:00
|
|
|
it('/api/v1/map/static/center/:token/:z/:lat/:lng/:width/:height.:format static maps', function (done) {
|
|
|
|
withLayergroupId(mapConfig, function (err, layergroupId) {
|
2019-10-25 00:38:37 +08:00
|
|
|
assert.ifError(err);
|
2017-03-11 00:22:07 +08:00
|
|
|
assert.response(
|
|
|
|
server,
|
2017-03-14 00:28:29 +08:00
|
|
|
getRequest('/api/v1/map/static/center/' + layergroupId + '/0/0/0/400/300.png', true),
|
2017-03-14 01:36:13 +08:00
|
|
|
validateCacheHeaders(done, expectedCacheHeaders)
|
2017-03-11 00:22:07 +08:00
|
|
|
);
|
|
|
|
});
|
2015-04-10 19:39:20 +08:00
|
|
|
});
|
|
|
|
|
2019-10-22 01:07:24 +08:00
|
|
|
it('/api/v1/map/static/bbox/:token/:bbox/:width/:height.:format static maps', function (done) {
|
|
|
|
withLayergroupId(mapConfig, function (err, layergroupId) {
|
2019-10-25 00:38:37 +08:00
|
|
|
assert.ifError(err);
|
2017-03-11 00:22:07 +08:00
|
|
|
assert.response(
|
|
|
|
server,
|
2017-03-14 00:28:29 +08:00
|
|
|
getRequest('/api/v1/map/static/bbox/' + layergroupId + '/-45,-45,45,45/400/300.png', true),
|
2017-03-14 01:36:13 +08:00
|
|
|
validateCacheHeaders(done, expectedCacheHeaders)
|
2017-03-11 00:22:07 +08:00
|
|
|
);
|
|
|
|
});
|
2015-04-10 19:39:20 +08:00
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
2019-10-22 01:07:24 +08:00
|
|
|
describe('cache headers should NOT be present', function () {
|
|
|
|
it('/', function (done) {
|
2015-04-10 19:39:20 +08:00
|
|
|
assert.response(
|
|
|
|
server,
|
|
|
|
getRequest('/'),
|
|
|
|
statusOkResponse,
|
2017-03-14 01:36:13 +08:00
|
|
|
noCacheHeaders(done)
|
2015-04-10 19:39:20 +08:00
|
|
|
);
|
|
|
|
});
|
|
|
|
|
2019-10-22 01:07:24 +08:00
|
|
|
it('/health', function (done) {
|
2015-04-10 19:39:20 +08:00
|
|
|
assert.response(
|
|
|
|
server,
|
|
|
|
getRequest('/health'),
|
|
|
|
statusOkResponse,
|
2017-03-14 01:36:13 +08:00
|
|
|
noCacheHeaders(done)
|
2015-04-10 19:39:20 +08:00
|
|
|
);
|
|
|
|
});
|
|
|
|
|
2019-10-22 01:07:24 +08:00
|
|
|
it('/api/v1/map/named list named maps', function (done) {
|
2015-04-10 19:39:20 +08:00
|
|
|
assert.response(
|
|
|
|
server,
|
|
|
|
getRequest('/api/v1/map/named', true),
|
|
|
|
statusOkResponse,
|
2017-03-14 01:36:13 +08:00
|
|
|
noCacheHeaders(done)
|
2015-04-10 19:39:20 +08:00
|
|
|
);
|
|
|
|
});
|
|
|
|
|
2019-10-22 01:07:24 +08:00
|
|
|
describe('with named maps', function () {
|
2015-04-10 19:39:20 +08:00
|
|
|
var templateName = 'x_cache';
|
|
|
|
|
2019-10-22 01:07:24 +08:00
|
|
|
beforeEach(function (done) {
|
|
|
|
var template = {
|
2015-04-10 19:39:20 +08:00
|
|
|
version: '0.0.1',
|
|
|
|
name: templateName,
|
|
|
|
auth: {
|
|
|
|
method: 'open'
|
|
|
|
},
|
2019-10-22 01:07:24 +08:00
|
|
|
layergroup: mapConfigs[0].data
|
2015-04-10 19:39:20 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
var namedMapRequest = {
|
|
|
|
url: '/api/v1/map/named?api_key=1234',
|
|
|
|
method: 'POST',
|
|
|
|
headers: {
|
|
|
|
host: 'localhost',
|
|
|
|
'Content-Type': 'application/json'
|
|
|
|
},
|
|
|
|
data: JSON.stringify(template)
|
|
|
|
};
|
|
|
|
|
|
|
|
assert.response(
|
|
|
|
server,
|
|
|
|
namedMapRequest,
|
|
|
|
statusOkResponse,
|
2019-10-22 01:07:24 +08:00
|
|
|
function (res, err) {
|
2015-04-10 19:39:20 +08:00
|
|
|
done(err);
|
|
|
|
}
|
|
|
|
);
|
|
|
|
});
|
|
|
|
|
2019-10-22 01:07:24 +08:00
|
|
|
afterEach(function (done) {
|
2015-04-10 19:39:20 +08:00
|
|
|
assert.response(
|
|
|
|
server,
|
|
|
|
{
|
|
|
|
url: '/api/v1/map/named/' + templateName + '?api_key=1234',
|
|
|
|
method: 'DELETE',
|
|
|
|
headers: {
|
|
|
|
host: 'localhost'
|
|
|
|
}
|
|
|
|
},
|
|
|
|
{
|
|
|
|
status: 204
|
|
|
|
},
|
2019-10-22 01:07:24 +08:00
|
|
|
function (res, err) {
|
2015-04-10 19:39:20 +08:00
|
|
|
done(err);
|
|
|
|
}
|
|
|
|
);
|
|
|
|
});
|
|
|
|
|
2019-10-22 01:07:24 +08:00
|
|
|
it('/api/v1/map/named/:template_id Named map retrieval', function (done) {
|
2015-04-10 19:39:20 +08:00
|
|
|
assert.response(
|
|
|
|
server,
|
|
|
|
getRequest('/api/v1/map/named/' + templateName, true),
|
|
|
|
statusOkResponse,
|
2017-03-14 01:36:13 +08:00
|
|
|
noCacheHeaders(done)
|
2015-04-10 19:39:20 +08:00
|
|
|
);
|
|
|
|
});
|
|
|
|
|
2019-10-22 01:07:24 +08:00
|
|
|
it('/api/v1/map/named/:template_id/jsonp Named map retrieval', function (done) {
|
2015-04-10 19:39:20 +08:00
|
|
|
assert.response(
|
|
|
|
server,
|
|
|
|
getRequest('/api/v1/map/named/' + templateName, true, 'cb'),
|
|
|
|
statusOkResponse,
|
2017-03-14 01:36:13 +08:00
|
|
|
noCacheHeaders(done)
|
2015-04-10 19:39:20 +08:00
|
|
|
);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|