From b25540720ca2e5e2b8dd3f285354b0b7ff522a6a Mon Sep 17 00:00:00 2001 From: Mario de Frutos Date: Tue, 9 May 2017 14:36:35 +0200 Subject: [PATCH] Added acceptance tests for stats functionallity --- .../stats/mapnik_stats_layergroup.js | 260 ++++++++++++++++++ test/acceptance/stats/multilayer_stats.js | 219 +++++++++++++++ test/support/sql/windshaft.test.sql | 2 + 3 files changed, 481 insertions(+) create mode 100644 test/acceptance/stats/mapnik_stats_layergroup.js create mode 100644 test/acceptance/stats/multilayer_stats.js diff --git a/test/acceptance/stats/mapnik_stats_layergroup.js b/test/acceptance/stats/mapnik_stats_layergroup.js new file mode 100644 index 00000000..746f6c5c --- /dev/null +++ b/test/acceptance/stats/mapnik_stats_layergroup.js @@ -0,0 +1,260 @@ +require('../../support/test_helper'); + +var assert = require('../../support/assert'); +var TestClient = require('../../support/test-client'); + +describe('Create mapnik layergroup', function() { + before(function() { + this.layerMetadataConfig = global.environment.enabledFeatures.layerMetadata; + global.environment.enabledFeatures.layerMetadata = true; + }); + + after(function() { + global.environment.enabledFeatures.layerMetadata = this.layerMetadataConfig; + }); + + var cartocssVersion = '2.3.0'; + var cartocss = '#layer { line-width:16; }'; + + var mapnikLayer1 = { + type: 'mapnik', + options: { + sql: 'select * from test_table limit 2', + cartocss_version: cartocssVersion, + cartocss: cartocss + } + }; + + var mapnikLayer2 = { + type: 'mapnik', + options: { + sql: 'select * from test_table_2 limit 2', + cartocss_version: cartocssVersion, + cartocss: cartocss + } + }; + + var mapnikLayer3 = { + type: 'mapnik', + options: { + sql: 'select * from test_table_3 limit 2', + cartocss_version: cartocssVersion, + cartocss: cartocss + } + }; + + var mapnikLayer4 = { + type: 'mapnik', + options: { + sql: [ + 'select t1.cartodb_id, t1.the_geom, t1.the_geom_webmercator, t2.address', + ' from test_table t1, test_table_2 t2', + ' where t1.cartodb_id = t2.cartodb_id;' + ].join(''), + cartocss_version: cartocssVersion, + cartocss: cartocss + } + }; + + var httpLayer = { + type: 'http', + options: { + urlTemplate: 'http://{s}.basemaps.cartocdn.com/dark_nolabels/{z}/{x}/{y}.png', + subdomains: ['a','b','c'] + } + }; + + var mapnikLayerGeomColumn = { + type: 'mapnik', + options: { + sql: 'select *, the_geom as my_geom from test_table_3 limit 2', + geom_column: 'my_geom', + cartocss_version: cartocssVersion, + cartocss: cartocss + } + }; + + function mapnikBasicLayerId(index) { + return 'layer' + index; + } + function typeLayerId(type, index) { + return type + '-' + mapnikBasicLayerId(index); + } + + it('with one mapnik layer should response with meta-stats for that layer', function(done) { + var testClient = new TestClient({ + version: '1.4.0', + layers: [ + mapnikLayer1 + ] + }); + + testClient.getLayergroup(function(err, layergroup) { + assert.ok(!err); + assert.equal(layergroup.metadata.layers[0].id, mapnikBasicLayerId(0)); + assert.equal(layergroup.metadata.layers[0].meta.stats[0].features, 5); + testClient.drain(done); + }); + }); + + it('with two mapnik layer should response with meta-stats for every layer', function(done) { + var testClient = new TestClient({ + version: '1.4.0', + layers: [ + mapnikLayer1, + mapnikLayer2 + ] + }); + + testClient.getLayergroup(function(err, layergroup) { + assert.ok(!err); + assert.equal(layergroup.metadata.layers[0].id, mapnikBasicLayerId(0)); + assert.equal(layergroup.metadata.layers[0].meta.stats[0].features, 5); + assert.equal(layergroup.metadata.layers[1].id, mapnikBasicLayerId(1)); + assert.equal(layergroup.metadata.layers[1].meta.stats[0].features, 5); + testClient.drain(done); + }); + }); + + it('with three mapnik layer should response with meta-stats for every layer', function(done) { + var testClient = new TestClient({ + version: '1.4.0', + layers: [ + mapnikLayer1, + mapnikLayer2, + mapnikLayer3 + ] + }); + + testClient.getLayergroup(function(err, layergroup) { + assert.ok(!err); + assert.equal(layergroup.metadata.layers[0].id, mapnikBasicLayerId(0)); + assert.equal(layergroup.metadata.layers[0].meta.stats[0].features, 5); + assert.equal(layergroup.metadata.layers[1].id, mapnikBasicLayerId(1)); + assert.equal(layergroup.metadata.layers[1].meta.stats[0].features, 5); + assert.equal(layergroup.metadata.layers[2].id, mapnikBasicLayerId(2)); + assert.equal(layergroup.metadata.layers[2].meta.stats[0].features, 5); + testClient.drain(done); + }); + }); + + it('with one mapnik layer (sql with join) should response with meta-stats for that layer', function(done) { + var testClient = new TestClient({ + version: '1.4.0', + layers: [ + mapnikLayer4 + ] + }); + + testClient.getLayergroup(function(err, layergroup) { + assert.ok(!err); + assert.equal(layergroup.metadata.layers[0].id, mapnikBasicLayerId(0)); + assert.equal(layergroup.metadata.layers[0].meta.stats[0].features, 5); + assert.equal(layergroup.metadata.layers[0].meta.stats[1].features, 5); + testClient.drain(done); + }); + }); + + it('with two mapnik layer (sql with join) should response with meta-stats for every layer', function(done) { + var testClient = new TestClient({ + version: '1.4.0', + layers: [ + mapnikLayer4, + mapnikLayer4 + ] + }); + + testClient.getLayergroup(function(err, layergroup) { + assert.ok(!err); + assert.equal(layergroup.metadata.layers[0].id, mapnikBasicLayerId(0)); + assert.equal(layergroup.metadata.layers[0].meta.stats[0].features, 5); + assert.equal(layergroup.metadata.layers[0].meta.stats[1].features, 5); + assert.equal(layergroup.metadata.layers[1].id, mapnikBasicLayerId(1)); + assert.equal(layergroup.metadata.layers[1].meta.stats[0].features, 5); + assert.equal(layergroup.metadata.layers[1].meta.stats[1].features, 5); + testClient.drain(done); + }); + }); + + it('with two mapnik layer (with & without join) should response with meta-stats for every layer', function(done) { + var testClient = new TestClient({ + version: '1.4.0', + layers: [ + mapnikLayer3, + mapnikLayer4 + ] + }); + + testClient.getLayergroup(function(err, layergroup) { + assert.ok(!err); + assert.equal(layergroup.metadata.layers[0].id, mapnikBasicLayerId(0)); + assert.equal(layergroup.metadata.layers[0].meta.stats[0].features, 5); + assert.ok(!layergroup.metadata.layers[0].meta.stats[1]); + assert.equal(layergroup.metadata.layers[1].id, mapnikBasicLayerId(1)); + assert.equal(layergroup.metadata.layers[1].meta.stats[0].features, 5); + assert.equal(layergroup.metadata.layers[1].meta.stats[1].features, 5); + assert.ok(!layergroup.metadata.layers[1].meta.stats[2]); + assert.ok(!layergroup.metadata.layers[2]); + testClient.drain(done); + }); + }); + + it('with mapnik and layer and httplayer should response with layer metadata with same order', function(done) { + var testClient = new TestClient({ + version: '1.4.0', + layers: [ + mapnikLayer1, + httpLayer + ] + }); + + testClient.getLayergroup(function(err, layergroup) { + assert.ok(!err); + assert.equal(layergroup.metadata.layers[0].id, mapnikBasicLayerId(0)); + assert.equal(layergroup.metadata.layers[0].type, 'mapnik'); + assert.equal(layergroup.metadata.layers[0].meta.stats[0].features, 5); + assert.equal(layergroup.metadata.layers[1].id, typeLayerId('http', 0)); + assert.equal(layergroup.metadata.layers[1].type, 'http'); + testClient.drain(done); + }); + }); + + it('with httpLayer and mapnik layer should response with layer metadata with same order', function(done) { + var testClient = new TestClient({ + version: '1.4.0', + layers: [ + httpLayer, + mapnikLayer1 + ] + }); + + testClient.getLayergroup(function (err, layergroup) { + assert.ok(!err); + assert.equal(layergroup.metadata.layers[0].id, typeLayerId('http', 0)); + assert.equal(layergroup.metadata.layers[0].type, 'http'); + assert.ok(!layergroup.metadata.layers[0].meta.cartocss); + assert.equal(layergroup.metadata.layers[1].meta.stats[0].features, 5); + assert.equal(layergroup.metadata.layers[1].id, mapnikBasicLayerId(0)); + assert.equal(layergroup.metadata.layers[1].type, 'mapnik'); + assert.equal(layergroup.metadata.layers[1].meta.cartocss, cartocss); + testClient.drain(done); + }); + }); + + it('should work with different geom_column', function(done) { + var testClient = new TestClient({ + version: '1.4.0', + layers: [ + mapnikLayerGeomColumn + ] + }); + + testClient.getLayergroup(function(err, layergroup) { + assert.ok(!err); + assert.equal(layergroup.metadata.layers[0].id, mapnikBasicLayerId(0)); + // we don't care about stats here as is an aliased column + assert.ok(layergroup.metadata.layers[0].meta.stats[0].hasOwnProperty('features')); + testClient.drain(done); + }); + }); +}); diff --git a/test/acceptance/stats/multilayer_stats.js b/test/acceptance/stats/multilayer_stats.js new file mode 100644 index 00000000..4571bf6a --- /dev/null +++ b/test/acceptance/stats/multilayer_stats.js @@ -0,0 +1,219 @@ +require('../../support/test_helper'); + +var assert = require('../../support/assert'); +var TestClient = require('../../support/test-client'); + +describe('multilayer stats disabled', function() { + + before(function () { + global.environment.enabledFeatures.layerMetadata = false; + }); + + after(function () { + global.environment.enabledFeatures.layerMetadata = true; + }); + + + function testLayerMetadataStats(testScenario) { + + it(testScenario.desc, function(done) { + var mapConfig = { + version: '1.3.0', + layers: testScenario.layers + }; + + var testClient = new TestClient(mapConfig); + + testClient.getLayergroup(function(err, layergroup) { + assert.ifError(err); + layergroup.metadata.layers.forEach(function (layer) { + if (layer.type !== 'torque' && layer.type !== 'mapnik') { + assert.ok('stats' in layer.meta); + } else if (layer.type !== 'torque') { + assert.ok('stats' in layer.meta); + assert.ok('cartocss' in layer.meta); + } else { + assert.ok('cartocss' in layer.meta); + // check torque metadata at least match in number + var torqueLayers = mapConfig.layers.filter(function(layer) { return layer.type === 'torque'; }); + if (torqueLayers.length) { + assert.equal(Object.keys(layergroup.metadata.torque).length, torqueLayers.length); + } + } + }); + + testClient.drain(done); + }); + }); + } + + var cartocssVersion = '2.3.0'; + var cartocss = '#layer { line-width:16; }'; + var sql = "select 1 as i, st_setsrid('LINESTRING(0 0, 1 0)'::geometry, 4326) as the_geom, st_setsrid('LINESTRING(0 0, 1 0)'::geometry, 3857) as the_geom_webmercator"; + var sqlWadus = "select 1 as wadus, st_setsrid('LINESTRING(0 0, 1 0)'::geometry, 4326) as the_geom, st_setsrid('LINESTRING(0 0, 1 0)'::geometry, 3857) as the_geom_webmercator"; + + var httpLayer = { + type: 'http', + options: { + urlTemplate: 'http://{s}.basemaps.cartocdn.com/dark_nolabels/{z}/{x}/{y}.png', + subdomains: ['a','b','c'] + } + }; + + var torqueLayer = { + type: 'torque', + options: { + sql: "select 1 id, '1970-01-02'::date d, 'POINT(0 0)'::geometry the_geom_webmercator", + cartocss: [ + "Map {", + "-torque-frame-count:2;", + "-torque-resolution:3;", + "-torque-time-attribute:d;", + "-torque-aggregation-function:'count(id)';", + "}" + ].join(' '), + cartocss_version: '2.0.1' + } + }; + + var mapnikLayer = { + type: 'mapnik', + options: { + sql: sql, + cartocss_version: cartocssVersion, + cartocss: cartocss + } + }; + + var mapnikInteractivityLayer = { + type: 'mapnik', + options: { + sql: sql, + cartocss_version: cartocssVersion, + cartocss: cartocss, + interactivity: 'i' + } + }; + + var cartodbLayer = { + type: 'cartodb', + options: { + sql: sql, + cartocss_version: cartocssVersion, + cartocss: cartocss + } + }; + + var cartodbInteractivityLayer = { + type: 'cartodb', + options: { + sql: sql, + cartocss_version: cartocssVersion, + cartocss: cartocss, + interactivity: 'i' + } + }; + + var cartodbWadusInteractivityLayer = { + type: 'cartodb', + options: { + sql: sqlWadus, + cartocss_version: cartocssVersion, + cartocss: cartocss, + interactivity: 'wadus' + } + }; + + var noTypeLayer = { + options: { + sql: sql, + cartocss_version: cartocssVersion, + cartocss: cartocss + } + }; + + var noTypeInteractivityLayer = { + options: { + sql: sql, + cartocss_version: cartocssVersion, + cartocss: cartocss, + interactivity: 'i' + } + }; + + var testScenarios = [ + { + desc: 'one layer, no interactivity', + layers: [cartodbLayer] + }, + { + desc: 'two layers, different interactivity columns', + layers: [ + cartodbWadusInteractivityLayer, + cartodbInteractivityLayer + ] + }, + { + desc: 'torque + interactivity layers', + layers: [ + torqueLayer, + cartodbWadusInteractivityLayer, + cartodbInteractivityLayer + ] + }, + { + desc: 'interactivity + torque + interactivity', + layers: [ + cartodbInteractivityLayer, + torqueLayer, + cartodbInteractivityLayer + ] + }, + { + desc: 'http + interactivity + torque + no interactivity + torque + interactivity', + layers: [ + httpLayer, + cartodbInteractivityLayer, + torqueLayer, + cartodbLayer, + torqueLayer, + cartodbWadusInteractivityLayer + ] + }, + { + desc: 'mapnik type – two layers, interactivity mix', + layers: [ + mapnikLayer, + mapnikInteractivityLayer + ] + }, + { + desc: 'mapnik type – http + interactivity + torque + interactivity', + layers: [ + httpLayer, + mapnikInteractivityLayer, + torqueLayer, + cartodbInteractivityLayer + ] + }, + { + desc: 'no type – two layers, interactivity mix', + layers: [ + noTypeLayer, + noTypeInteractivityLayer + ] + }, + { + desc: 'no type – http + interactivity + torque + interactivity', + layers: [ + httpLayer, + noTypeInteractivityLayer, + torqueLayer, + noTypeInteractivityLayer + ] + } + ]; + + testScenarios.forEach(testLayerMetadataStats); + +}); diff --git a/test/support/sql/windshaft.test.sql b/test/support/sql/windshaft.test.sql index eb495028..91484950 100644 --- a/test/support/sql/windshaft.test.sql +++ b/test/support/sql/windshaft.test.sql @@ -649,3 +649,5 @@ CREATE OR REPLACE FUNCTION cdb_crankshaft.CDB_KMeans(query text, no_clusters int END; $$ LANGUAGE plpgsql; GRANT ALL ON FUNCTION cdb_crankshaft.CDB_KMeans(text, integer, integer) TO :TESTUSER; + +ANALYZE;