diff --git a/test/index.html b/test/index.html index 186d6ac5f..b2254e67c 100644 --- a/test/index.html +++ b/test/index.html @@ -106,6 +106,7 @@ + diff --git a/test/spec/services/streetside.js b/test/spec/services/streetside.js new file mode 100644 index 000000000..601f62eca --- /dev/null +++ b/test/spec/services/streetside.js @@ -0,0 +1,178 @@ +describe('iD.serviceStreetside', function() { + var dimensions = [64, 64], + context, server, streetside; + + before(function() { + iD.services.streetside = iD.serviceStreetside; + }); + + after(function() { + delete iD.services.streetside; + }); + + beforeEach(function() { + context = iD.Context().assetPath('../dist/'); + context.projection + .scale(667544.214430109) // z14 + .translate([-116508, 0]) // 10,0 + .clipExtent([[0,0], dimensions]); + + server = sinon.fakeServer.create(); + streetside = iD.services.streetside; + streetside.reset(); + }); + + afterEach(function() { + window.JSONP_FIX = undefined; + server.restore(); + }); + + + describe('#init', function() { + it('Initializes cache one time', function() { + var cache = streetside.cache(); + expect(cache).to.have.property('bubbles'); + expect(cache).to.have.property('sequences'); + + streetside.init(); + var cache2 = streetside.cache(); + expect(cache).to.equal(cache2); + }); + }); + + describe('#reset', function() { + it('resets cache', function() { + streetside.cache().foo = 'bar'; + streetside.reset(); + expect(streetside.cache()).to.not.have.property('foo'); + }); + }); + + describe('#loadBubbles', function() { + it('fires loadedBubbles when bubbles are loaded', function() { + // adjust projection so that only one tile is fetched + // (JSONP hack will return the same data for every fetch) + context.projection + .scale(10680707.430881744) // z18 + .translate([-1863988.9381333336, 762.8270222954452]) // 10.002,0.002 + .clipExtent([[0,0], dimensions]); + + var spy = sinon.spy(); + streetside.on('loadedBubbles', spy); + + window.JSONP_DELAY = 0; + window.JSONP_FIX = [{ + elapsed: 0.001 + }, { + id: 1, la: 0, lo: 10.001, al: 0, ro: 0, pi: 0, he: 0, bl: '', + cd: '1/1/2018 12:00:00 PM', ml: 3, nbn: [], pbn: [], rn: [], + pr: undefined, ne: 2 + }, { + id: 2, la: 0, lo: 10.002, al: 0, ro: 0, pi: 0, he: 0, bl: '', + cd: '1/1/2018 12:00:01 PM', ml: 3, nbn: [], pbn: [], rn: [], + pr: 1, ne: 3 + }, { + id: 3, la: 0, lo: 10.003, al: 0, ro: 0, pi: 0, he: 0, bl: '', + cd: '1/1/2018 12:00:02 PM', ml: 3, nbn: [], pbn: [], rn: [], + pr: 2, ne: undefined + } + ]; + + streetside.loadBubbles(context.projection); + expect(spy).to.have.been.calledOnce; + }); + + it('does not load bubbles around null island', function() { + context.projection + .scale(10680707.430881744) // z18 + .translate([0, 0]) + .clipExtent([[0,0], dimensions]); + + var spy = sinon.spy(); + streetside.on('loadedBubbles', spy); + + window.JSONP_DELAY = 0; + window.JSONP_FIX = [{ + elapsed: 0.001 + }, { + id: 1, la: 0, lo: 0, al: 0, ro: 0, pi: 0, he: 0, bl: '', + cd: '1/1/2018 12:00:00 PM', ml: 3, nbn: [], pbn: [], rn: [], + pr: undefined, ne: 2 + }, { + id: 2, la: 0, lo: 0, al: 0, ro: 0, pi: 0, he: 0, bl: '', + cd: '1/1/2018 12:00:01 PM', ml: 3, nbn: [], pbn: [], rn: [], + pr: 1, ne: 3 + }, { + id: 3, la: 0, lo: 0, al: 0, ro: 0, pi: 0, he: 0, bl: '', + cd: '1/1/2018 12:00:02 PM', ml: 3, nbn: [], pbn: [], rn: [], + pr: 2, ne: undefined + } + ]; + + streetside.loadBubbles(context.projection); + expect(spy).to.have.been.not.called; + }); + }); + + + describe('#bubbles', function() { + it('returns bubbles in the visible map area', function() { + var features = [ + { minX: 10, minY: 0, maxX: 10, maxY: 0, data: { key: 1, loc: [10, 0], ca: 90, pr: undefined, ne: 2, pano: true, sequenceKey: 1 } }, + { minX: 10, minY: 0, maxX: 10, maxY: 0, data: { key: 2, loc: [10, 0], ca: 90, pr: 1, ne: 3, pano: true, sequenceKey: 1 } }, + { minX: 10, minY: 1, maxX: 10, maxY: 1, data: { key: 3, loc: [10, 1], ca: 90, pr: 2, ne: undefined, pano: true, sequenceKey: 1 } } + ]; + + streetside.cache().bubbles.rtree.load(features); + var res = streetside.bubbles(context.projection); + + expect(res).to.deep.eql([ + { key: 1, loc: [10, 0], ca: 90, pr: undefined, ne: 2, pano: true, sequenceKey: 1 }, + { key: 2, loc: [10, 0], ca: 90, pr: 1, ne: 3, pano: true, sequenceKey: 1 } + ]); + }); + + it('limits results no more than 3 stacked bubbles in one spot', function() { + var features = [ + { minX: 10, minY: 0, maxX: 10, maxY: 0, data: { key: 1, loc: [10, 0], ca: 90, pr: undefined, ne: 2, pano: true, sequence_id: 1 } }, + { minX: 10, minY: 0, maxX: 10, maxY: 0, data: { key: 2, loc: [10, 0], ca: 90, pr: 1, ne: 3, pano: true, sequence_id: 1 } }, + { minX: 10, minY: 0, maxX: 10, maxY: 0, data: { key: 3, loc: [10, 0], ca: 90, pr: 2, ne: 4, pano: true, sequence_id: 1 } }, + { minX: 10, minY: 0, maxX: 10, maxY: 0, data: { key: 4, loc: [10, 0], ca: 90, pr: 3, ne: 5, pano: true, sequence_id: 1 } }, + { minX: 10, minY: 0, maxX: 10, maxY: 0, data: { key: 5, loc: [10, 0], ca: 90, pr: 4, ne: undefined, pano: true, sequence_id: 1 } } + ]; + + streetside.cache().bubbles.rtree.load(features); + var res = streetside.bubbles(context.projection); + expect(res).to.have.length.of.at.most(3); + }); + }); + + + describe('#sequences', function() { + it('returns sequence linestrings in the visible map area', function() { + var features = [ + { minX: 10, minY: 0, maxX: 10, maxY: 0, data: { key: 1, loc: [10, 0], ca: 90, pr: undefined, ne: 2, pano: true, sequenceKey: 1 } }, + { minX: 10, minY: 0, maxX: 10, maxY: 0, data: { key: 2, loc: [10, 0], ca: 90, pr: 1, ne: 3, pano: true, sequenceKey: 1 } }, + { minX: 10, minY: 1, maxX: 10, maxY: 1, data: { key: 3, loc: [10, 1], ca: 90, pr: 2, ne: undefined, pano: true, sequenceKey: 1 } } + ]; + + streetside.cache().bubbles.rtree.load(features); + + var seq = { + key: 1, + bubbles: features.map(function(f) { return f.data; }), + geojson: { + type: 'LineString', + properties: { key: 1 }, + coordinates: features.map(function(f) { return f.data.loc; }), + } + }; + + streetside.cache().sequences[1] = seq; + + var res = streetside.sequences(context.projection); + expect(res).to.deep.eql([seq.geojson]); + }); + }); + +});