describe('iD.serviceStreetside', function() { var dimensions = [64, 64]; var context, server, streetside; before(function() { iD.services.streetside = iD.serviceStreetside; }); after(function() { delete iD.services.streetside; }); beforeEach(function() { context = iD.coreContext().assetPath('../dist/').init(); context.projection .scale(iD.geoZoomToScale(14)) .translate([-116508, 0]) // 10,0 .clipExtent([[0,0], dimensions]); server = window.fakeFetch().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 loadedImages when bubbles are loaded', function(done) { // adjust projection so that only one tile is fetched // (JSONP hack will return the same data for every fetch) context.projection .scale(iD.geoZoomToScale(18)) .translate([-1863988.9381333336, 762.8270222954452]) // 10.002,0.002 .clipExtent([[0,0], dimensions]); var spy = sinon.spy(); streetside.on('loadedImages', 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, 0); // 0 = don't fetch margin tiles window.setTimeout(function() { expect(spy).to.have.been.calledOnce; done(); }, 200); }); it('does not load bubbles around null island', function(done) { context.projection .scale(iD.geoZoomToScale(18)) .translate([0, 0]) .clipExtent([[0,0], dimensions]); var spy = sinon.spy(); streetside.on('loadedImages', 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, 0); // 0 = don't fetch margin tiles window.setTimeout(function() { expect(spy).to.have.been.not.called; done(); }, 200); }); }); 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 5 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: 6, pano: true, sequence_id: 1 } }, { minX: 10, minY: 0, maxX: 10, maxY: 0, data: { key: 6, loc: [10, 0], ca: 90, pr: 5, 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(5); }); }); 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]); }); }); });