From 3ad9c29a35f3049579149173135c6152b3b18dde Mon Sep 17 00:00:00 2001 From: Bryan Housel Date: Tue, 16 Feb 2016 15:59:14 -0500 Subject: [PATCH] Add test coverage for mapillary service --- test/spec/services/mapillary.js | 326 +++++++++++++++++++++++++++++++- 1 file changed, 319 insertions(+), 7 deletions(-) diff --git a/test/spec/services/mapillary.js b/test/spec/services/mapillary.js index 8df099dd6..cea1274ed 100644 --- a/test/spec/services/mapillary.js +++ b/test/spec/services/mapillary.js @@ -1,7 +1,11 @@ -describe("iD.services.mapillary", function() { - var server, mapillary; +describe('iD.services.mapillary', function() { + var dimensions = [64, 64], + context, server, mapillary; beforeEach(function() { + context = iD(); + context.projection.scale(667544.214430109); // z14 + server = sinon.fakeServer.create(); mapillary = iD.services.mapillary(); mapillary.reset(); @@ -11,14 +15,322 @@ describe("iD.services.mapillary", function() { server.restore(); }); - function query(url) { - return iD.util.stringQs(url.substring(url.indexOf('?') + 1)); - } - describe("#images", function() { + describe('Mapillary service', function() { + it('Initializes cache one time', function() { + var cache = iD.services.mapillary.cache; + expect(cache).to.have.property('images'); + expect(cache).to.have.property('signs'); + + var mapillary2 = iD.services.mapillary(); + var cache2 = iD.services.mapillary.cache; + expect(cache).to.equal(cache2); + }); }); - describe("#signs", function() { + describe('#loadImages', function() { + it('fires loadedImages when images are loaded', function() { + var spy = sinon.spy(); + mapillary.on('loadedImages', spy); + mapillary.loadImages(context.projection, dimensions); + + var match = /search\/im\/geojson/, + features = [{ + type: 'Feature', + geometry: { type: 'Point', coordinates: [0,0] }, + properties: { ca: 90, key: '0' } + }], + response = { type: 'FeatureCollection', features: features }; + + server.respondWith('GET', match, + [200, { 'Content-Type': 'application/json' }, JSON.stringify(response) ]); + server.respond(); + + expect(spy).to.have.been.calledOnce; + }); + + it('loads multiple pages of image results', function() { + var spy = sinon.spy(); + mapillary.on('loadedImages', spy); + mapillary.loadImages(context.projection, dimensions); + + var features0 = [], + features1 = [], + i; + + for (i = 0; i < 1000; i++) { + features0.push({ + type: 'Feature', + geometry: { type: 'Point', coordinates: [0,0] }, + properties: { ca: 90, key: String(i) } + }); + } + for (i = 0; i < 500; i++) { + features1.push({ + type: 'Feature', + geometry: { type: 'Point', coordinates: [0,0] }, + properties: { ca: 90, key: String(1000 + i) } + }); + } + + var match0 = /page=0/, + response0 = { type: 'FeatureCollection', features: features0 }, + match1 = /page=1/, + response1 = { type: 'FeatureCollection', features: features1 } + + server.respondWith('GET', match0, + [200, { 'Content-Type': 'application/json' }, JSON.stringify(response0) ]); + server.respondWith('GET', match1, + [200, { 'Content-Type': 'application/json' }, JSON.stringify(response1) ]); + server.respond(); + + expect(spy).to.have.been.calledTwice; + }); + }); + + describe('#loadSigns', function() { + it('loads sign_defs', function() { + mapillary.loadSigns(context, context.projection, dimensions); + + var base = 'regulatory--maximum-speed-limit-65--', + match = /traffico\/string-maps\/(\w+)-map.json/; + + server.respondWith('GET', match, function (xhr, id) { + xhr.respond(200, { 'Content-Type': 'application/json' }, + '{ "' + base + id + '": true }'); + }); + server.respond(); + + var sign_defs = iD.services.mapillary.sign_defs; + + expect(sign_defs).to.have.property('au') + .that.is.an('object') + .that.deep.equals({'regulatory--maximum-speed-limit-65--au': true}); + expect(sign_defs).to.have.property('br') + .that.is.an('object') + .that.deep.equals({'regulatory--maximum-speed-limit-65--br': true}); + expect(sign_defs).to.have.property('ca') + .that.is.an('object') + .that.deep.equals({'regulatory--maximum-speed-limit-65--ca': true}); + expect(sign_defs).to.have.property('eu') + .that.is.an('object') + .that.deep.equals({'regulatory--maximum-speed-limit-65--de': true}); + expect(sign_defs).to.have.property('us') + .that.is.an('object') + .that.deep.equals({'regulatory--maximum-speed-limit-65--us': true}); + }); + + it('fires loadedSigns when signs are loaded', function() { + var spy = sinon.spy(); + mapillary.on('loadedSigns', spy); + mapillary.loadSigns(context, context.projection, dimensions); + + var match = /search\/im\/geojson\/or/, + rects = [{ + 'package': 'trafficsign_us_3.0', + rect: [ 0.805, 0.463, 0.833, 0.502 ], + length: 4, + score: '1.27', + type: 'regulatory--maximum-speed-limit-65--us' + }], + features = [{ + type: 'Feature', + geometry: { type: 'Point', coordinates: [0,0] }, + properties: { rects: rects, key: '0' } + }], + response = { type: 'FeatureCollection', features: features }; + + server.respondWith('GET', match, + [200, { 'Content-Type': 'application/json' }, JSON.stringify(response) ]); + server.respond(); + + expect(spy).to.have.been.calledOnce; + }); + + it('loads multiple pages of signs results', function() { + var spy = sinon.spy(); + mapillary.on('loadedSigns', spy); + mapillary.loadSigns(context, context.projection, dimensions); + + var rects = [{ + 'package': 'trafficsign_us_3.0', + rect: [ 0.805, 0.463, 0.833, 0.502 ], + length: 4, + score: '1.27', + type: 'regulatory--maximum-speed-limit-65--us' + }], + features0 = [], + features1 = [], + i; + + for (i = 0; i < 1000; i++) { + features0.push({ + type: 'Feature', + geometry: { type: 'Point', coordinates: [0,0] }, + properties: { rects: rects, key: String(i) } + }); + } + for (i = 0; i < 500; i++) { + features1.push({ + type: 'Feature', + geometry: { type: 'Point', coordinates: [0,0] }, + properties: { rects: rects, key: String(1000 + i) } + }); + } + + var match0 = /page=0/, + response0 = { type: 'FeatureCollection', features: features0 }, + match1 = /page=1/, + response1 = { type: 'FeatureCollection', features: features1 } + + server.respondWith('GET', match0, + [200, { 'Content-Type': 'application/json' }, JSON.stringify(response0) ]); + server.respondWith('GET', match1, + [200, { 'Content-Type': 'application/json' }, JSON.stringify(response1) ]); + server.respond(); + + expect(spy).to.have.been.calledTwice; + }); + }); + + + describe('#images', function() { + it('returns images in the visible map area', function() { + var features = [ + [0, 0, 0, 0, { key: '0', loc: [0,0], ca: 90 }], + [0, 0, 0, 0, { key: '1', loc: [0,0], ca: 90 }], + [0, 1, 0, 1, { key: '2', loc: [0,1], ca: 90 }] + ]; + + iD.services.mapillary.cache.images.rtree.load(features); + var res = mapillary.images(context.projection, dimensions); + + expect(res).to.deep.eql([ + { key: '0', loc: [0,0], ca: 90 }, + { key: '1', loc: [0,0], ca: 90 } + ]); + }); + + it('limits results no more than 3 stacked images in one spot', function() { + var features = [ + [0, 0, 0, 0, { key: '0', loc: [0,0], ca: 90 }], + [0, 0, 0, 0, { key: '1', loc: [0,0], ca: 90 }], + [0, 0, 0, 0, { key: '2', loc: [0,0], ca: 90 }], + [0, 0, 0, 0, { key: '3', loc: [0,0], ca: 90 }], + [0, 0, 0, 0, { key: '4', loc: [0,0], ca: 90 }] + ]; + + iD.services.mapillary.cache.images.rtree.load(features); + var res = mapillary.images(context.projection, dimensions); + expect(res).to.have.length.of.at.most(3); + }); + }); + + describe('#signs', function() { + it('returns signs in the visible map area', function() { + var signs = [{ + 'package': 'trafficsign_us_3.0', + rect: [ 0.805, 0.463, 0.833, 0.502 ], + length: 4, + score: '1.27', + type: 'regulatory--maximum-speed-limit-65--us' + }], + features = [ + [0, 0, 0, 0, { key: '0', loc: [0,0], signs: signs }], + [0, 0, 0, 0, { key: '1', loc: [0,0], signs: signs }], + [0, 1, 0, 1, { key: '2', loc: [0,1], signs: signs }] + ]; + + iD.services.mapillary.cache.signs.rtree.load(features); + var res = mapillary.signs(context.projection, dimensions); + + expect(res).to.deep.eql([ + { key: '0', loc: [0,0], signs: signs }, + { key: '1', loc: [0,0], signs: signs } + ]); + }); + + it('limits results no more than 3 stacked signs in one spot', function() { + var signs = [{ + 'package': 'trafficsign_us_3.0', + rect: [ 0.805, 0.463, 0.833, 0.502 ], + length: 4, + score: '1.27', + type: 'regulatory--maximum-speed-limit-65--us' + }], + features = [ + [0, 0, 0, 0, { key: '0', loc: [0,0], signs: signs }], + [0, 0, 0, 0, { key: '1', loc: [0,0], signs: signs }], + [0, 0, 0, 0, { key: '2', loc: [0,0], signs: signs }], + [0, 0, 0, 0, { key: '3', loc: [0,0], signs: signs }], + [0, 0, 0, 0, { key: '4', loc: [0,0], signs: signs }] + ]; + + iD.services.mapillary.cache.signs.rtree.load(features); + var res = mapillary.signs(context.projection, dimensions); + expect(res).to.have.length.of.at.most(3); + }); + }); + + describe('#signsSupported', function() { + it('returns false for Internet Explorer', function() { + var detect = iD.detect; + iD.detect = function() { return { ie: true, browser: 'Internet Explorer' }; }; + expect(mapillary.signsSupported()).to.be.false; + iD.detect = detect; + }); + + it('returns false for Safari', function() { + var detect = iD.detect; + iD.detect = function() { return { ie: false, browser: 'Safari' }; }; + expect(mapillary.signsSupported()).to.be.false; + iD.detect = detect; + }); + }); + + describe('#signHTML', function() { + it('returns sign HTML', function() { + iD.services.mapillary.sign_defs = { + us: {'regulatory--maximum-speed-limit-65--us': '65'} + }; + + var signdata = { + key: '0', + loc: [0,0], + signs: [{ + 'package': 'trafficsign_us_3.0', + rect: [ 0.805, 0.463, 0.833, 0.502 ], + length: 4, + score: '1.27', + type: 'regulatory--maximum-speed-limit-65--us' + }] + }; + + expect(mapillary.signHTML(signdata)).to.eql('65') + }); + }); + + describe('#selectedThumbnail', function() { + it('sets thumbnail image', function() { + mapillary.selectedThumbnail('foo'); + expect(iD.services.mapillary.thumb).to.eql('foo'); + }); + + it('gets thumbnail image', function() { + iD.services.mapillary.thumb = 'bar'; + expect(mapillary.selectedThumbnail()).to.eql('bar'); + }); + }); + + describe('#reset', function() { + it('resets cache and thumbnail image', function() { + iD.services.mapillary.cache.foo = 'bar'; + iD.services.mapillary.thumb = 'bar'; + + mapillary.reset(); + expect(iD.services.mapillary.cache).to.not.have.property('foo'); + expect(iD.services.mapillary.thumb).to.be.null; + }); }); });