2013-02-25 22:08:28 +08:00
var assert = require ( '../support/assert' ) ;
var tests = module . exports = { } ;
var _ = require ( 'underscore' ) ;
var redis = require ( 'redis' ) ;
var querystring = require ( 'querystring' ) ;
var semver = require ( 'semver' ) ;
var mapnik = require ( 'mapnik' ) ;
var Step = require ( 'step' ) ;
2013-06-04 19:29:36 +08:00
var strftime = require ( 'strftime' ) ;
2013-03-14 01:41:37 +08:00
var SQLAPIEmu = require ( _ _dirname + '/../support/SQLAPIEmu.js' ) ;
2013-06-04 19:29:36 +08:00
var redis _stats _db = 5 ;
2013-02-25 22:08:28 +08:00
require ( _ _dirname + '/../support/test_helper' ) ;
var windshaft _fixtures = _ _dirname + '/../../node_modules/windshaft/test/fixtures' ;
var CartodbWindshaft = require ( _ _dirname + '/../../lib/cartodb/cartodb_windshaft' ) ;
var serverOptions = require ( _ _dirname + '/../../lib/cartodb/server_options' ) ;
var server = new CartodbWindshaft ( serverOptions ) ;
server . setMaxListeners ( 0 ) ;
suite ( 'multilayer' , function ( ) {
var redis _client = redis . createClient ( global . environment . redis . port ) ;
2013-03-13 18:55:57 +08:00
var sqlapi _server ;
2013-04-04 19:15:50 +08:00
var expected _last _updated _epoch = 1234567890123 ; // this is hard-coded into SQLAPIEmu
var expected _last _updated = new Date ( expected _last _updated _epoch ) . toISOString ( ) ;
2013-02-25 22:08:28 +08:00
2013-03-13 18:55:57 +08:00
suiteSetup ( function ( done ) {
2013-03-14 01:41:37 +08:00
sqlapi _server = new SQLAPIEmu ( global . environment . sqlapi . port , done ) ;
2013-02-25 22:08:28 +08:00
} ) ;
2013-04-02 18:24:03 +08:00
test ( "layergroup with 2 layers, each with its style" , function ( done ) {
2013-02-25 22:08:28 +08:00
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; }' ,
2013-04-04 19:15:50 +08:00
cartocss _version : '2.0.1' ,
interactivity : 'cartodb_id'
2013-02-25 22:08:28 +08:00
} } ,
{ options : {
sql : 'select cartodb_id, ST_Translate(the_geom_webmercator, -5e6, 0) as the_geom_webmercator from test_table limit 2 offset 2' ,
cartocss : '#layer { marker-fill:blue; marker-allow-overlap:true; }' ,
2013-04-04 19:15:50 +08:00
cartocss _version : '2.0.2' ,
interactivity : 'cartodb_id'
2013-02-25 22:08:28 +08:00
} }
]
} ;
2013-04-04 19:15:50 +08:00
var expected _token = "e34dd7e235138a062f8ba7ad051aa3a7" ;
2013-02-25 22:08:28 +08:00
Step (
function do _post ( )
{
var next = this ;
assert . response ( server , {
url : '/tiles/layergroup' ,
method : 'POST' ,
headers : { host : 'localhost' , 'Content-Type' : 'application/json' } ,
data : JSON . stringify ( layergroup )
} , { } , function ( res ) {
assert . equal ( res . statusCode , 200 , res . body ) ;
var parsedBody = JSON . parse ( res . body ) ;
var expectedBody = { layergroupid : expected _token } ;
2013-03-14 01:41:37 +08:00
// check last modified
var qTables = JSON . stringify ( {
'q' : 'SELECT CDB_QueryTables($windshaft$'
+ layergroup . layers [ 0 ] . options . sql + ';'
+ layergroup . layers [ 1 ] . options . sql
+ '$windshaft$)'
} ) ;
2013-04-04 19:15:50 +08:00
assert . equal ( parsedBody . last _updated , expected _last _updated ) ;
2013-03-14 01:41:37 +08:00
if ( expected _token ) {
2013-04-04 19:15:50 +08:00
assert . equal ( parsedBody . layergroupid , expected _token + ':' + expected _last _updated _epoch ) ;
2013-03-14 01:41:37 +08:00
}
2013-02-25 22:08:28 +08:00
else expected _token = parsedBody . layergroupid ;
next ( null , res ) ;
} ) ;
} ,
function do _get _tile ( err )
{
if ( err ) throw err ;
var next = this ;
assert . response ( server , {
2013-04-04 19:15:50 +08:00
url : '/tiles/layergroup/' + expected _token + ':cb0/0/0/0.png' ,
2013-02-25 22:08:28 +08:00
method : 'GET' ,
headers : { host : 'localhost' } ,
encoding : 'binary'
} , { } , function ( res ) {
assert . equal ( res . statusCode , 200 , res . body ) ;
assert . equal ( res . headers [ 'content-type' ] , "image/png" ) ;
2013-03-13 18:55:57 +08:00
2013-07-08 18:13:45 +08:00
// Check Cache-Control
var cc = res . headers [ 'cache-control' ] ;
assert . equal ( cc , 'public,max-age=31536000' ) ; // 1 year
2013-03-13 18:55:57 +08:00
// Check X-Cache-Channel
2013-07-08 18:13:45 +08:00
cc = res . headers [ 'x-cache-channel' ] ;
2013-03-13 23:45:15 +08:00
assert . ok ( cc ) ;
2013-11-11 07:50:03 +08:00
var dbname = 'test_cartodb_user_1_db'
2013-03-13 18:55:57 +08:00
assert . equal ( cc . substring ( 0 , dbname . length ) , dbname ) ;
var jsonquery = cc . substring ( dbname . length + 1 ) ;
var sentquery = JSON . parse ( jsonquery ) ;
2013-03-13 23:45:15 +08:00
assert . equal ( sentquery . q , 'SELECT CDB_QueryTables($windshaft$'
+ layergroup . layers [ 0 ] . options . sql + ';'
+ layergroup . layers [ 1 ] . options . sql
+ '$windshaft$)' ) ;
2013-03-13 18:55:57 +08:00
2013-02-25 22:08:28 +08:00
assert . imageEqualsFile ( res . body , 'test/fixtures/test_table_0_0_0_multilayer1.png' , 2 ,
function ( err , similarity ) {
next ( err ) ;
} ) ;
} ) ;
} ,
function do _get _grid _layer0 ( err )
{
if ( err ) throw err ;
var next = this ;
assert . response ( server , {
url : '/tiles/layergroup/' + expected _token
2013-04-04 19:15:50 +08:00
+ '/0/0/0/0.grid.json' ,
2013-02-25 22:08:28 +08:00
headers : { host : 'localhost' } ,
method : 'GET'
} , { } , function ( res ) {
assert . equal ( res . statusCode , 200 , res . body ) ;
assert . equal ( res . headers [ 'content-type' ] , "text/javascript; charset=utf-8; charset=utf-8" ) ;
assert . utfgridEqualsFile ( res . body , 'test/fixtures/test_table_0_0_0_multilayer1.layer0.grid.json' , 2 ,
function ( err , similarity ) {
next ( err ) ;
} ) ;
} ) ;
} ,
function do _get _grid _layer1 ( err )
{
if ( err ) throw err ;
var next = this ;
assert . response ( server , {
url : '/tiles/layergroup/' + expected _token
2013-04-04 19:15:50 +08:00
+ '/1/0/0/0.grid.json' ,
2013-02-25 22:08:28 +08:00
headers : { host : 'localhost' } ,
method : 'GET'
} , { } , function ( res ) {
assert . equal ( res . statusCode , 200 , res . body ) ;
assert . equal ( res . headers [ 'content-type' ] , "text/javascript; charset=utf-8; charset=utf-8" ) ;
assert . utfgridEqualsFile ( res . body , 'test/fixtures/test_table_0_0_0_multilayer1.layer1.grid.json' , 2 ,
function ( err , similarity ) {
next ( err ) ;
} ) ;
} ) ;
} ,
function finish ( err ) {
var errors = [ ] ;
if ( err ) {
errors . push ( err . message ) ;
console . log ( "Error: " + err ) ;
}
2013-11-11 07:50:03 +08:00
redis _client . keys ( "map_style|test_cartodb_user_1_db|~" + expected _token , function ( err , matches ) {
2013-02-25 22:08:28 +08:00
if ( err ) errors . push ( err . message ) ;
assert . equal ( matches . length , 1 , "Missing expected token " + expected _token + " from redis: " + matches ) ;
redis _client . del ( matches , function ( err ) {
if ( err ) errors . push ( err . message ) ;
if ( errors . length ) done ( new Error ( errors ) ) ;
else done ( null ) ;
} ) ;
} ) ;
}
) ;
} ) ;
2013-04-02 18:24:03 +08:00
2013-03-28 19:48:00 +08:00
test ( "layergroup can hold substitution tokens" , function ( done ) {
var layergroup = {
version : '1.0.0' ,
layers : [
{ options : {
sql : 'select 1 as cartodb_id, '
+ 'ST_Buffer(!bbox!, -32*greatest(!pixel_width!,!pixel_height!)) as the_geom_webmercator' ,
cartocss : '#layer { polygon-fill:red; }' ,
2013-04-04 19:15:50 +08:00
cartocss _version : '2.0.1' ,
interactivity : 'cartodb_id'
2013-03-28 19:48:00 +08:00
} }
]
} ;
2013-04-04 19:15:50 +08:00
var expected _token = "6d8e4ad5458e2d25cf0eef38e38717a6" ;
2013-03-28 19:48:00 +08:00
Step (
function do _post ( )
{
var next = this ;
assert . response ( server , {
url : '/tiles/layergroup' ,
method : 'POST' ,
headers : { host : 'localhost' , 'Content-Type' : 'application/json' } ,
data : JSON . stringify ( layergroup )
} , { } , function ( res ) {
assert . equal ( res . statusCode , 200 , res . body ) ;
var parsedBody = JSON . parse ( res . body ) ;
var expectedBody = { layergroupid : expected _token } ;
// check last modified
var qTables = JSON . stringify ( {
'q' : 'SELECT CDB_QueryTables($windshaft$'
+ layergroup . layers [ 0 ] . options . sql
+ '$windshaft$)'
} ) ;
2013-04-04 19:15:50 +08:00
assert . equal ( parsedBody . last _updated , expected _last _updated ) ;
2013-03-28 19:48:00 +08:00
if ( expected _token ) {
2013-04-04 19:15:50 +08:00
assert . equal ( parsedBody . layergroupid , expected _token + ':' + expected _last _updated _epoch ) ;
2013-03-28 19:48:00 +08:00
}
else expected _token = parsedBody . layergroupid ;
next ( null , res ) ;
} ) ;
} ,
function do _get _tile1 ( err )
{
if ( err ) throw err ;
var next = this ;
assert . response ( server , {
2013-04-04 19:15:50 +08:00
url : '/tiles/layergroup/' + expected _token + ':cb10/1/0/0.png' ,
2013-03-28 19:48:00 +08:00
method : 'GET' ,
headers : { host : 'localhost' } ,
encoding : 'binary'
} , { } , function ( res ) {
assert . equal ( res . statusCode , 200 , res . body ) ;
assert . equal ( res . headers [ 'content-type' ] , "image/png" ) ;
// Check X-Cache-Channel
var cc = res . headers [ 'x-cache-channel' ] ;
assert . ok ( cc ) ;
2013-11-11 07:50:03 +08:00
var dbname = 'test_cartodb_user_1_db'
2013-03-28 19:48:00 +08:00
assert . equal ( cc . substring ( 0 , dbname . length ) , dbname ) ;
var jsonquery = cc . substring ( dbname . length + 1 ) ;
var sentquery = JSON . parse ( jsonquery ) ;
assert . equal ( sentquery . q , 'SELECT CDB_QueryTables($windshaft$'
+ layergroup . layers [ 0 ] . options . sql
2013-04-23 23:12:10 +08:00
. replace ( RegExp ( '!bbox!' , 'g' ) , 'ST_MakeEnvelope(0,0,0,0)' )
. replace ( RegExp ( '!pixel_width!' , 'g' ) , '1' )
. replace ( RegExp ( '!pixel_height!' , 'g' ) , '1' )
2013-03-28 19:48:00 +08:00
+ '$windshaft$)' ) ;
assert . imageEqualsFile ( res . body , 'test/fixtures/test_multilayer_bbox.png' , 2 ,
function ( err , similarity ) {
next ( err ) ;
} ) ;
} ) ;
} ,
function do _get _tile4 ( err )
{
if ( err ) throw err ;
var next = this ;
assert . response ( server , {
2013-04-04 19:15:50 +08:00
url : '/tiles/layergroup/' + expected _token + ':cb11/4/0/0.png' ,
2013-03-28 19:48:00 +08:00
method : 'GET' ,
headers : { host : 'localhost' } ,
encoding : 'binary'
} , { } , function ( res ) {
assert . equal ( res . statusCode , 200 , res . body ) ;
assert . equal ( res . headers [ 'content-type' ] , "image/png" ) ;
// Check X-Cache-Channel
var cc = res . headers [ 'x-cache-channel' ] ;
assert . ok ( cc ) ;
2013-11-11 07:50:03 +08:00
var dbname = 'test_cartodb_user_1_db'
2013-03-28 19:48:00 +08:00
assert . equal ( cc . substring ( 0 , dbname . length ) , dbname ) ;
var jsonquery = cc . substring ( dbname . length + 1 ) ;
var sentquery = JSON . parse ( jsonquery ) ;
assert . equal ( sentquery . q , 'SELECT CDB_QueryTables($windshaft$'
+ layergroup . layers [ 0 ] . options . sql
2013-04-23 23:12:10 +08:00
. replace ( '!bbox!' , 'ST_MakeEnvelope(0,0,0,0)' )
. replace ( '!pixel_width!' , '1' )
. replace ( '!pixel_height!' , '1' )
2013-03-28 19:48:00 +08:00
+ '$windshaft$)' ) ;
assert . imageEqualsFile ( res . body , 'test/fixtures/test_multilayer_bbox.png' , 2 ,
function ( err , similarity ) {
next ( err ) ;
} ) ;
} ) ;
} ,
function do _get _grid1 ( err )
{
if ( err ) throw err ;
var next = this ;
assert . response ( server , {
url : '/tiles/layergroup/' + expected _token
2013-04-04 19:15:50 +08:00
+ '/0/1/0/0.grid.json' ,
2013-03-28 19:48:00 +08:00
headers : { host : 'localhost' } ,
method : 'GET'
} , { } , function ( res ) {
assert . equal ( res . statusCode , 200 , res . body ) ;
assert . equal ( res . headers [ 'content-type' ] , "text/javascript; charset=utf-8; charset=utf-8" ) ;
assert . utfgridEqualsFile ( res . body , 'test/fixtures/test_multilayer_bbox.grid.json' , 2 ,
function ( err , similarity ) {
next ( err ) ;
} ) ;
} ) ;
} ,
function do _get _grid4 ( err )
{
if ( err ) throw err ;
var next = this ;
assert . response ( server , {
url : '/tiles/layergroup/' + expected _token
2013-04-04 19:15:50 +08:00
+ '/0/4/0/0.grid.json' ,
2013-03-28 19:48:00 +08:00
headers : { host : 'localhost' } ,
method : 'GET'
} , { } , function ( res ) {
assert . equal ( res . statusCode , 200 , res . body ) ;
assert . equal ( res . headers [ 'content-type' ] , "text/javascript; charset=utf-8; charset=utf-8" ) ;
assert . utfgridEqualsFile ( res . body , 'test/fixtures/test_multilayer_bbox.grid.json' , 2 ,
function ( err , similarity ) {
next ( err ) ;
} ) ;
} ) ;
} ,
function finish ( err ) {
var errors = [ ] ;
2013-04-12 23:28:34 +08:00
if ( err ) {
errors . push ( err . message ) ;
console . log ( "Error: " + err ) ;
}
2013-11-11 07:50:03 +08:00
redis _client . keys ( "map_style|test_cartodb_user_1_db|~" + expected _token , function ( err , matches ) {
2013-04-12 23:28:34 +08:00
if ( err ) errors . push ( err . message ) ;
assert . equal ( matches . length , 1 , "Missing expected token " + expected _token + " from redis: " + matches ) ;
redis _client . del ( matches , function ( err ) {
if ( err ) errors . push ( err . message ) ;
if ( errors . length ) done ( new Error ( errors ) ) ;
else done ( null ) ;
} ) ;
} ) ;
}
) ;
} ) ;
test ( "layergroup creation raises mapviews counter" , function ( done ) {
var layergroup = {
2013-06-04 19:29:36 +08:00
stat _tag : 'random_tag' ,
2013-04-12 23:28:34 +08:00
version : '1.0.0' ,
layers : [
{ options : {
2013-06-19 23:24:01 +08:00
sql : 'select 1 as cartodb_id, !pixel_height! as h, '
2013-04-12 23:28:34 +08:00
+ 'ST_Buffer(!bbox!, -32*greatest(!pixel_width!,!pixel_height!)) as the_geom_webmercator' ,
cartocss : '#layer { polygon-fill:red; }' ,
cartocss _version : '2.0.1'
} }
]
} ;
2013-06-04 19:29:36 +08:00
var statskey = "user:localhost:mapviews" ;
2013-04-12 23:28:34 +08:00
var redis _stats _client = redis . createClient ( global . environment . redis . port ) ;
var expected _token ; // will be set on first post and checked on second
2013-06-04 19:29:36 +08:00
var now = strftime ( "%Y%m%d" , new Date ( ) ) ;
var errors = [ ] ;
2013-04-12 23:28:34 +08:00
Step (
function clean _stats ( )
{
var next = this ;
redis _stats _client . select ( redis _stats _db , function ( err ) {
if ( err ) next ( err ) ;
2013-06-04 19:29:36 +08:00
else redis _stats _client . del ( statskey + ':global' , next ) ;
2013-04-12 23:28:34 +08:00
} ) ;
} ,
function do _post _1 ( err )
{
if ( err ) throw err ;
var next = this ;
assert . response ( server , {
url : '/tiles/layergroup' ,
method : 'POST' ,
headers : { host : 'localhost' , 'Content-Type' : 'application/json' } ,
data : JSON . stringify ( layergroup )
} , { } , function ( res ) {
assert . equal ( res . statusCode , 200 , res . body ) ;
expected _token = JSON . parse ( res . body ) . layergroupid ;
2013-06-04 19:29:36 +08:00
redis _stats _client . zscore ( statskey + ":global" , now , next ) ;
2013-04-12 23:28:34 +08:00
} ) ;
} ,
2013-06-04 19:29:36 +08:00
function check _global _stats _1 ( err , val ) {
2013-04-12 23:28:34 +08:00
if ( err ) throw err ;
2013-06-04 19:29:36 +08:00
assert . equal ( val , 1 , "Expected score of " + now + " in "
+ statskey + ":global to be 1, got " + val ) ;
redis _stats _client . zscore ( statskey + ':stat_tag:random_tag' , now , this ) ;
} ,
function check _tag _stats _1 _do _post _2 ( err , val ) {
if ( err ) throw err ;
assert . equal ( val , 1 , "Expected score of " + now + " in "
+ statskey + ":stat_tag:" + layergroup . stat _tag + " to be 1, got " + val ) ;
2013-04-12 23:28:34 +08:00
var next = this ;
assert . response ( server , {
url : '/tiles/layergroup' ,
method : 'POST' ,
headers : { host : 'localhost' , 'Content-Type' : 'application/json' } ,
data : JSON . stringify ( layergroup )
} , { } , function ( res ) {
assert . equal ( res . statusCode , 200 , res . body ) ;
assert . equal ( JSON . parse ( res . body ) . layergroupid , expected _token ) ;
2013-06-04 19:29:36 +08:00
redis _stats _client . zscore ( statskey + ':global' , now , next ) ;
2013-04-12 23:28:34 +08:00
} ) ;
} ,
2013-06-04 19:29:36 +08:00
function check _global _stats _2 ( err , val )
2013-04-12 23:28:34 +08:00
{
if ( err ) throw err ;
2013-06-04 19:29:36 +08:00
assert . equal ( val , 2 , "Expected score of " + now + " in "
+ statskey + ":global to be 2, got " + val ) ;
redis _stats _client . zscore ( statskey + ':stat_tag:' + layergroup . stat _tag , now , this ) ;
} ,
function check _tag _stats _2 ( err , val )
{
if ( err ) throw err ;
assert . equal ( val , 2 , "Expected score of " + now + " in "
+ statskey + ":stat_tag:" + layergroup . stat _tag + " to be 2, got " + val ) ;
2013-04-12 23:28:34 +08:00
return 1 ;
} ,
2013-06-04 19:29:36 +08:00
function cleanup _map _style ( err ) {
if ( err ) errors . push ( '' + err ) ;
var next = this ;
2013-04-04 19:15:50 +08:00
// trip epoch
expected _token = expected _token . split ( ':' ) [ 0 ] ;
2013-11-11 07:50:03 +08:00
redis _client . keys ( "map_style|test_cartodb_user_1_db|~" + expected _token , function ( err , matches ) {
2013-06-04 19:29:36 +08:00
redis _client . del ( matches , next ) ;
2013-03-28 19:48:00 +08:00
} ) ;
2013-06-04 19:29:36 +08:00
} ,
function cleanup _stats ( err ) {
if ( err ) errors . push ( '' + err ) ;
redis _client . del ( [ statskey + ':global' , statskey + ':stat_tag:' + layergroup . stat _tag ] , this ) ;
} ,
function finish ( err ) {
if ( err ) errors . push ( '' + err ) ;
if ( errors . length ) done ( new Error ( errors . join ( ',' ) ) ) ;
else done ( null ) ;
2013-03-28 19:48:00 +08:00
}
) ;
} ) ;
2013-06-10 17:53:28 +08:00
test ( "layergroup creation fails if CartoCSS is bogus" , function ( done ) {
var layergroup = {
stat _tag : 'random_tag' ,
version : '1.0.0' ,
layers : [
{ options : {
sql : 'select 1 as cartodb_id, !pixel_height! as h'
+ 'ST_Buffer(!bbox!, -32*greatest(!pixel_width!,!pixel_height!)) as the_geom_webmercator' ,
cartocss : '#layer { polygon-fit:red; }' ,
cartocss _version : '2.0.1'
} }
]
} ;
assert . response ( server , {
url : '/tiles/layergroup' ,
method : 'POST' ,
headers : { host : 'localhost' , 'Content-Type' : 'application/json' } ,
data : JSON . stringify ( layergroup )
} , { } , function ( res ) {
assert . equal ( res . statusCode , 400 , res . body ) ;
var parsed = JSON . parse ( res . body ) ;
assert . ok ( parsed . errors [ 0 ] . match ( /^style0/ ) ) ;
assert . ok ( parsed . errors [ 0 ] . match ( /Unrecognized rule: polygon-fit/ ) ) ;
done ( ) ;
} ) ;
} ) ;
2013-06-17 23:24:09 +08:00
test ( "layergroup with 2 private-table layers" , function ( done ) {
var layergroup = {
version : '1.0.0' ,
layers : [
{ options : {
sql : 'select * from test_table_private_1 where cartodb_id=1' ,
cartocss : '#layer { marker-fill:red; marker-width:32; marker-allow-overlap:true; }' ,
2013-09-13 00:37:25 +08:00
cartocss _version : '2.1.0' ,
2013-06-17 23:24:09 +08:00
interactivity : 'cartodb_id'
} } ,
{ options : {
sql : 'select * from test_table_private_1 where cartodb_id=2' ,
cartocss : '#layer { marker-fill:blue; marker-allow-overlap:true; }' ,
2013-09-13 00:37:25 +08:00
cartocss _version : '2.1.0' ,
2013-06-17 23:24:09 +08:00
interactivity : 'cartodb_id'
} }
]
} ;
2013-09-13 00:37:25 +08:00
var expected _token = "b4ed64d93a411a59f330ab3d798e4009" ;
2013-06-17 23:24:09 +08:00
Step (
function do _post ( )
{
var next = this ;
assert . response ( server , {
url : '/tiles/layergroup?map_key=1234' ,
method : 'POST' ,
headers : { host : 'localhost' , 'Content-Type' : 'application/json' } ,
data : JSON . stringify ( layergroup )
} , { } , function ( res ) {
assert . equal ( res . statusCode , 200 , res . body ) ;
var parsedBody = JSON . parse ( res . body ) ;
var expectedBody = { layergroupid : expected _token } ;
// check last modified
var qTables = JSON . stringify ( {
'q' : 'SELECT CDB_QueryTables($windshaft$'
+ layergroup . layers [ 0 ] . options . sql + ';'
+ layergroup . layers [ 1 ] . options . sql
+ '$windshaft$)'
} ) ;
assert . equal ( parsedBody . last _updated , expected _last _updated ) ;
if ( expected _token ) {
assert . equal ( parsedBody . layergroupid , expected _token + ':' + expected _last _updated _epoch ) ;
}
else expected _token = parsedBody . layergroupid ;
next ( null , res ) ;
} ) ;
} ,
function do _get _tile ( err )
{
if ( err ) throw err ;
var next = this ;
assert . response ( server , {
url : '/tiles/layergroup/' + expected _token + ':cb0/0/0/0.png?map_key=1234' ,
method : 'GET' ,
headers : { host : 'localhost' } ,
encoding : 'binary'
} , { } , function ( res ) {
assert . equal ( res . statusCode , 200 , res . body ) ;
assert . equal ( res . headers [ 'content-type' ] , "image/png" ) ;
// Check X-Cache-Channel
var cc = res . headers [ 'x-cache-channel' ] ;
assert . ok ( cc ) ;
2013-11-11 07:50:03 +08:00
var dbname = 'test_cartodb_user_1_db'
2013-06-17 23:24:09 +08:00
assert . equal ( cc . substring ( 0 , dbname . length ) , dbname ) ;
next ( err ) ;
} ) ;
} ,
function do _get _grid _layer0 ( err )
{
if ( err ) throw err ;
var next = this ;
assert . response ( server , {
url : '/tiles/layergroup/' + expected _token
+ '/0/0/0/0.grid.json?map_key=1234' ,
headers : { host : 'localhost' } ,
method : 'GET'
} , { } , function ( res ) {
assert . equal ( res . statusCode , 200 , res . body ) ;
next ( err ) ;
} ) ;
} ,
function do _get _grid _layer1 ( err )
{
if ( err ) throw err ;
var next = this ;
assert . response ( server , {
url : '/tiles/layergroup/' + expected _token
+ '/1/0/0/0.grid.json?map_key=1234' ,
headers : { host : 'localhost' } ,
method : 'GET'
} , { } , function ( res ) {
assert . equal ( res . statusCode , 200 , res . body ) ;
assert . equal ( res . headers [ 'content-type' ] , "text/javascript; charset=utf-8; charset=utf-8" ) ;
next ( err ) ;
} ) ;
} ,
2013-09-23 17:59:03 +08:00
function do _get _tile _unauth ( err )
{
if ( err ) throw err ;
var next = this ;
assert . response ( server , {
url : '/tiles/layergroup/' + expected _token + ':cb0/0/0/0.png' ,
method : 'GET' ,
headers : { host : 'localhost' } ,
encoding : 'binary'
} , { } , function ( res ) {
assert . equal ( res . statusCode , 401 ) ;
var re = RegExp ( 'permission denied' ) ;
assert . ok ( res . body . match ( re ) , 'No "permission denied" error: ' + res . body ) ;
next ( err ) ;
} ) ;
} ,
function do _get _grid _layer0 _unauth ( err )
{
if ( err ) throw err ;
var next = this ;
assert . response ( server , {
url : '/tiles/layergroup/' + expected _token
+ '/0/0/0/0.grid.json' ,
headers : { host : 'localhost' } ,
method : 'GET'
} , { } , function ( res ) {
assert . equal ( res . statusCode , 401 ) ;
var re = RegExp ( 'permission denied' ) ;
assert . ok ( res . body . match ( re ) , 'No "permission denied" error: ' + res . body ) ;
next ( err ) ;
} ) ;
} ,
function do _get _grid _layer1 _unauth ( err )
{
if ( err ) throw err ;
var next = this ;
assert . response ( server , {
url : '/tiles/layergroup/' + expected _token
+ '/1/0/0/0.grid.json' ,
headers : { host : 'localhost' } ,
method : 'GET'
} , { } , function ( res ) {
assert . equal ( res . statusCode , 401 ) ;
var re = RegExp ( 'permission denied' ) ;
assert . ok ( res . body . match ( re ) , 'No "permission denied" error: ' + res . body ) ;
next ( err ) ;
} ) ;
} ,
2013-06-17 23:24:09 +08:00
function finish ( err ) {
var errors = [ ] ;
if ( err ) {
errors . push ( err . message ) ;
console . log ( "Error: " + err ) ;
}
2013-11-11 07:50:03 +08:00
redis _client . keys ( "map_style|test_cartodb_user_1_db|~" + expected _token , function ( err , matches ) {
2013-06-17 23:24:09 +08:00
if ( err ) errors . push ( err . message ) ;
assert . equal ( matches . length , 1 , "Missing expected token " + expected _token + " from redis: " + matches ) ;
redis _client . del ( matches , function ( err ) {
if ( err ) errors . push ( err . message ) ;
if ( errors . length ) done ( new Error ( errors ) ) ;
else done ( null ) ;
} ) ;
} ) ;
}
) ;
} ) ;
2013-09-23 16:57:22 +08:00
// https://github.com/cartodb/Windshaft-cartodb/issues/81
test ( "invalid text-name in CartoCSS" , function ( done ) {
2013-09-12 23:32:10 +08:00
var layergroup = {
version : '1.0.1' ,
layers : [
{ options : {
sql : "select 1 as cartodb_id, 'SRID=3857;POINT(0 0)'::geometry as the_geom_webmercator" ,
cartocss : '#sample { text-name: cartodb_id; text-face-name: "Dejagnu"; }' ,
2013-09-13 00:37:25 +08:00
cartocss _version : '2.1.0' ,
2013-09-12 23:32:10 +08:00
} }
]
} ;
assert . response ( server , {
url : '/tiles/layergroup?' ,
method : 'POST' ,
headers : { host : 'localhost' , 'Content-Type' : 'application/json' } ,
data : JSON . stringify ( layergroup )
} , { } , function ( res ) {
assert . equal ( res . statusCode , 400 , res . statusCode + ': ' + res . body ) ;
var parsed = JSON . parse ( res . body ) ;
assert . deepEqual ( parsed , { "errors" : [ "style0:1:10 Invalid value for text-name, the type expression is expected. cartodb_id (of type keyword) was given." ] } ) ;
done ( ) ;
} ) ;
} ) ;
2013-10-03 23:01:12 +08:00
test ( "quotes CartoCSS" , function ( done ) {
var layergroup = {
version : '1.0.1' ,
layers : [
{ options : {
sql : "select 'single''quote' as n, 'SRID=3857;POINT(0 0)'::geometry as the_geom_webmercator" ,
cartocss : '#s [n="single\'quote" ] { marker-fill:red; }' ,
cartocss _version : '2.1.0' ,
} } ,
{ options : {
sql : "select 'double\"quote' as n, 'SRID=3857;POINT(2 0)'::geometry as the_geom_webmercator" ,
cartocss : '#s [n="double\\"quote" ] { marker-fill:red; }' ,
cartocss _version : '2.1.0' ,
} }
]
} ;
assert . response ( server , {
url : '/tiles/layergroup?' ,
method : 'POST' ,
headers : { host : 'localhost' , 'Content-Type' : 'application/json' } ,
data : JSON . stringify ( layergroup )
} , { } , function ( res ) {
assert . equal ( res . statusCode , 200 , res . statusCode + ': ' + res . body ) ;
done ( ) ;
} ) ;
} ) ;
2013-11-08 19:34:34 +08:00
// See https://github.com/CartoDB/Windshaft-cartodb/issues/87
test ( "exponential notation in CartoCSS filter values" , function ( done ) {
var layergroup = {
version : '1.0.1' ,
layers : [
{ options : {
sql : "select .4 as n, 'SRID=3857;POINT(0 0)'::geometry as the_geom_webmercator" ,
cartocss : '#s [n<=.2e-2] { marker-fill:red; }' ,
cartocss _version : '2.1.0' ,
} }
]
} ;
assert . response ( server , {
url : '/tiles/layergroup?' ,
method : 'POST' ,
headers : { host : 'localhost' , 'Content-Type' : 'application/json' } ,
data : JSON . stringify ( layergroup )
} , { } , function ( res ) {
assert . equal ( res . statusCode , 200 , res . statusCode + ': ' + res . body ) ;
done ( ) ;
} ) ;
} ) ;
2013-02-25 22:08:28 +08:00
suiteTeardown ( function ( done ) {
2013-06-04 19:29:36 +08:00
2013-02-25 22:08:28 +08:00
// This test will add map_style records, like
// 'map_style|null|publicuser|my_table',
redis _client . keys ( "map_style|*" , function ( err , matches ) {
2013-03-28 19:48:00 +08:00
redis _client . del ( matches , function ( err ) {
2013-06-04 19:29:36 +08:00
redis _client . select ( 5 , function ( err , matches ) {
redis _client . keys ( "user:localhost:mapviews*" , function ( err , matches ) {
redis _client . del ( matches , function ( err ) {
sqlapi _server . close ( done ) ;
} ) ;
} ) ;
} ) ;
2013-03-28 19:48:00 +08:00
} ) ;
2013-02-25 22:08:28 +08:00
} ) ;
2013-06-04 19:29:36 +08:00
2013-02-25 22:08:28 +08:00
} ) ;
} ) ;