mirror of
https://github.com/FoggedLens/iD.git
synced 2026-02-13 01:02:58 +00:00
Switch mapillary and openstreetcam tests to work async
- can't reliably use sinon.spy to tell whether a thing has been called, so we listen for events instead and check server.requests() - make sure to request the next page before dispatching `loadedImages` so we can `server.respond()` to the request in the event handler if we want to - also moves `localeDateString` in the openstreetcam service from parsing code to display code, because it's very slow (we can just do this for the images we look at, instead of all images we fetch)
This commit is contained in:
@@ -180,18 +180,18 @@ function loadNextTilePage(which, currZoom, url, tile) {
|
||||
cache.rtree.load(features);
|
||||
}
|
||||
|
||||
if (which === 'images' || which === 'sequences') {
|
||||
dispatch.call('loadedImages');
|
||||
} else if (which === 'map_features') {
|
||||
dispatch.call('loadedSigns');
|
||||
}
|
||||
|
||||
if (data.features.length === maxResults) { // more pages to load
|
||||
cache.nextPage[tile.id] = nextPage + 1;
|
||||
loadNextTilePage(which, currZoom, url, tile);
|
||||
} else {
|
||||
cache.nextPage[tile.id] = Infinity; // no more pages to load
|
||||
}
|
||||
|
||||
if (which === 'images' || which === 'sequences') {
|
||||
dispatch.call('loadedImages');
|
||||
} else if (which === 'map_features') {
|
||||
dispatch.call('loadedSigns');
|
||||
}
|
||||
})
|
||||
.catch(function() {
|
||||
cache.loaded[id] = true;
|
||||
@@ -326,7 +326,7 @@ export default {
|
||||
},
|
||||
|
||||
|
||||
loadSigns: function(context, projection) {
|
||||
loadSigns: function(projection) {
|
||||
// if we are looking at signs, we'll actually need to fetch images too
|
||||
loadTiles('images', apibase + 'images?', projection);
|
||||
loadTiles('map_features', apibase + 'map_features?layers=trafficsigns&min_nbr_image_detections=1&', projection);
|
||||
|
||||
@@ -95,15 +95,6 @@ function loadNextTilePage(which, currZoom, url, tile) {
|
||||
throw new Error('No Data');
|
||||
}
|
||||
|
||||
function localeDateString(s) {
|
||||
if (!s) return null;
|
||||
var detected = utilDetect();
|
||||
var options = { day: 'numeric', month: 'short', year: 'numeric' };
|
||||
var d = new Date(s);
|
||||
if (isNaN(d.getTime())) return null;
|
||||
return d.toLocaleDateString(detected.locale, options);
|
||||
}
|
||||
|
||||
var features = data.currentPageItems.map(function(item) {
|
||||
var loc = [+item.lng, +item.lat];
|
||||
var d;
|
||||
@@ -113,7 +104,7 @@ function loadNextTilePage(which, currZoom, url, tile) {
|
||||
loc: loc,
|
||||
key: item.id,
|
||||
ca: +item.heading,
|
||||
captured_at: localeDateString(item.shot_date || item.date_added),
|
||||
captured_at: (item.shot_date || item.date_added),
|
||||
captured_by: item.username,
|
||||
imagePath: item.lth_name,
|
||||
sequence_id: item.sequence_id,
|
||||
@@ -136,16 +127,16 @@ function loadNextTilePage(which, currZoom, url, tile) {
|
||||
|
||||
cache.rtree.load(features);
|
||||
|
||||
if (which === 'images') {
|
||||
dispatch.call('loadedImages');
|
||||
}
|
||||
|
||||
if (data.currentPageItems.length === maxResults) { // more pages to load
|
||||
cache.nextPage[tile.id] = nextPage + 1;
|
||||
loadNextTilePage(which, currZoom, url, tile);
|
||||
} else {
|
||||
cache.nextPage[tile.id] = Infinity; // no more pages to load
|
||||
}
|
||||
|
||||
if (which === 'images') {
|
||||
dispatch.call('loadedImages');
|
||||
}
|
||||
})
|
||||
.catch(function() {
|
||||
cache.loaded[id] = true;
|
||||
@@ -439,7 +430,7 @@ export default {
|
||||
attribution
|
||||
.append('span')
|
||||
.attr('class', 'captured_at')
|
||||
.text(d.captured_at);
|
||||
.text(localeDateString(d.captured_at));
|
||||
|
||||
attribution
|
||||
.append('span')
|
||||
@@ -453,7 +444,18 @@ export default {
|
||||
.attr('href', 'https://openstreetcam.org/details/' + d.sequence_id + '/' + d.sequence_index)
|
||||
.text('openstreetcam.org');
|
||||
}
|
||||
|
||||
return this;
|
||||
|
||||
|
||||
function localeDateString(s) {
|
||||
if (!s) return null;
|
||||
var detected = utilDetect();
|
||||
var options = { day: 'numeric', month: 'short', year: 'numeric' };
|
||||
var d = new Date(s);
|
||||
if (isNaN(d.getTime())) return null;
|
||||
return d.toLocaleDateString(detected.locale, options);
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
|
||||
@@ -142,7 +142,7 @@ export function svgMapillarySigns(projection, context, dispatch) {
|
||||
if (service && ~~context.map().zoom() >= minZoom) {
|
||||
editOn();
|
||||
update();
|
||||
service.loadSigns(context, projection);
|
||||
service.loadSigns(projection);
|
||||
} else {
|
||||
editOff();
|
||||
}
|
||||
|
||||
@@ -55,11 +55,13 @@ describe('iD.serviceMapillary', function() {
|
||||
|
||||
describe('#loadImages', function() {
|
||||
it('fires loadedImages when images are loaded', function(done) {
|
||||
var spy = sinon.spy();
|
||||
mapillary.on('loadedImages', spy);
|
||||
mapillary.on('loadedImages', function() {
|
||||
expect(server.requests().length).to.eql(2); // 1 images, 1 sequences
|
||||
done();
|
||||
});
|
||||
|
||||
mapillary.loadImages(context.projection);
|
||||
|
||||
var match = /images/;
|
||||
var features = [{
|
||||
type: 'Feature',
|
||||
geometry: { type: 'Point', coordinates: [10,0] },
|
||||
@@ -67,23 +69,18 @@ describe('iD.serviceMapillary', function() {
|
||||
}];
|
||||
var response = { type: 'FeatureCollection', features: features };
|
||||
|
||||
server.respondWith('GET', match,
|
||||
server.respondWith('GET', /images/,
|
||||
[200, { 'Content-Type': 'application/json' }, JSON.stringify(response) ]);
|
||||
server.respond();
|
||||
|
||||
window.setTimeout(function() {
|
||||
expect(spy).to.have.been.calledOnce;
|
||||
done();
|
||||
}, 200);
|
||||
});
|
||||
|
||||
it('does not load images around null island', function(done) {
|
||||
var spy = sinon.spy();
|
||||
context.projection.translate([0,0]);
|
||||
|
||||
mapillary.on('loadedImages', spy);
|
||||
mapillary.loadImages(context.projection);
|
||||
|
||||
var match = /images/;
|
||||
var features = [{
|
||||
type: 'Feature',
|
||||
geometry: { type: 'Point', coordinates: [0,0] },
|
||||
@@ -91,70 +88,72 @@ describe('iD.serviceMapillary', function() {
|
||||
}];
|
||||
var response = { type: 'FeatureCollection', features: features };
|
||||
|
||||
server.respondWith('GET', match,
|
||||
server.respondWith('GET', /images/,
|
||||
[200, { 'Content-Type': 'application/json' }, JSON.stringify(response) ]);
|
||||
server.respond();
|
||||
|
||||
window.setTimeout(function() {
|
||||
expect(spy).to.have.been.not.called;
|
||||
expect(server.requests().length).to.eql(0); // no tile requests of any kind
|
||||
done();
|
||||
}, 200);
|
||||
});
|
||||
|
||||
it.skip('loads multiple pages of image results', function(done) {
|
||||
var spy = sinon.spy();
|
||||
mapillary.on('loadedImages', spy);
|
||||
it('loads multiple pages of image results', function(done) {
|
||||
var calls = 0;
|
||||
mapillary.on('loadedImages', function() {
|
||||
server.respond(); // respond to new fetches
|
||||
if (++calls === 2) {
|
||||
expect(server.requests().length).to.eql(3); // 2 images, 1 sequences
|
||||
done();
|
||||
}
|
||||
});
|
||||
|
||||
mapillary.loadImages(context.projection);
|
||||
|
||||
var features0 = [];
|
||||
var features1 = [];
|
||||
var i;
|
||||
var i, key;
|
||||
|
||||
for (i = 0; i < 1000; i++) {
|
||||
key = String(i);
|
||||
features0.push({
|
||||
type: 'Feature',
|
||||
geometry: { type: 'Point', coordinates: [10,0] },
|
||||
properties: { ca: 90, key: String(i) }
|
||||
properties: { ca: 90, key: key }
|
||||
});
|
||||
}
|
||||
for (i = 0; i < 500; i++) {
|
||||
key = String(1000 + i);
|
||||
features1.push({
|
||||
type: 'Feature',
|
||||
geometry: { type: 'Point', coordinates: [10,0] },
|
||||
properties: { ca: 90, key: String(1000 + i) }
|
||||
properties: { ca: 90, key: key }
|
||||
});
|
||||
}
|
||||
|
||||
var match0 = /page=0/;
|
||||
var response0 = { type: 'FeatureCollection', features: features0 };
|
||||
var match1 = /page=1/;
|
||||
var response1 = { type: 'FeatureCollection', features: features1 };
|
||||
|
||||
server.respondWith('GET', match0,
|
||||
server.respondWith('GET', /\/images\?.*&page=0/,
|
||||
[200, { 'Content-Type': 'application/json' }, JSON.stringify(response0) ]);
|
||||
server.respondWith('GET', match1,
|
||||
server.respondWith('GET', /\/images\?.*&page=1/,
|
||||
[200, { 'Content-Type': 'application/json' }, JSON.stringify(response1) ]);
|
||||
server.respond();
|
||||
|
||||
window.setTimeout(function() {
|
||||
expect(spy).to.have.been.calledTwice;
|
||||
done();
|
||||
}, 200);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
describe('#loadSigns', function() {
|
||||
it('fires loadedSigns when signs are loaded', function(done) {
|
||||
var spy = sinon.spy();
|
||||
mapillary.on('loadedSigns', spy);
|
||||
mapillary.loadSigns(context, context.projection);
|
||||
mapillary.on('loadedSigns', function() {
|
||||
expect(server.requests().length).to.eql(3); // 1 images, 1 map_features, 1 image_detections
|
||||
done();
|
||||
});
|
||||
|
||||
var match = /map_features/;
|
||||
var detections = [{
|
||||
detection_key: '0',
|
||||
image_key: '0'
|
||||
}];
|
||||
mapillary.loadSigns(context.projection);
|
||||
|
||||
var detections = [{ detection_key: '0', image_key: '0' }];
|
||||
var features = [{
|
||||
type: 'Feature',
|
||||
geometry: { type: 'Point', coordinates: [10,0] },
|
||||
@@ -162,27 +161,19 @@ describe('iD.serviceMapillary', function() {
|
||||
}];
|
||||
var response = { type: 'FeatureCollection', features: features };
|
||||
|
||||
server.respondWith('GET', match,
|
||||
server.respondWith('GET', /map_features/,
|
||||
[200, { 'Content-Type': 'application/json' }, JSON.stringify(response) ]);
|
||||
server.respond();
|
||||
|
||||
window.setTimeout(function() {
|
||||
expect(spy).to.have.been.calledOnce;
|
||||
done();
|
||||
}, 200);
|
||||
});
|
||||
|
||||
it('does not load signs around null island', function(done) {
|
||||
var spy = sinon.spy();
|
||||
context.projection.translate([0,0]);
|
||||
mapillary.on('loadedSigns', spy);
|
||||
mapillary.loadSigns(context, context.projection);
|
||||
|
||||
var match = /map_features/;
|
||||
var detections = [{
|
||||
detection_key: '0',
|
||||
image_key: '0'
|
||||
}];
|
||||
mapillary.on('loadedSigns', spy);
|
||||
mapillary.loadSigns(context.projection);
|
||||
|
||||
var detections = [{ detection_key: '0', image_key: '0' }];
|
||||
var features = [{
|
||||
type: 'Feature',
|
||||
geometry: { type: 'Point', coordinates: [0,0] },
|
||||
@@ -190,62 +181,60 @@ describe('iD.serviceMapillary', function() {
|
||||
}];
|
||||
var response = { type: 'FeatureCollection', features: features };
|
||||
|
||||
server.respondWith('GET', match,
|
||||
server.respondWith('GET', /map_features/,
|
||||
[200, { 'Content-Type': 'application/json' }, JSON.stringify(response) ]);
|
||||
server.respond();
|
||||
|
||||
window.setTimeout(function() {
|
||||
expect(spy).to.have.been.not.called;
|
||||
expect(server.requests().length).to.eql(0); // no tile requests of any kind
|
||||
done();
|
||||
}, 200);
|
||||
});
|
||||
|
||||
it.skip('loads multiple pages of signs results', function(done) {
|
||||
var spy = sinon.spy();
|
||||
mapillary.on('loadedSigns', spy);
|
||||
mapillary.loadSigns(context, context.projection);
|
||||
it('loads multiple pages of signs results', function(done) {
|
||||
var calls = 0;
|
||||
mapillary.on('loadedSigns', function() {
|
||||
server.respond(); // respond to new fetches
|
||||
if (++calls === 2) {
|
||||
expect(server.requests().length).to.eql(4); // 2 images, 1 map_features, 1 image_detections
|
||||
done();
|
||||
}
|
||||
});
|
||||
|
||||
mapillary.loadSigns(context.projection);
|
||||
|
||||
var rects = [{
|
||||
package: 'trafficsign',
|
||||
rect: [ 0.805, 0.463, 0.833, 0.502 ],
|
||||
length: 4,
|
||||
score: '1.27',
|
||||
type: 'regulatory--maximum-speed-limit-65--us'
|
||||
}];
|
||||
var features0 = [];
|
||||
var features1 = [];
|
||||
var i;
|
||||
var i, key, detections;
|
||||
|
||||
for (i = 0; i < 1000; i++) {
|
||||
key = String(i);
|
||||
detections = [{ detection_key: key, image_key: key }];
|
||||
features0.push({
|
||||
type: 'Feature',
|
||||
geometry: { type: 'Point', coordinates: [10,0] },
|
||||
properties: { rects: rects, key: String(i) }
|
||||
properties: { detections: detections, key: key, value: 'not-in-set' }
|
||||
});
|
||||
}
|
||||
for (i = 0; i < 500; i++) {
|
||||
key = String(1000 + i);
|
||||
detections = [{ detection_key: key, image_key: key }];
|
||||
features1.push({
|
||||
type: 'Feature',
|
||||
geometry: { type: 'Point', coordinates: [10,0] },
|
||||
properties: { rects: rects, key: String(1000 + i) }
|
||||
properties: { detections: detections, key: key, value: 'not-in-set' }
|
||||
});
|
||||
}
|
||||
|
||||
var match0 = /page=0/;
|
||||
var response0 = { type: 'FeatureCollection', features: features0 };
|
||||
var match1 = /page=1/;
|
||||
var response1 = { type: 'FeatureCollection', features: features1 };
|
||||
|
||||
server.respondWith('GET', match0,
|
||||
server.respondWith('GET', /\/map_features\?.*&page=0/,
|
||||
[200, { 'Content-Type': 'application/json' }, JSON.stringify(response0) ]);
|
||||
server.respondWith('GET', match1,
|
||||
server.respondWith('GET', /\/map_features\?.*&page=1/,
|
||||
[200, { 'Content-Type': 'application/json' }, JSON.stringify(response1) ]);
|
||||
server.respond();
|
||||
|
||||
window.setTimeout(function() {
|
||||
expect(spy).to.have.been.calledTwice;
|
||||
done();
|
||||
}, 200);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -283,6 +272,7 @@ describe('iD.serviceMapillary', function() {
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
describe('#signs', function() {
|
||||
it('returns signs in the visible map area', function() {
|
||||
var detections = [{
|
||||
|
||||
@@ -52,8 +52,11 @@ describe('iD.serviceOpenstreetcam', function() {
|
||||
|
||||
describe('#loadImages', function() {
|
||||
it('fires loadedImages when images are loaded', function(done) {
|
||||
var spy = sinon.spy();
|
||||
openstreetcam.on('loadedImages', spy);
|
||||
openstreetcam.on('loadedImages', function() {
|
||||
expect(server.requests().length).to.eql(1); // 1 nearby-photos
|
||||
done();
|
||||
});
|
||||
|
||||
openstreetcam.loadImages(context.projection);
|
||||
|
||||
var data = {
|
||||
@@ -101,16 +104,12 @@ describe('iD.serviceOpenstreetcam', function() {
|
||||
server.respondWith('POST', /nearby-photos/,
|
||||
[200, { 'Content-Type': 'application/json' }, JSON.stringify(data) ]);
|
||||
server.respond();
|
||||
|
||||
window.setTimeout(function() {
|
||||
expect(spy).to.have.been.calledOnce;
|
||||
done();
|
||||
}, 200);
|
||||
});
|
||||
|
||||
it('does not load images around null island', function(done) {
|
||||
var spy = sinon.spy();
|
||||
context.projection.translate([0,0]);
|
||||
|
||||
openstreetcam.on('loadedImages', spy);
|
||||
openstreetcam.loadImages(context.projection);
|
||||
|
||||
@@ -162,76 +161,45 @@ describe('iD.serviceOpenstreetcam', function() {
|
||||
|
||||
window.setTimeout(function() {
|
||||
expect(spy).to.have.been.not.called;
|
||||
expect(server.requests().length).to.eql(0); // no tile requests of any kind
|
||||
done();
|
||||
}, 200);
|
||||
});
|
||||
|
||||
it.skip('loads multiple pages of image results', function(done) {
|
||||
var spy = sinon.spy();
|
||||
openstreetcam.on('loadedImages', spy);
|
||||
it('loads multiple pages of image results', function(done) {
|
||||
openstreetcam.on('loadedImages', function() {
|
||||
expect(server.requests().length).to.eql(2); // 2 nearby-photos
|
||||
done();
|
||||
});
|
||||
|
||||
openstreetcam.loadImages(context.projection);
|
||||
|
||||
var features0 = [],
|
||||
features1 = [],
|
||||
i;
|
||||
|
||||
for (i = 0; i < 1000; i++) {
|
||||
features0.push({
|
||||
id: String(i),
|
||||
var features = [];
|
||||
for (var i = 0; i < 1000; i++) {
|
||||
var key = String(i);
|
||||
features.push({
|
||||
id: key,
|
||||
sequence_id: '100',
|
||||
sequence_index: String(i),
|
||||
sequence_index: key,
|
||||
lat: '10',
|
||||
lng: '0',
|
||||
name: 'storage6\/files\/photo\/foo' + String(i) +'.jpg',
|
||||
lth_name: 'storage6\/files\/photo\/lth\/foo' + String(i) +'.jpg',
|
||||
th_name: 'storage6\/files\/photo\/th\/foo' + String(i) +'.jpg',
|
||||
shot_date: '2017-09-24 23:58:07',
|
||||
heading: '90',
|
||||
username: 'test'
|
||||
});
|
||||
}
|
||||
for (i = 0; i < 500; i++) {
|
||||
features1.push({
|
||||
id: String(i),
|
||||
sequence_id: '100',
|
||||
sequence_index: String(1000 + i),
|
||||
lat: '10',
|
||||
lng: '0',
|
||||
name: 'storage6\/files\/photo\/foo' + String(1000 + i) +'.jpg',
|
||||
lth_name: 'storage6\/files\/photo\/lth\/foo' + String(1000 + i) +'.jpg',
|
||||
th_name: 'storage6\/files\/photo\/th\/foo' + String(1000 + i) +'.jpg',
|
||||
name: 'storage6\/files\/photo\/foo' + key + '.jpg',
|
||||
lth_name: 'storage6\/files\/photo\/lth\/foo' + key + '.jpg',
|
||||
th_name: 'storage6\/files\/photo\/th\/foo' + key + '.jpg',
|
||||
shot_date: '2017-09-24 23:58:07',
|
||||
heading: '90',
|
||||
username: 'test'
|
||||
});
|
||||
}
|
||||
var response = {
|
||||
status: { apiCode: '600', httpCode: 200, httpMessage: 'Success' },
|
||||
currentPageItems: features,
|
||||
totalFilteredItems: ['1000']
|
||||
};
|
||||
|
||||
var response0 = {
|
||||
status: { apiCode: '600', httpCode: 200, httpMessage: 'Success' },
|
||||
currentPageItems: [features0],
|
||||
totalFilteredItems: ['1000']
|
||||
},
|
||||
response1 = {
|
||||
status: { apiCode: '600', httpCode: 200, httpMessage: 'Success' },
|
||||
currentPageItems: [features1],
|
||||
totalFilteredItems: ['500']
|
||||
};
|
||||
|
||||
server.respondWith('POST', /nearby-photos/, function (request) {
|
||||
var response;
|
||||
if (request.requestBody.match(/page=1/) !== null) {
|
||||
response = JSON.stringify(response0);
|
||||
} else if (request.requestBody.match(/page=2/) !== null) {
|
||||
response = JSON.stringify(response1);
|
||||
}
|
||||
request.respond(200, {'Content-Type': 'application/json'}, response);
|
||||
});
|
||||
server.respondWith('POST', /nearby-photos/,
|
||||
[200, { 'Content-Type': 'application/json' }, JSON.stringify(response) ]);
|
||||
server.respond();
|
||||
|
||||
window.setTimeout(function() {
|
||||
expect(spy).to.have.been.calledTwice;
|
||||
done();
|
||||
}, 200);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user