Merge remote-tracking branch 'origin/master' into new_querytables_library
This commit is contained in:
commit
dcf156ba21
@ -16,10 +16,6 @@ Make sure that you have the requirements needed. These are
|
||||
- CartoDB 0.9.5+ (for `CDB_QueryTables`)
|
||||
- Varnish (http://www.varnish-cache.org)
|
||||
|
||||
- For running the testsuite
|
||||
- ImageMagick (http://www.imagemagick.org)
|
||||
|
||||
|
||||
On Ubuntu 14.04 the dependencies can be installed with
|
||||
|
||||
```shell
|
||||
|
7
NEWS.md
7
NEWS.md
@ -1,9 +1,14 @@
|
||||
# Changelog
|
||||
|
||||
## 2.25.3
|
||||
|
||||
|
||||
## 2.25.2
|
||||
|
||||
Released 2016-mm-dd
|
||||
Released 2016-02-22
|
||||
|
||||
Bug fixes:
|
||||
- Correct URLs for widgets in named maps #381
|
||||
|
||||
|
||||
## 2.25.1
|
||||
|
@ -184,6 +184,8 @@ MapController.prototype.create = function(req, res, prepareConfigFn) {
|
||||
if (err) {
|
||||
self.sendError(req, res, err, 'ANONYMOUS LAYERGROUP');
|
||||
} else {
|
||||
addWidgetsUrl(req.context.user, layergroup);
|
||||
|
||||
res.set('X-Layergroup-Id', layergroup.layergroupid);
|
||||
self.send(req, res, layergroup, 200);
|
||||
}
|
||||
@ -257,6 +259,8 @@ MapController.prototype.instantiateTemplate = function(req, res, prepareParamsFn
|
||||
var templateHash = self.templateMaps.fingerPrint(mapConfigProvider.template).substring(0, 8);
|
||||
layergroup.layergroupid = cdbuser + '@' + templateHash + '@' + layergroup.layergroupid;
|
||||
|
||||
addWidgetsUrl(req.context.user, layergroup);
|
||||
|
||||
res.set('X-Layergroup-Id', layergroup.layergroupid);
|
||||
self.surrogateKeysCache.tag(res, new NamedMapsCacheEntry(cdbuser, mapConfigProvider.getTemplateName()));
|
||||
|
||||
|
2
npm-shrinkwrap.json
generated
2
npm-shrinkwrap.json
generated
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "windshaft-cartodb",
|
||||
"version": "2.25.2",
|
||||
"version": "2.25.3",
|
||||
"dependencies": {
|
||||
"body-parser": {
|
||||
"version": "1.14.2",
|
||||
|
@ -1,7 +1,7 @@
|
||||
{
|
||||
"private": true,
|
||||
"name": "windshaft-cartodb",
|
||||
"version": "2.25.2",
|
||||
"version": "2.25.3",
|
||||
"description": "A map tile server for CartoDB",
|
||||
"keywords": [
|
||||
"cartodb"
|
||||
|
@ -292,7 +292,8 @@ describe('render limits', function() {
|
||||
if (err) {
|
||||
done(err);
|
||||
}
|
||||
assert.imageEqualsFile(res.body, './test/fixtures/render-timeout-fallback.png', 25,
|
||||
var referenceImagePath = './test/fixtures/render-timeout-fallback.png';
|
||||
assert.imageBufferIsSimilarToFile(res.body, referenceImagePath, 25,
|
||||
function(imgErr/*, similarity*/) {
|
||||
done(imgErr);
|
||||
}
|
||||
|
@ -122,7 +122,7 @@ describe(suiteName, function() {
|
||||
' WHERE m.tabname = any ((SELECT tablenames from querytables)::regclass[])');
|
||||
}
|
||||
|
||||
assert.imageEqualsFile(res.body, 'test/fixtures/test_table_0_0_0_multilayer1.png',
|
||||
assert.imageBufferIsSimilarToFile(res.body, 'test/fixtures/test_table_0_0_0_multilayer1.png',
|
||||
IMAGE_EQUALS_HIGHER_TOLERANCE_PER_MIL, function(err/*, similarity*/) {
|
||||
next(err);
|
||||
}
|
||||
@ -190,38 +190,50 @@ describe(suiteName, function() {
|
||||
});
|
||||
|
||||
|
||||
it("should include serverMedata in the response", function(done) {
|
||||
global.environment.serverMetadata = { cdn_url : { http:'test', https: 'tests' } };
|
||||
var layergroup = {
|
||||
version: '1.0.0',
|
||||
layers: [
|
||||
{ options: {
|
||||
sql: 'select cartodb_id, ST_Translate(the_geom_webmercator, 5e6, 0) as the_geom_webmercator' +
|
||||
' from test_table limit 2',
|
||||
cartocss: '#layer { marker-fill:red; marker-width:32; marker-allow-overlap:true; }',
|
||||
cartocss_version: '2.0.1'
|
||||
} }
|
||||
]
|
||||
};
|
||||
describe('server-metadata', function() {
|
||||
var serverMetadata;
|
||||
beforeEach(function() {
|
||||
serverMetadata = global.environment.serverMetadata;
|
||||
global.environment.serverMetadata = { cdn_url : { http:'test', https: 'tests' } };
|
||||
});
|
||||
|
||||
afterEach(function() {
|
||||
global.environment.serverMetadata = serverMetadata;
|
||||
});
|
||||
|
||||
it("should include serverMedata in the response", function(done) {
|
||||
var layergroup = {
|
||||
version: '1.0.0',
|
||||
layers: [
|
||||
{ options: {
|
||||
sql: 'select cartodb_id, ST_Translate(the_geom_webmercator, 5e6, 0) as the_geom_webmercator' +
|
||||
' from test_table limit 2',
|
||||
cartocss: '#layer { marker-fill:red; marker-width:32; marker-allow-overlap:true; }',
|
||||
cartocss_version: '2.0.1'
|
||||
} }
|
||||
]
|
||||
};
|
||||
|
||||
step(
|
||||
function do_create_get()
|
||||
{
|
||||
var next = this;
|
||||
assert.response(server, {
|
||||
url: layergroup_url + '?config=' + encodeURIComponent(JSON.stringify(layergroup)),
|
||||
method: 'GET',
|
||||
headers: {host: 'localhost'}
|
||||
}, {}, function(res, err) { next(err, res); });
|
||||
},
|
||||
function do_check_create(err, res) {
|
||||
var parsed = JSON.parse(res.body);
|
||||
keysToDelete['map_cfg|' + LayergroupToken.parse(parsed.layergroupid).token] = 0;
|
||||
keysToDelete['user:localhost:mapviews:global'] = 5;
|
||||
assert.ok(_.isEqual(parsed.cdn_url, global.environment.serverMetadata.cdn_url));
|
||||
done();
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
step(
|
||||
function do_create_get()
|
||||
{
|
||||
var next = this;
|
||||
assert.response(server, {
|
||||
url: layergroup_url + '?config=' + encodeURIComponent(JSON.stringify(layergroup)),
|
||||
method: 'GET',
|
||||
headers: {host: 'localhost'}
|
||||
}, {}, function(res, err) { next(err, res); });
|
||||
},
|
||||
function do_check_create(err, res) {
|
||||
var parsed = JSON.parse(res.body);
|
||||
keysToDelete['map_cfg|' + LayergroupToken.parse(parsed.layergroupid).token] = 0;
|
||||
keysToDelete['user:localhost:mapviews:global'] = 5;
|
||||
assert.ok(_.isEqual(parsed.cdn_url, global.environment.serverMetadata.cdn_url));
|
||||
done();
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
|
||||
@ -392,7 +404,8 @@ describe(suiteName, function() {
|
||||
' WHERE m.tabname = any ((SELECT tablenames from querytables)::regclass[])');
|
||||
}
|
||||
|
||||
assert.imageEqualsFile(res.body, 'test/fixtures/test_multilayer_bbox.png', IMAGE_EQUALS_TOLERANCE_PER_MIL,
|
||||
var referenceImagePath = 'test/fixtures/test_multilayer_bbox.png';
|
||||
assert.imageBufferIsSimilarToFile(res.body, referenceImagePath, IMAGE_EQUALS_TOLERANCE_PER_MIL,
|
||||
function(err/*, similarity*/) {
|
||||
next(err);
|
||||
});
|
||||
@ -431,7 +444,8 @@ describe(suiteName, function() {
|
||||
' WHERE m.tabname = any ((SELECT tablenames from querytables)::regclass[])');
|
||||
}
|
||||
|
||||
assert.imageEqualsFile(res.body, 'test/fixtures/test_multilayer_bbox.png', IMAGE_EQUALS_TOLERANCE_PER_MIL,
|
||||
var referenceImagePath = 'test/fixtures/test_multilayer_bbox.png';
|
||||
assert.imageBufferIsSimilarToFile(res.body, referenceImagePath, IMAGE_EQUALS_TOLERANCE_PER_MIL,
|
||||
function(err/*, similarity*/) {
|
||||
next(err);
|
||||
});
|
||||
@ -1007,7 +1021,7 @@ describe(suiteName, function() {
|
||||
}, {}, function(res) {
|
||||
assert.equal(res.statusCode, 200, res.body);
|
||||
assert.equal(res.headers['content-type'], "image/png");
|
||||
assert.imageEqualsFile(res.body, windshaft_fixtures + '/test_default_mapnik_point.png',
|
||||
assert.imageBufferIsSimilarToFile(res.body, windshaft_fixtures + '/test_default_mapnik_point.png',
|
||||
IMAGE_EQUALS_TOLERANCE_PER_MIL, function(err/*, similarity*/) {
|
||||
next(err);
|
||||
}
|
||||
|
@ -30,7 +30,8 @@ describe('overviews_queries', function() {
|
||||
if (err) {
|
||||
return done(err);
|
||||
}
|
||||
assert.imageEqualsFile(tile.body, './test/fixtures/' + fixture, IMAGE_EQUALS_TOLERANCE_PER_MIL, done);
|
||||
var referenceImagePath = './test/fixtures/' + fixture;
|
||||
assert.imageBufferIsSimilarToFile(tile.body, referenceImagePath, IMAGE_EQUALS_TOLERANCE_PER_MIL, done);
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -95,10 +95,12 @@ 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.imageEqualsFile(res.body, blendPngFixture(zxy), IMAGE_TOLERANCE_PER_MIL, function(err) {
|
||||
assert.ok(!err);
|
||||
done();
|
||||
});
|
||||
assert.imageBufferIsSimilarToFile(res.body, blendPngFixture(zxy), IMAGE_TOLERANCE_PER_MIL,
|
||||
function(err) {
|
||||
assert.ok(!err);
|
||||
done();
|
||||
}
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -156,10 +156,12 @@ describe('blend layer filtering', function() {
|
||||
|
||||
it('should filter on ' + layerFilter + '/1/0/0.png', function (done) {
|
||||
testClient.getTileLayer(mapConfig, tileRequest, function(err, res) {
|
||||
assert.imageEqualsFile(res.body, blendPngFixture(filteredLayers), IMG_TOLERANCE_PER_MIL, function(err) {
|
||||
assert.ok(!err);
|
||||
done();
|
||||
});
|
||||
assert.imageBufferIsSimilarToFile(res.body, blendPngFixture(filteredLayers), IMG_TOLERANCE_PER_MIL,
|
||||
function(err) {
|
||||
assert.ok(!err);
|
||||
done();
|
||||
}
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -111,10 +111,12 @@ 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.imageEqualsFile(res.body, blendPngFixture(filteredLayers), IMG_TOLERANCE_PER_MIL, function(err) {
|
||||
assert.ok(!err, err);
|
||||
done();
|
||||
});
|
||||
assert.imageBufferIsSimilarToFile(res.body, blendPngFixture(filteredLayers), IMG_TOLERANCE_PER_MIL,
|
||||
function(err) {
|
||||
assert.ok(!err, err);
|
||||
done();
|
||||
}
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -57,7 +57,8 @@ describe('external resources', function() {
|
||||
if (err) {
|
||||
return done(err);
|
||||
}
|
||||
assert.imageEqualsFile(res.body, './test/fixtures/' + fixture, IMAGE_EQUALS_TOLERANCE_PER_MIL, done);
|
||||
var referenceImagePath = './test/fixtures/' + fixture;
|
||||
assert.imageBufferIsSimilarToFile(res.body, referenceImagePath, IMAGE_EQUALS_TOLERANCE_PER_MIL, done);
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -84,11 +84,13 @@ describe.skip('render limits', function() {
|
||||
testClient.withLayergroup(slowQueryMapConfig, options, function(err, requestTile, finish) {
|
||||
var tileUrl = '/0/0/0.png';
|
||||
requestTile(tileUrl, options, function(err, res) {
|
||||
assert.imageEqualsFile(res.body, fixtureImage, IMAGE_EQUALS_TOLERANCE_PER_MIL, function(err) {
|
||||
finish(function(finishErr) {
|
||||
done(err || finishErr);
|
||||
});
|
||||
});
|
||||
assert.imageBufferIsSimilarToFile(res.body, fixtureImage, IMAGE_EQUALS_TOLERANCE_PER_MIL,
|
||||
function(err) {
|
||||
finish(function(finishErr) {
|
||||
done(err || finishErr);
|
||||
});
|
||||
}
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -117,7 +117,8 @@ describe('multilayer', function() {
|
||||
assert.equal(res.statusCode, 200, res.body);
|
||||
assert.equal(res.headers['content-type'], "image/png");
|
||||
checkCORSHeaders(res);
|
||||
assert.imageEqualsFile(res.body, './test/fixtures/test_bigpoint_red.png', IMAGE_EQUALS_TOLERANCE_PER_MIL,
|
||||
var referenceImagePath = './test/fixtures/test_bigpoint_red.png';
|
||||
assert.imageBufferIsSimilarToFile(res.body, referenceImagePath, IMAGE_EQUALS_TOLERANCE_PER_MIL,
|
||||
function(err) {
|
||||
next(err);
|
||||
});
|
||||
@ -191,7 +192,8 @@ describe('multilayer', function() {
|
||||
}, {}, function(res) {
|
||||
assert.equal(res.statusCode, 200, res.body);
|
||||
assert.equal(res.headers['content-type'], "image/png");
|
||||
assert.imageEqualsFile(res.body, './test/acceptance/ported/fixtures/test_table_0_0_0_multilayer1.png',
|
||||
var referenceImagePath = './test/acceptance/ported/fixtures/test_table_0_0_0_multilayer1.png';
|
||||
assert.imageBufferIsSimilarToFile(res.body, referenceImagePath,
|
||||
IMAGE_EQUALS_TOLERANCE_PER_MIL, function(err) {
|
||||
next(err);
|
||||
});
|
||||
@ -302,7 +304,8 @@ describe('multilayer', function() {
|
||||
}, {}, function(res) {
|
||||
assert.equal(res.statusCode, 200, res.body);
|
||||
assert.equal(res.headers['content-type'], "image/png");
|
||||
assert.imageEqualsFile(res.body, './test/acceptance/ported/fixtures/test_table_0_0_0_multilayer1.png',
|
||||
var referenceImagePath = './test/acceptance/ported/fixtures/test_table_0_0_0_multilayer1.png';
|
||||
assert.imageBufferIsSimilarToFile(res.body, referenceImagePath,
|
||||
IMAGE_EQUALS_TOLERANCE_PER_MIL, function(err) {
|
||||
next(err);
|
||||
});
|
||||
@ -425,7 +428,8 @@ describe('multilayer', function() {
|
||||
}, {}, function(res) {
|
||||
assert.equal(res.statusCode, 200, res.body);
|
||||
assert.equal(res.headers['content-type'], "image/png");
|
||||
assert.imageEqualsFile(res.body, './test/acceptance/ported/fixtures/test_table_0_0_0_multilayer1.png',
|
||||
var referenceImagePath = './test/acceptance/ported/fixtures/test_table_0_0_0_multilayer1.png';
|
||||
assert.imageBufferIsSimilarToFile(res.body, referenceImagePath,
|
||||
IMAGE_EQUALS_TOLERANCE_PER_MIL, function(err) {
|
||||
next(err);
|
||||
});
|
||||
@ -541,7 +545,8 @@ describe('multilayer', function() {
|
||||
}, {}, function(res) {
|
||||
assert.equal(res.statusCode, 200, res.body);
|
||||
assert.equal(res.headers['content-type'], "image/png");
|
||||
assert.imageEqualsFile(res.body, './test/acceptance/ported/fixtures/test_table_0_0_0_multilayer1.png',
|
||||
var referenceImagePath = './test/acceptance/ported/fixtures/test_table_0_0_0_multilayer1.png';
|
||||
assert.imageBufferIsSimilarToFile(res.body, referenceImagePath,
|
||||
IMAGE_EQUALS_TOLERANCE_PER_MIL, function(err) {
|
||||
next(err);
|
||||
});
|
||||
@ -727,7 +732,8 @@ describe('multilayer', function() {
|
||||
}, {}, function(res) {
|
||||
assert.equal(res.statusCode, 200, res.body);
|
||||
assert.equal(res.headers['content-type'], "image/png");
|
||||
assert.imageEqualsFile(res.body, './test/acceptance/ported/fixtures/test_table_0_0_0_multilayer2.png',
|
||||
var referenceImagePath = './test/acceptance/ported/fixtures/test_table_0_0_0_multilayer2.png';
|
||||
assert.imageBufferIsSimilarToFile(res.body, referenceImagePath,
|
||||
IMAGE_EQUALS_TOLERANCE_PER_MIL, function(err) {
|
||||
next(err);
|
||||
});
|
||||
@ -761,7 +767,8 @@ describe('multilayer', function() {
|
||||
}, {}, function(res) {
|
||||
assert.equal(res.statusCode, 200, res.body);
|
||||
assert.equal(res.headers['content-type'], "image/png");
|
||||
assert.imageEqualsFile(res.body, './test/acceptance/ported/fixtures/test_table_0_0_0_multilayer3.png',
|
||||
var referenceImagePath = './test/acceptance/ported/fixtures/test_table_0_0_0_multilayer3.png';
|
||||
assert.imageBufferIsSimilarToFile(res.body, referenceImagePath,
|
||||
IMAGE_EQUALS_TOLERANCE_PER_MIL, function(err) {
|
||||
next(err);
|
||||
});
|
||||
@ -856,7 +863,8 @@ describe('multilayer', function() {
|
||||
}, {}, function(res) {
|
||||
assert.equal(res.statusCode, 200, res.body);
|
||||
assert.equal(res.headers['content-type'], "image/png");
|
||||
assert.imageEqualsFile(res.body, './test/acceptance/ported/fixtures/test_table_0_0_0_multilayer4.png',
|
||||
var referenceImagePath = './test/acceptance/ported/fixtures/test_table_0_0_0_multilayer4.png';
|
||||
assert.imageBufferIsSimilarToFile(res.body, referenceImagePath,
|
||||
IMAGE_EQUALS_TOLERANCE_PER_MIL, function(err) {
|
||||
next(err);
|
||||
});
|
||||
@ -1259,7 +1267,7 @@ describe('multilayer', function() {
|
||||
assert.equal(res.statusCode, 200, res.body);
|
||||
assert.equal(res.headers['content-type'], "image/png");
|
||||
checkCORSHeaders(res);
|
||||
assert.imageEqualsFile(res.body, './test/fixtures/test_bigpoint_red.png',
|
||||
assert.imageBufferIsSimilarToFile(res.body, './test/fixtures/test_bigpoint_red.png',
|
||||
IMAGE_EQUALS_TOLERANCE_PER_MIL, function(err) {
|
||||
next(err);
|
||||
});
|
||||
|
@ -87,7 +87,7 @@ describe('raster', function() {
|
||||
assert.equal(res.statusCode, 200, res.body);
|
||||
assert.deepEqual(res.headers['content-type'], "image/png");
|
||||
var next = this;
|
||||
assert.imageEqualsFile(res.body,
|
||||
assert.imageBufferIsSimilarToFile(res.body,
|
||||
'./test/fixtures/raster_gray_rect.png',
|
||||
IMAGE_EQUALS_TOLERANCE_PER_MIL, function(err) {
|
||||
try {
|
||||
|
@ -34,7 +34,9 @@ describe('server_gettile', function() {
|
||||
if (err) {
|
||||
return done(err);
|
||||
}
|
||||
assert.imageEqualsFile(res.body, './test/fixtures/' + fixture, IMAGE_EQUALS_TOLERANCE_PER_MIL, done);
|
||||
assert.imageBufferIsSimilarToFile(
|
||||
res.body, './test/fixtures/' + fixture, IMAGE_EQUALS_TOLERANCE_PER_MIL, done
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
@ -113,12 +115,13 @@ describe('server_gettile', function() {
|
||||
assert.ok(res.headers.hasOwnProperty('x-windshaft-cache'), "Did not hit renderer cache on second time");
|
||||
assert.ok(res.headers['x-windshaft-cache'] >= 0);
|
||||
|
||||
assert.imageEqualsFile(res.body, imageFixture, IMAGE_EQUALS_TOLERANCE_PER_MIL, function(err) {
|
||||
|
||||
finish(function(finishErr) {
|
||||
done(err || finishErr);
|
||||
});
|
||||
});
|
||||
assert.imageBufferIsSimilarToFile(res.body, imageFixture, IMAGE_EQUALS_TOLERANCE_PER_MIL,
|
||||
function(err) {
|
||||
finish(function(finishErr) {
|
||||
done(err || finishErr);
|
||||
});
|
||||
}
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -108,7 +108,7 @@ describe('server_png8_format', function() {
|
||||
assert.equal(responsePng8.headers['content-type'], "image/png");
|
||||
bufferPng8 = responsePng8.body;
|
||||
assert.ok(bufferPng8.length < bufferPng32.length);
|
||||
assert.imageBuffersAreEqual(bufferPng32, bufferPng8, IMAGE_EQUALS_TOLERANCE_PER_MIL,
|
||||
assert.imageBuffersAreSimilar(bufferPng32, bufferPng8, IMAGE_EQUALS_TOLERANCE_PER_MIL,
|
||||
function(err, imagePaths, similarity) {
|
||||
|
||||
keysToDelete['map_cfg|' + LayergroupToken.parse(layergroupId).token] = 0;
|
||||
|
@ -83,10 +83,12 @@ 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.imageEqualsFile(res.body, torquePngFixture(zxy), IMAGE_TOLERANCE_PER_MIL, function(err) {
|
||||
assert.ok(!err);
|
||||
done();
|
||||
});
|
||||
assert.imageBufferIsSimilarToFile(res.body, torquePngFixture(zxy), IMAGE_TOLERANCE_PER_MIL,
|
||||
function(err) {
|
||||
assert.ok(!err);
|
||||
done();
|
||||
}
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -107,10 +107,12 @@ 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.imageEqualsFile(res.body, blendPngFixture(fixtureZxy), IMG_TOLERANCE_PER_MIL, function(err) {
|
||||
assert.ok(!err);
|
||||
done();
|
||||
});
|
||||
assert.imageBufferIsSimilarToFile(res.body, blendPngFixture(fixtureZxy), IMG_TOLERANCE_PER_MIL,
|
||||
function(err) {
|
||||
assert.ok(!err);
|
||||
done();
|
||||
}
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -313,51 +313,63 @@ describe('template_api', function() {
|
||||
});
|
||||
});
|
||||
|
||||
it("instance endpoint should return server metadata", function(done){
|
||||
global.environment.serverMetadata = { cdn_url : { http:'test', https: 'tests' } };
|
||||
var tmpl = _.clone(template_acceptance1);
|
||||
tmpl.name = "rambotemplate2";
|
||||
describe('server-metadata', function() {
|
||||
var serverMetadata;
|
||||
beforeEach(function() {
|
||||
serverMetadata = global.environment.serverMetadata;
|
||||
global.environment.serverMetadata = { cdn_url : { http:'test', https: 'tests' } };
|
||||
});
|
||||
|
||||
step(function postTemplate1() {
|
||||
var next = this;
|
||||
var post_request = {
|
||||
url: '/api/v1/map/named?api_key=1234',
|
||||
method: 'POST',
|
||||
headers: {host: 'localhost', 'Content-Type': 'application/json' },
|
||||
data: JSON.stringify(tmpl)
|
||||
};
|
||||
assert.response(server, post_request, {}, function(res) {
|
||||
next(null, res);
|
||||
});
|
||||
},
|
||||
function testCORS() {
|
||||
var next = this;
|
||||
assert.response(server, {
|
||||
url: '/api/v1/map/named/' + tmpl.name,
|
||||
method: 'POST',
|
||||
headers: {host: 'localhost', 'Content-Type': 'application/json' }
|
||||
},{
|
||||
status: 200
|
||||
}, function(res) {
|
||||
var parsed = JSON.parse(res.body);
|
||||
keysToDelete['map_cfg|' + LayergroupToken.parse(parsed.layergroupid).token] = 0;
|
||||
keysToDelete['user:localhost:mapviews:global'] = 5;
|
||||
assert.ok(_.isEqual(parsed.cdn_url, global.environment.serverMetadata.cdn_url));
|
||||
next(null);
|
||||
});
|
||||
},
|
||||
function deleteTemplate(err) {
|
||||
assert.ifError(err);
|
||||
var del_request = {
|
||||
url: '/api/v1/map/named/' + tmpl.name + '?api_key=1234',
|
||||
method: 'DELETE',
|
||||
headers: {host: 'localhost', 'Content-Type': 'application/json' }
|
||||
};
|
||||
assert.response(server, del_request, {}, function() {
|
||||
done();
|
||||
});
|
||||
}
|
||||
);
|
||||
afterEach(function() {
|
||||
global.environment.serverMetadata = serverMetadata;
|
||||
});
|
||||
|
||||
|
||||
it("instance endpoint should return server metadata", function(done){
|
||||
var tmpl = _.clone(template_acceptance1);
|
||||
tmpl.name = "rambotemplate2";
|
||||
|
||||
step(function postTemplate1() {
|
||||
var next = this;
|
||||
var post_request = {
|
||||
url: '/api/v1/map/named?api_key=1234',
|
||||
method: 'POST',
|
||||
headers: {host: 'localhost', 'Content-Type': 'application/json' },
|
||||
data: JSON.stringify(tmpl)
|
||||
};
|
||||
assert.response(server, post_request, {}, function(res) {
|
||||
next(null, res);
|
||||
});
|
||||
},
|
||||
function testCORS() {
|
||||
var next = this;
|
||||
assert.response(server, {
|
||||
url: '/api/v1/map/named/' + tmpl.name,
|
||||
method: 'POST',
|
||||
headers: {host: 'localhost', 'Content-Type': 'application/json' }
|
||||
},{
|
||||
status: 200
|
||||
}, function(res) {
|
||||
var parsed = JSON.parse(res.body);
|
||||
keysToDelete['map_cfg|' + LayergroupToken.parse(parsed.layergroupid).token] = 0;
|
||||
keysToDelete['user:localhost:mapviews:global'] = 5;
|
||||
assert.ok(_.isEqual(parsed.cdn_url, global.environment.serverMetadata.cdn_url));
|
||||
next(null);
|
||||
});
|
||||
},
|
||||
function deleteTemplate(err) {
|
||||
assert.ifError(err);
|
||||
var del_request = {
|
||||
url: '/api/v1/map/named/' + tmpl.name + '?api_key=1234',
|
||||
method: 'DELETE',
|
||||
headers: {host: 'localhost', 'Content-Type': 'application/json' }
|
||||
};
|
||||
assert.response(server, del_request, {}, function() {
|
||||
done();
|
||||
});
|
||||
}
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
|
@ -1,6 +1,9 @@
|
||||
var assert = require('../../support/assert');
|
||||
var step = require('step');
|
||||
|
||||
var url = require('url');
|
||||
var queue = require('queue-async');
|
||||
|
||||
var helper = require('../../support/test_helper');
|
||||
|
||||
var CartodbWindshaft = require('../../../lib/cartodb/server');
|
||||
@ -15,6 +18,7 @@ describe('named-maps widgets', function() {
|
||||
var widgetsTemplateName = 'widgets-template';
|
||||
|
||||
var layergroupid;
|
||||
var layergroup;
|
||||
var keysToDelete;
|
||||
|
||||
beforeEach(function(done) {
|
||||
@ -33,6 +37,13 @@ describe('named-maps widgets', function() {
|
||||
cartocss: '#layer { marker-fill: blue; }',
|
||||
cartocss_version: '2.3.0',
|
||||
widgets: {
|
||||
pop_max_formula_sum: {
|
||||
type: 'formula',
|
||||
options: {
|
||||
column: 'pop_max',
|
||||
operation: 'sum'
|
||||
}
|
||||
},
|
||||
country_places_count: {
|
||||
type: 'aggregation',
|
||||
options: {
|
||||
@ -105,12 +116,11 @@ describe('named-maps widgets', function() {
|
||||
function fetchTile(err, res) {
|
||||
assert.ifError(err);
|
||||
|
||||
var parsed = JSON.parse(res.body);
|
||||
assert.ok(
|
||||
parsed.hasOwnProperty('layergroupid'), "Missing 'layergroupid' from response body: " + res.body);
|
||||
layergroupid = parsed.layergroupid;
|
||||
layergroup = JSON.parse(res.body);
|
||||
assert.ok(layergroup.hasOwnProperty('layergroupid'), "Missing 'layergroupid' from: " + res.body);
|
||||
layergroupid = layergroup.layergroupid;
|
||||
|
||||
keysToDelete['map_cfg|' + LayergroupToken.parse(parsed.layergroupid).token] = 0;
|
||||
keysToDelete['map_cfg|' + LayergroupToken.parse(layergroup.layergroupid).token] = 0;
|
||||
keysToDelete['user:localhost:mapviews:global'] = 5;
|
||||
|
||||
return done();
|
||||
@ -171,6 +181,49 @@ describe('named-maps widgets', function() {
|
||||
);
|
||||
}
|
||||
|
||||
it('should be able to retrieve widgets from all URLs', function(done) {
|
||||
var widgetsPaths = layergroup.metadata.layers.reduce(function(paths, layer) {
|
||||
var widgets = layer.widgets || {};
|
||||
Object.keys(widgets).forEach(function(widget) {
|
||||
paths.push(url.parse(widgets[widget].url.http).path);
|
||||
});
|
||||
|
||||
return paths;
|
||||
}, []);
|
||||
|
||||
var widgetsQueue = queue(widgetsPaths.length);
|
||||
|
||||
widgetsPaths.forEach(function(path) {
|
||||
widgetsQueue.defer(function(path, done) {
|
||||
assert.response(
|
||||
server,
|
||||
{
|
||||
url: path,
|
||||
method: 'GET',
|
||||
headers: {
|
||||
host: username
|
||||
}
|
||||
},
|
||||
{
|
||||
status: 200
|
||||
},
|
||||
function(res, err) {
|
||||
if (err) {
|
||||
return done(err);
|
||||
}
|
||||
var parsedBody = JSON.parse(res.body);
|
||||
return done(null, parsedBody);
|
||||
}
|
||||
);
|
||||
}, path);
|
||||
});
|
||||
|
||||
widgetsQueue.awaitAll(function(err, results) {
|
||||
assert.equal(results.length, 3);
|
||||
done(err);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
it("should retrieve aggregation", function(done) {
|
||||
getWidget('country_places_count', function(err, response, aggregation) {
|
||||
|
@ -1,7 +1,6 @@
|
||||
// Cribbed from the ever prolific Konstantin Kaefer
|
||||
// https://github.com/mapbox/tilelive-mapnik/blob/master/test/support/assert.js
|
||||
|
||||
var exec = require('child_process').exec;
|
||||
var fs = require('fs');
|
||||
var path = require('path');
|
||||
var util = require('util');
|
||||
@ -13,7 +12,7 @@ var request = require('request');
|
||||
var assert = module.exports = exports = require('assert');
|
||||
|
||||
/**
|
||||
* Takes an image data as an input and an image path and compare them using ImageMagick fuzz algorithm, if case the
|
||||
* Takes an image data as an input and an image path and compare them using mapnik.Image.compare mechanism, in case the
|
||||
* similarity is not within the tolerance limit it will callback with an error.
|
||||
*
|
||||
* @param buffer The image data to compare from
|
||||
@ -22,70 +21,39 @@ var assert = module.exports = exports = require('assert');
|
||||
* @param {function} callback Will call to home with null in case there is no error, otherwise with the error itself
|
||||
* @see FUZZY in http://www.imagemagick.org/script/command-line-options.php#metric
|
||||
*/
|
||||
assert.imageEqualsFile = function(buffer, referenceImageRelativeFilePath, tolerance, callback) {
|
||||
assert.imageBufferIsSimilarToFile = function(buffer, referenceImageRelativeFilePath, tolerance, callback) {
|
||||
callback = callback || function(err) { assert.ifError(err); };
|
||||
var referenceImageFilePath = path.resolve(referenceImageRelativeFilePath),
|
||||
testImageFilePath = createImageFromBuffer(buffer, 'test');
|
||||
|
||||
imageFilesAreEqual(testImageFilePath, referenceImageFilePath, tolerance, function(err) {
|
||||
fs.unlinkSync(testImageFilePath);
|
||||
var referenceImageFilePath = path.resolve(referenceImageRelativeFilePath);
|
||||
var referenceImageBuffer = fs.readFileSync(referenceImageFilePath, { encoding: null });
|
||||
|
||||
assert.imageBuffersAreSimilar(buffer, referenceImageBuffer, tolerance, callback);
|
||||
};
|
||||
|
||||
assert.imageBuffersAreSimilar = function(bufferA, bufferB, tolerance, callback) {
|
||||
var testImage = mapnik.Image.fromBytes(Buffer.isBuffer(bufferA) ? bufferA : new Buffer(bufferA, 'binary'));
|
||||
var referenceImage = mapnik.Image.fromBytes(Buffer.isBuffer(bufferB) ? bufferB : new Buffer(bufferB, 'binary'));
|
||||
|
||||
imagesAreSimilar(testImage, referenceImage, tolerance, callback);
|
||||
};
|
||||
|
||||
assert.imageIsSimilarToFile = function(testImage, referenceImageRelativeFilePath, tolerance, callback) {
|
||||
callback = callback || function(err) { assert.ifError(err); };
|
||||
|
||||
var referenceImageFilePath = path.resolve(referenceImageRelativeFilePath);
|
||||
|
||||
var referenceImage = mapnik.Image.fromBytes(fs.readFileSync(referenceImageFilePath, { encoding: null }));
|
||||
|
||||
imagesAreSimilar(testImage, referenceImage, tolerance, function(err) {
|
||||
if (err) {
|
||||
var testImageFilePath = randomImagePath();
|
||||
testImage.save(testImageFilePath);
|
||||
}
|
||||
callback(err);
|
||||
});
|
||||
};
|
||||
|
||||
assert.imageBuffersAreEqual = function(bufferA, bufferB, tolerance, callback) {
|
||||
var randStr = (Math.random() * 1e16).toString().substring(0, 8);
|
||||
var imageFilePathA = createImageFromBuffer(bufferA, randStr + '-a'),
|
||||
imageFilePathB = createImageFromBuffer(bufferB, randStr + '-b');
|
||||
|
||||
imageFilesAreEqual(imageFilePathA, imageFilePathB, tolerance, function(err, similarity) {
|
||||
callback(err, [imageFilePathA, imageFilePathB], similarity);
|
||||
});
|
||||
};
|
||||
|
||||
function createImageFromBuffer(buffer, nameHint) {
|
||||
var imageFilePath = path.resolve('test/results/png/image-' + nameHint + '-' + Date.now() + '.png');
|
||||
var err = fs.writeFileSync(imageFilePath, buffer, 'binary');
|
||||
assert.ifError(err);
|
||||
return imageFilePath;
|
||||
}
|
||||
|
||||
function imageFilesAreEqual(testImageFilePath, referenceImageFilePath, tolerance, callback) {
|
||||
var resultFilePath = path.resolve(util.format('/tmp/windshaft-result-%s-diff.png', Date.now()));
|
||||
var imageMagickCmd = util.format(
|
||||
'compare -metric fuzz "%s" "%s" "%s"',
|
||||
testImageFilePath, referenceImageFilePath, resultFilePath
|
||||
);
|
||||
|
||||
exec(imageMagickCmd, function(err, stdout, stderr) {
|
||||
if (err) {
|
||||
fs.unlinkSync(testImageFilePath);
|
||||
callback(err);
|
||||
} else {
|
||||
stderr = stderr.trim();
|
||||
var metrics = stderr.match(/([0-9]*) \((.*)\)/);
|
||||
if ( ! metrics ) {
|
||||
callback(new Error("No match for " + stderr));
|
||||
return;
|
||||
}
|
||||
var similarity = parseFloat(metrics[2]),
|
||||
tolerancePerMil = (tolerance / 1000);
|
||||
if (similarity > tolerancePerMil) {
|
||||
err = new Error(util.format(
|
||||
'Images %s and %s are not equal (got %d similarity, expected %d). Result %s',
|
||||
testImageFilePath, referenceImageFilePath, similarity, tolerancePerMil, resultFilePath)
|
||||
);
|
||||
err.similarity = similarity;
|
||||
callback(err, similarity);
|
||||
} else {
|
||||
fs.unlinkSync(resultFilePath);
|
||||
callback(null, similarity);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
assert.imagesAreSimilar = function(testImage, referenceImage, tolerance, callback) {
|
||||
function imagesAreSimilar(testImage, referenceImage, tolerance, callback) {
|
||||
if (testImage.width() !== referenceImage.width() || testImage.height() !== referenceImage.height()) {
|
||||
return callback(new Error('Images are not the same size'));
|
||||
}
|
||||
@ -103,27 +71,10 @@ assert.imagesAreSimilar = function(testImage, referenceImage, tolerance, callbac
|
||||
} else {
|
||||
callback(null, similarity);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
assert.imageIsSimilarToFile = function(testImage, referenceImageRelativeFilePath, tolerance, callback) {
|
||||
callback = callback || function(err) { assert.ifError(err); };
|
||||
|
||||
var referenceImageFilePath = path.resolve(referenceImageRelativeFilePath);
|
||||
|
||||
var referenceImage = mapnik.Image.fromBytes(fs.readFileSync(referenceImageFilePath, { encoding: null }));
|
||||
|
||||
assert.imagesAreSimilar(testImage, referenceImage, tolerance, function(err) {
|
||||
if (err) {
|
||||
var testImageFilePath = randomImagePath();
|
||||
testImage.save(testImageFilePath);
|
||||
}
|
||||
callback(err);
|
||||
});
|
||||
};
|
||||
|
||||
function randomImagePath(nameHint) {
|
||||
nameHint = nameHint || 'test';
|
||||
return path.resolve('test/results/png/image-' + nameHint + '-' + Date.now() + '.png');
|
||||
function randomImagePath() {
|
||||
return path.resolve('test/results/png/image-test-' + Date.now() + '.png');
|
||||
}
|
||||
|
||||
// jshint maxcomplexity:9
|
||||
|
@ -74,6 +74,14 @@ function checkSurrogateKey(res, expectedKey) {
|
||||
assert.deepEqual(keys, expectedKeys);
|
||||
}
|
||||
|
||||
var redisClient;
|
||||
|
||||
beforeEach(function() {
|
||||
if (!redisClient) {
|
||||
redisClient = redis.createClient(global.environment.redis.port);
|
||||
}
|
||||
});
|
||||
|
||||
//global afterEach to capture test suites that leave keys in redis
|
||||
afterEach(function(done) {
|
||||
|
||||
@ -110,7 +118,6 @@ afterEach(function(done) {
|
||||
}
|
||||
|
||||
Object.keys(databasesTasks).forEach(function(db) {
|
||||
var redisClient = redis.createClient(global.environment.redis.port);
|
||||
redisClient.select(db, function() {
|
||||
// Check that we start with an empty redis db
|
||||
redisClient.keys("*", function(err, keys) {
|
||||
@ -137,6 +144,7 @@ function deleteRedisKeys(keysToDelete, callback) {
|
||||
var redisClient = redis.createClient(global.environment.redis.port);
|
||||
redisClient.select(keysToDelete[k], function() {
|
||||
redisClient.del(k, function(err, deletedKeysCount) {
|
||||
redisClient.quit();
|
||||
assert.notStrictEqual(deletedKeysCount, 0, 'No KEYS deleted for: [db=' + keysToDelete[k] + ']' + k);
|
||||
taskDone(k);
|
||||
});
|
||||
|
Loading…
Reference in New Issue
Block a user