diff --git a/lib/app.js b/lib/app.js index 032758d..d70850f 100644 --- a/lib/app.js +++ b/lib/app.js @@ -154,13 +154,13 @@ module.exports = function(tilelive, options) { if (ext !== format) { debug("Invalid format '%s', expected '%s'", format, ext); - return callback(null, null, populateHeaders({}, params, { 404: true, invalidFormat: true })); + return callback(null, null, populateHeaders({}, params, { 404: true, invalidFormat: true }), 404); } // validate zoom if (z < info.minzoom || z > info.maxzoom) { debug("Invalid zoom:", z); - return callback(null, null, populateHeaders({}, params, { 404: true, invalidZoom: true })); + return callback(null, null, populateHeaders({}, params, { 404: true, invalidZoom: true }), 404); } // validate coords against bounds @@ -171,22 +171,24 @@ module.exports = function(tilelive, options) { y < xyz.minY || y > xyz.maxY) { debug("Invalid coordinates: %d,%d relative to bounds:", x, y, xyz); - return callback(null, null, populateHeaders({}, params, { 404: true, invalidCoordinates: true })); + return callback(null, null, populateHeaders({}, params, { 404: true, invalidCoordinates: true }), 404); } return source.getTile(z, x, y, function(err, data, headers) { headers = normalizeHeaders(headers || {}); if (err) { - if (err.message.match(/(Tile|Grid) does not exist/)) { - return callback(null, null, populateHeaders(headers, params, { 404: true })); + if (!err.message.match(/(Tile|Grid) does not exist/)) { + return callback(err); } - - return callback(err); } if (data === null || data === undefined) { - return callback(null, null, populateHeaders(headers, params, { 404: true })); + if (ext != "pbf") { // return 404 error for missing rasters + return callback(null, null, populateHeaders(headers, params, {404: true}), 404); + } else { + data = ""; + } } if (!headers["content-md5"]) { @@ -199,7 +201,7 @@ module.exports = function(tilelive, options) { headers["content-encoding"] = headers["content-encoding"] || "gzip"; } - return callback(null, data, populateHeaders(headers, params, { 200: true })); + return callback(null, data, populateHeaders(headers, params, { 200: true }), 200); }); }); }); @@ -211,16 +213,20 @@ module.exports = function(tilelive, options) { y = req.params.y | 0, scale = getScale(req.params.scale), format = req.params.format; - return getTile(z, x, y, scale, format, function(err, data, headers) { + return getTile(z, x, y, scale, format, function(err, data, headers, status) { if (err) { return next(err); } - if (data == null && format !== "pbf") { - return res.status(404).send("Not found"); - } else { - res.set(headers); - return res.status(200).send(data); + + status = status || 200; + if (status != 200) { + return res.sendStatus(status); } + + return res + .status(200) + .set(headers) + .send(data); }, res, next); }); diff --git a/package.json b/package.json index cbde107..02744ac 100644 --- a/package.json +++ b/package.json @@ -11,7 +11,8 @@ "url": "https://github.com/mojodna/tessera.git" }, "scripts": { - "prepublish": "npm install bower && bower install" + "prepublish": "npm install bower && bower install", + "test": "mocha" }, "dependencies": { "abaculus": "^1.2.1", @@ -28,5 +29,10 @@ "tilelive": "^5.3.3", "tilelive-cache": "^0.6.1", "tilelive-modules": "^0.2.0" + }, + "devDependencies": { + "mocha": "^1.18.0", + "supertest": "^0.3", + "mbtiles": "^0.2.9" } } diff --git a/test/fixtures/empty.mbtiles b/test/fixtures/empty.mbtiles new file mode 100644 index 0000000..4370b1b Binary files /dev/null and b/test/fixtures/empty.mbtiles differ diff --git a/test/mbtiles.js b/test/mbtiles.js new file mode 100644 index 0000000..8fa72c9 --- /dev/null +++ b/test/mbtiles.js @@ -0,0 +1,64 @@ +"use strict"; + +var assert = require("assert"), + express = require("express"), + request = require("supertest"), + tilelive = require("tilelive-cache")(require("tilelive"), {}), + serve = require("../lib/app"), + tessera = require("../lib/index"); + +// load and register tilelive modules +require("tilelive-modules/loader")(tilelive, {}); + +describe("MBTiles", function () { + var app; + before(function (done) { + var uri = "mbtiles://./test/fixtures/empty.mbtiles"; + app = express(); + app.use(serve(tilelive, uri)); + + return done(); + }); + + it("should return TileJSON", function (done) { + request(app) + .get("/index.json") + .expect(200) + .end(function (err, res) { + assert.equal(err, null); + assert(typeof res.body == "object"); + + assert.equal(res.body.format, "pbf"); + assert.equal(res.body.minzoom, 0); + assert.equal(res.body.maxzoom, 14); + + done(); + }); + }); + + it("should return empty vector tile on valid request", function (done) { + request(app) + .get("/5/1/1.pbf") + .expect(200) + .end(function (err, res) { + console.error(err); + assert.equal(err, null); + assert.equal(typeof res.text, "undefined"); + assert.deepEqual(res.body, {}); + + done(); + }); + }); + + it("should return 404 on overzoom request", function (done) { + request(app) + .get("/15/1/1.pbf") + .expect(404) + .end(function (err, res) { + assert.equal(err, null); + assert.equal(res.text, "Not Found"); + + done(); + }); + }); +});