mirror of
https://github.com/FoggedLens/iD.git
synced 2026-05-19 23:14:47 +02:00
Merge branch 'master' into Psigio-3375
This commit is contained in:
+1
-1
@@ -91,7 +91,7 @@
|
||||
|
||||
<script src='spec/presets/category.js'></script>
|
||||
<script src='spec/presets/collection.js'></script>
|
||||
<script src='spec/presets/init.js'></script>
|
||||
<script src='spec/presets/index.js'></script>
|
||||
<script src='spec/presets/preset.js'></script>
|
||||
|
||||
<script src='spec/renderer/background_source.js'></script>
|
||||
|
||||
+1
-1
@@ -46,7 +46,7 @@
|
||||
};
|
||||
|
||||
context.presets = function() {
|
||||
return iD.presetInit().load({
|
||||
return iD.presetIndex().load({
|
||||
presets: {
|
||||
'amenity/restaurant': {
|
||||
geometry: ['point'],
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
describe('iD.actionSplit', function () {
|
||||
|
||||
beforeEach(function () {
|
||||
iD.areaKeys = iD.Context(window)
|
||||
.presets(iD.dataPresets).presets().areaKeys();
|
||||
iD.areaKeys = iD.Context().presets().areaKeys();
|
||||
});
|
||||
|
||||
describe('#disabled', function () {
|
||||
|
||||
@@ -4,17 +4,13 @@ describe('iD.behaviorHash', function () {
|
||||
var hash, context;
|
||||
|
||||
beforeEach(function () {
|
||||
context = iD.Context(window)
|
||||
.imagery(iD.dataImagery);
|
||||
context.container(d3.select(document.createElement('div')));
|
||||
|
||||
// Neuter connection
|
||||
context.connection().loadTiles = function () {};
|
||||
context = iD.Context();
|
||||
context.connection().loadTiles = function () {}; // Neuter connection
|
||||
|
||||
var container = d3.select(document.createElement('div'));
|
||||
context.container(container);
|
||||
container.call(context.map());
|
||||
hash = iD.behaviorHash(context);
|
||||
|
||||
d3.select(document.createElement('div'))
|
||||
.call(context.map());
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
@@ -22,18 +18,14 @@ describe('iD.behaviorHash', function () {
|
||||
});
|
||||
|
||||
it('sets hadHash if location.hash is present', function () {
|
||||
location.hash = 'map=20.00/-77.02405/38.87952';
|
||||
|
||||
location.hash = 'map=20.00/38.87952/-77.02405';
|
||||
hash();
|
||||
|
||||
expect(hash.hadHash).to.be.true;
|
||||
});
|
||||
|
||||
it('centerZooms map to requested level', function () {
|
||||
location.hash = 'map=20.00/-77.02405/38.87952';
|
||||
|
||||
location.hash = 'map=20.00/38.87952/-77.02405';
|
||||
hash();
|
||||
|
||||
expect(context.map().center()[0]).to.be.closeTo(-77.02405, 0.1);
|
||||
expect(context.map().center()[1]).to.be.closeTo(38.87952, 0.1);
|
||||
expect(context.map().zoom()).to.equal(20.0);
|
||||
@@ -41,7 +33,6 @@ describe('iD.behaviorHash', function () {
|
||||
|
||||
it('centerZooms map at requested coordinates on hash change', function (done) {
|
||||
hash();
|
||||
|
||||
d3.select(window).on('hashchange', function () {
|
||||
expect(context.map().center()[0]).to.be.closeTo(-77.02405, 0.1);
|
||||
expect(context.map().center()[1]).to.be.closeTo(38.87952, 0.1);
|
||||
@@ -49,24 +40,17 @@ describe('iD.behaviorHash', function () {
|
||||
d3.select(window).on('hashchange', null);
|
||||
done();
|
||||
});
|
||||
|
||||
location.hash = 'map=20.00/-77.02405/38.87952';
|
||||
location.hash = 'map=20.00/38.87952/-77.02405';
|
||||
});
|
||||
|
||||
it('stores the current zoom and coordinates in location.hash on map move events', function () {
|
||||
location.hash = '';
|
||||
|
||||
hash();
|
||||
|
||||
var clock = sinon.useFakeTimers();
|
||||
|
||||
context.map().center([38.9, -77.0]);
|
||||
context.map().center([-77.0, 38.9]);
|
||||
context.map().zoom(2.0);
|
||||
|
||||
clock.tick(500);
|
||||
|
||||
expect(location.hash).to.equal('#map=2.00/38.9/-77.0');
|
||||
|
||||
clock.restore();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,17 +1,12 @@
|
||||
describe('iD.behaviorLasso', function () {
|
||||
var lasso, context;
|
||||
var context, lasso;
|
||||
|
||||
beforeEach(function () {
|
||||
context = iD.Context(window).imagery(iD.dataImagery);
|
||||
context.container(d3.select(document.createElement('div')));
|
||||
|
||||
// Neuter connection
|
||||
context.connection().loadTiles = function () {};
|
||||
|
||||
lasso = iD.behaviorLasso(context);
|
||||
|
||||
context = iD.Context();
|
||||
d3.select(document.createElement('div'))
|
||||
.attr('id', 'map')
|
||||
.call(context.map());
|
||||
lasso = iD.behaviorLasso(context);
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
|
||||
@@ -3,7 +3,7 @@ describe('iD.behaviorSelect', function() {
|
||||
|
||||
beforeEach(function() {
|
||||
container = d3.select('body').append('div');
|
||||
context = iD.Context(window).imagery(iD.dataImagery).container(container);
|
||||
context = iD.Context().container(container);
|
||||
|
||||
a = iD.Node({loc: [0, 0]});
|
||||
b = iD.Node({loc: [0, 0]});
|
||||
@@ -31,6 +31,18 @@ describe('iD.behaviorSelect', function() {
|
||||
container.remove();
|
||||
});
|
||||
|
||||
specify('refuse to enter select mode with no ids', function() {
|
||||
context.enter(iD.modeSelect(context, []));
|
||||
expect(context.mode().id, 'empty array').to.eql('browse');
|
||||
context.enter(iD.modeSelect(context, undefined));
|
||||
expect(context.mode().id, 'undefined').to.eql('browse');
|
||||
});
|
||||
|
||||
specify('refuse to enter select mode with nonexistent ids', function() {
|
||||
context.enter(iD.modeSelect(context, ['w-1']));
|
||||
expect(context.mode().id).to.eql('browse');
|
||||
});
|
||||
|
||||
specify('click on entity selects the entity', function() {
|
||||
happen.click(context.surface().selectAll('.' + a.id).node());
|
||||
expect(context.selectedIDs()).to.eql([a.id]);
|
||||
|
||||
@@ -5,7 +5,7 @@ describe('iD.Context', function() {
|
||||
|
||||
describe('#assetPath', function() {
|
||||
it('sets and gets assetPath', function() {
|
||||
var context = iD.Context(window);
|
||||
var context = iD.Context();
|
||||
expect(context.assetPath()).to.eql('');
|
||||
|
||||
context.assetPath('iD/');
|
||||
@@ -15,7 +15,7 @@ describe('iD.Context', function() {
|
||||
|
||||
describe('#assetMap', function() {
|
||||
it('sets and gets assetMap', function() {
|
||||
var context = iD.Context(window);
|
||||
var context = iD.Context();
|
||||
expect(context.assetMap()).to.eql({});
|
||||
|
||||
context.assetMap(assets);
|
||||
@@ -26,7 +26,7 @@ describe('iD.Context', function() {
|
||||
describe('#asset', function() {
|
||||
var context;
|
||||
beforeEach(function() {
|
||||
context = iD.Context(window).assetPath('iD/').assetMap(assets);
|
||||
context = iD.Context().assetPath('iD/').assetMap(assets);
|
||||
});
|
||||
|
||||
it('looks first in assetMap', function() {
|
||||
@@ -40,7 +40,7 @@ describe('iD.Context', function() {
|
||||
describe('#imagePath', function() {
|
||||
var context;
|
||||
beforeEach(function() {
|
||||
context = iD.Context(window).assetPath('iD/').assetMap(assets);
|
||||
context = iD.Context().assetPath('iD/').assetMap(assets);
|
||||
});
|
||||
|
||||
it('looks first in assetMap', function() {
|
||||
@@ -51,57 +51,9 @@ describe('iD.Context', function() {
|
||||
});
|
||||
});
|
||||
|
||||
describe('#presets', function() {
|
||||
it('supports custom presets', function() {
|
||||
var presetsCollection = {
|
||||
presets: {
|
||||
'mines': {
|
||||
geometry: ['point', 'area'],
|
||||
name: 'Mining Concession',
|
||||
tags: { 'concession': 'mining' }
|
||||
},
|
||||
'area': {
|
||||
'name': 'Area',
|
||||
'tags': {},
|
||||
'geometry': ['area']
|
||||
},
|
||||
'point': {
|
||||
'name': 'Point',
|
||||
'tags': {},
|
||||
'geometry': ['point']
|
||||
},
|
||||
'line': {
|
||||
'name': 'Line',
|
||||
'tags': {},
|
||||
'geometry': ['line']
|
||||
},
|
||||
'vertex': {
|
||||
'name': 'Other',
|
||||
'tags': {},
|
||||
'geometry': ['vertex']
|
||||
}
|
||||
},
|
||||
fields: {
|
||||
'name': {
|
||||
'key': 'name',
|
||||
'type': 'localized',
|
||||
'label': 'Name',
|
||||
'placeholder': 'Common name (if any)'
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
var context = iD.Context(window).presets(presetsCollection),
|
||||
way = iD.Way({tags: {concession: 'mining', area: 'yes'}}),
|
||||
graph = iD.Graph([way]);
|
||||
|
||||
expect(context.presets().match(way, graph).id).to.eql('mines');
|
||||
});
|
||||
});
|
||||
|
||||
describe('#debug', function() {
|
||||
it('sets and gets debug flags', function() {
|
||||
var context = iD.Context(window),
|
||||
var context = iD.Context(),
|
||||
flags = {
|
||||
tile: false,
|
||||
collision: false,
|
||||
|
||||
@@ -3,7 +3,7 @@ describe('iD.History', function () {
|
||||
action = function() { return iD.Graph(); };
|
||||
|
||||
beforeEach(function () {
|
||||
context = iD.Context(window);
|
||||
context = iD.Context();
|
||||
history = context.history();
|
||||
spy = sinon.spy();
|
||||
// clear lock
|
||||
|
||||
@@ -38,6 +38,16 @@ describe('d3.keybinding', function() {
|
||||
expect(spy).to.have.been.calledOnce;
|
||||
});
|
||||
|
||||
it('adds multiple bindings given an array of keys', function () {
|
||||
d3.select(document).call(keybinding.on(['A','B'], spy));
|
||||
|
||||
happen.keydown(document, {keyCode: 65});
|
||||
expect(spy).to.have.been.calledOnce;
|
||||
|
||||
happen.keydown(document, {keyCode: 66});
|
||||
expect(spy).to.have.been.calledTwice;
|
||||
});
|
||||
|
||||
it('does not dispatch when focus is in input elements by default', function () {
|
||||
d3.select(document).call(keybinding.on('A', spy));
|
||||
|
||||
|
||||
@@ -4,9 +4,7 @@ describe.skip('iD.modeAddPoint', function() {
|
||||
beforeEach(function() {
|
||||
var container = d3.select(document.createElement('div'));
|
||||
|
||||
context = iD.Context(window)
|
||||
.presets(iD.dataPresets)
|
||||
.imagery([])
|
||||
context = iD.Context()
|
||||
.container(container);
|
||||
|
||||
context.loadTiles = function () {};
|
||||
|
||||
@@ -318,7 +318,7 @@ describe('iD.osmWay', function() {
|
||||
|
||||
describe('#isArea', function() {
|
||||
before(function() {
|
||||
iD.Context(window).presets(iD.dataPresets);
|
||||
iD.Context();
|
||||
});
|
||||
|
||||
it('returns false when the way has no tags', function() {
|
||||
|
||||
@@ -1,65 +1,84 @@
|
||||
describe('iD.presetInit', function() {
|
||||
var p = {
|
||||
point: {
|
||||
tags: {},
|
||||
geometry: ['point']
|
||||
},
|
||||
line: {
|
||||
tags: {},
|
||||
geometry: ['line']
|
||||
},
|
||||
vertex: {
|
||||
tags: {},
|
||||
geometry: ['vertex']
|
||||
},
|
||||
residential: {
|
||||
tags: { highway: 'residential' },
|
||||
geometry: ['line']
|
||||
},
|
||||
park: {
|
||||
tags: { leisure: 'park' },
|
||||
geometry: ['point', 'area']
|
||||
}
|
||||
};
|
||||
describe('iD.presetIndex', function() {
|
||||
var savedPresets;
|
||||
|
||||
var c = iD.presetInit().load({presets: p});
|
||||
before(function () {
|
||||
savedPresets = iD.data.presets;
|
||||
});
|
||||
|
||||
after(function () {
|
||||
iD.data.presets = savedPresets;
|
||||
});
|
||||
|
||||
describe('#match', function() {
|
||||
var testPresets = {
|
||||
presets: {
|
||||
point: {
|
||||
tags: {},
|
||||
geometry: ['point']
|
||||
},
|
||||
line: {
|
||||
tags: {},
|
||||
geometry: ['line']
|
||||
},
|
||||
vertex: {
|
||||
tags: {},
|
||||
geometry: ['vertex']
|
||||
},
|
||||
residential: {
|
||||
tags: { highway: 'residential' },
|
||||
geometry: ['line']
|
||||
},
|
||||
park: {
|
||||
tags: { leisure: 'park' },
|
||||
geometry: ['point', 'area']
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
it('returns a collection containing presets matching a geometry and tags', function() {
|
||||
var way = iD.Way({ tags: { highway: 'residential' } }),
|
||||
iD.data.presets = testPresets;
|
||||
var presets = iD.Context().presets(),
|
||||
way = iD.Way({ tags: { highway: 'residential' } }),
|
||||
graph = iD.Graph([way]);
|
||||
expect(c.match(way, graph).id).to.eql('residential');
|
||||
|
||||
expect(presets.match(way, graph).id).to.eql('residential');
|
||||
});
|
||||
|
||||
it('returns the appropriate fallback preset when no tags match', function() {
|
||||
var point = iD.Node(),
|
||||
iD.data.presets = testPresets;
|
||||
var presets = iD.Context().presets(),
|
||||
point = iD.Node(),
|
||||
line = iD.Way({ tags: { foo: 'bar' } }),
|
||||
graph = iD.Graph([point, line]);
|
||||
|
||||
expect(c.match(point, graph).id).to.eql('point');
|
||||
expect(c.match(line, graph).id).to.eql('line');
|
||||
expect(presets.match(point, graph).id).to.eql('point');
|
||||
expect(presets.match(line, graph).id).to.eql('line');
|
||||
});
|
||||
|
||||
it('matches vertices on a line as vertices', function() {
|
||||
var point = iD.Node({ tags: { leisure: 'park' } }),
|
||||
iD.data.presets = testPresets;
|
||||
var presets = iD.Context().presets(),
|
||||
point = iD.Node({ tags: { leisure: 'park' } }),
|
||||
line = iD.Way({ nodes: [point.id], tags: { 'highway': 'residential' } }),
|
||||
graph = iD.Graph([point, line]);
|
||||
|
||||
expect(c.match(point, graph).id).to.eql('vertex');
|
||||
expect(presets.match(point, graph).id).to.eql('vertex');
|
||||
});
|
||||
|
||||
it('matches vertices on an addr:interpolation line as points', function() {
|
||||
var point = iD.Node({ tags: { leisure: 'park' } }),
|
||||
iD.data.presets = testPresets;
|
||||
var presets = iD.Context().presets(),
|
||||
point = iD.Node({ tags: { leisure: 'park' } }),
|
||||
line = iD.Way({ nodes: [point.id], tags: { 'addr:interpolation': 'even' } }),
|
||||
graph = iD.Graph([point, line]);
|
||||
|
||||
expect(c.match(point, graph).id).to.eql('park');
|
||||
expect(presets.match(point, graph).id).to.eql('park');
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
|
||||
describe('#areaKeys', function() {
|
||||
var presets = iD.presetInit().load({
|
||||
var testPresets = {
|
||||
presets: {
|
||||
'amenity/fuel/shell': {
|
||||
tags: { 'amenity': 'fuel' },
|
||||
@@ -91,62 +110,78 @@ describe('iD.presetInit', function() {
|
||||
geometry: ['point', 'area']
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
it('whitelists keys for presets with area geometry', function() {
|
||||
iD.data.presets = testPresets;
|
||||
var presets = iD.Context().presets();
|
||||
expect(presets.areaKeys()).to.include.keys('natural');
|
||||
});
|
||||
|
||||
it('blacklists key-values for presets with a line geometry', function() {
|
||||
iD.data.presets = testPresets;
|
||||
var presets = iD.Context().presets();
|
||||
expect(presets.areaKeys().natural).to.include.keys('tree_row');
|
||||
expect(presets.areaKeys().natural.tree_row).to.be.true;
|
||||
});
|
||||
|
||||
it('does not blacklist key-values for presets with both area and line geometry', function() {
|
||||
iD.data.presets = testPresets;
|
||||
var presets = iD.Context().presets();
|
||||
expect(presets.areaKeys().golf).not.to.include.keys('water_hazard');
|
||||
});
|
||||
|
||||
it('does not blacklist key-values for presets with neither area nor line geometry', function() {
|
||||
iD.data.presets = testPresets;
|
||||
var presets = iD.Context().presets();
|
||||
expect(presets.areaKeys().natural).not.to.include.keys('peak');
|
||||
});
|
||||
|
||||
it('does not blacklist generic \'*\' key-values', function() {
|
||||
iD.data.presets = testPresets;
|
||||
var presets = iD.Context().presets();
|
||||
expect(presets.areaKeys().natural).not.to.include.keys('natural');
|
||||
});
|
||||
|
||||
it('ignores keys like \'highway\' that are assumed to be lines', function() {
|
||||
iD.data.presets = testPresets;
|
||||
var presets = iD.Context().presets();
|
||||
expect(presets.areaKeys()).not.to.include.keys('highway');
|
||||
});
|
||||
|
||||
it('ignores suggestion presets', function() {
|
||||
iD.data.presets = testPresets;
|
||||
var presets = iD.Context().presets();
|
||||
expect(presets.areaKeys()).not.to.include.keys('amenity');
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('expected matches', function() {
|
||||
var presets;
|
||||
|
||||
before(function() {
|
||||
presets = iD.presetInit().load(iD.dataPresets);
|
||||
});
|
||||
describe('expected matches', function() {
|
||||
|
||||
it('prefers building to multipolygon', function() {
|
||||
var relation = iD.Relation({tags: {type: 'multipolygon', building: 'yes'}}),
|
||||
graph = iD.Graph([relation]);
|
||||
iD.data.presets = savedPresets;
|
||||
var presets = iD.Context().presets(),
|
||||
relation = iD.Relation({ tags: { type: 'multipolygon', building: 'yes' }}),
|
||||
graph = iD.Graph([relation]);
|
||||
expect(presets.match(relation, graph).id).to.eql('building');
|
||||
});
|
||||
|
||||
it('prefers building to address', function() {
|
||||
var way = iD.Way({tags: {area: 'yes', building: 'yes', 'addr:housenumber': '1234'}}),
|
||||
iD.data.presets = savedPresets;
|
||||
var presets = iD.Context().presets(),
|
||||
way = iD.Way({ tags: { area: 'yes', building: 'yes', 'addr:housenumber': '1234' }}),
|
||||
graph = iD.Graph([way]);
|
||||
expect(presets.match(way, graph).id).to.eql('building');
|
||||
});
|
||||
|
||||
it('prefers pedestrian to area', function() {
|
||||
var way = iD.Way({tags: {area: 'yes', highway: 'pedestrian'}}),
|
||||
iD.data.presets = savedPresets;
|
||||
var presets = iD.Context().presets(),
|
||||
way = iD.Way({ tags: { area: 'yes', highway: 'pedestrian' }}),
|
||||
graph = iD.Graph([way]);
|
||||
expect(presets.match(way, graph).id).to.eql('highway/pedestrian');
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
@@ -1,10 +1,12 @@
|
||||
describe('iD.Features', function() {
|
||||
var dimensions = [1000, 1000],
|
||||
context,
|
||||
features;
|
||||
context, features;
|
||||
|
||||
beforeEach(function() {
|
||||
context = iD.Context(window);
|
||||
context = iD.Context();
|
||||
d3.select(document.createElement('div'))
|
||||
.attr('id', 'map')
|
||||
.call(context.map());
|
||||
context.map().zoom(16);
|
||||
features = iD.Features(context);
|
||||
});
|
||||
|
||||
@@ -2,7 +2,7 @@ describe('iD.Map', function() {
|
||||
var context, map;
|
||||
|
||||
beforeEach(function() {
|
||||
context = iD.Context(window).imagery(iD.dataImagery);
|
||||
context = iD.Context();
|
||||
context.container(d3.select(document.createElement('div')));
|
||||
map = context.map();
|
||||
d3.select(document.createElement('div'))
|
||||
|
||||
@@ -2,7 +2,7 @@ describe('iD.TileLayer', function() {
|
||||
var context, d, c;
|
||||
|
||||
beforeEach(function() {
|
||||
context = iD.Context(window);
|
||||
context = iD.Context();
|
||||
d = d3.select(document.createElement('div'));
|
||||
c = iD.TileLayer(context).projection(d3.geoMercator());
|
||||
});
|
||||
|
||||
@@ -7,7 +7,7 @@ describe('iD.serviceMapillary', function() {
|
||||
|
||||
|
||||
beforeEach(function() {
|
||||
context = iD.Context(window).assetPath('../dist/');
|
||||
context = iD.Context().assetPath('../dist/');
|
||||
context.projection
|
||||
.scale(667544.214430109) // z14
|
||||
.translate([-116508, 0]) // 10,0
|
||||
|
||||
+219
-20
@@ -1,12 +1,31 @@
|
||||
describe('iD.serviceOsm', function () {
|
||||
var connection;
|
||||
var context, connection, spy;
|
||||
|
||||
function login() {
|
||||
if (!connection) return;
|
||||
connection.switch({
|
||||
urlroot: 'http://www.openstreetmap.org',
|
||||
oauth_consumer_key: '5A043yRSEugj4DJ5TljuapfnrflWDte8jTOcWLlT',
|
||||
oauth_secret: 'aB3jKq1TRsCOUrfOIZ6oQMEDmv2ptV76PA54NGLL',
|
||||
oauth_token: 'foo',
|
||||
oauth_token_secret: 'foo'
|
||||
});
|
||||
}
|
||||
|
||||
function logout() {
|
||||
if (!connection) return;
|
||||
connection.logout();
|
||||
}
|
||||
|
||||
beforeEach(function () {
|
||||
connection = iD.services.osm;
|
||||
connection.switch({ urlroot: 'http://www.openstreetmap.org'});
|
||||
context = iD.Context();
|
||||
connection = context.connection();
|
||||
connection.switch({ urlroot: 'http://www.openstreetmap.org' });
|
||||
connection.reset();
|
||||
spy = sinon.spy();
|
||||
});
|
||||
|
||||
|
||||
it('is instantiated', function () {
|
||||
expect(connection).to.be.ok;
|
||||
});
|
||||
@@ -44,46 +63,169 @@ describe('iD.serviceOsm', function () {
|
||||
expect(connection.changesetURL(1)).to.equal('http://example.com/changeset/1');
|
||||
});
|
||||
|
||||
it('emits an auth event', function(done) {
|
||||
connection.on('auth', function() {
|
||||
connection.on('auth', null);
|
||||
done();
|
||||
});
|
||||
it('emits a change event', function() {
|
||||
connection.on('change', spy);
|
||||
connection.switch({ urlroot: 'http://example.com' });
|
||||
expect(spy).to.have.been.calledOnce;
|
||||
});
|
||||
});
|
||||
|
||||
describe('#loadFromAPI', function () {
|
||||
var server,
|
||||
path = '/api/0.6/map?bbox=-74.542,40.655,-74.541,40.656',
|
||||
response = '<?xml version="1.0" encoding="UTF-8"?>' +
|
||||
'<osm version="0.6">' +
|
||||
' <bounds minlat="40.655" minlon="-74.542" maxlat="40.656" maxlon="-74.541' +
|
||||
' <node id="105340439" visible="true" version="2" changeset="2880013" timestamp="2009-10-18T07:47:39Z" user="woodpeck_fixbot" uid="147510" lat="40.6555" lon="-74.5415"/>' +
|
||||
' <node id="105340442" visible="true" version="2" changeset="2880013" timestamp="2009-10-18T07:47:39Z" user="woodpeck_fixbot" uid="147510" lat="40.6556" lon="-74.5416"/>' +
|
||||
' <way id="40376199" visible="true" version="1" changeset="2403012" timestamp="2009-09-07T16:01:13Z" user="NJDataUploads" uid="148169">' +
|
||||
' <nd ref="105340439"/>' +
|
||||
' <nd ref="105340442"/>' +
|
||||
' <tag k="highway" v="residential"/>' +
|
||||
' <tag k="name" v="Potomac Drive"/>' +
|
||||
' </way>' +
|
||||
'</osm>';
|
||||
|
||||
beforeEach(function() {
|
||||
// force loading locally via d3.xml
|
||||
connection.switch({ urlroot: '' }).logout();
|
||||
connection.reset();
|
||||
server = sinon.fakeServer.create();
|
||||
spy = sinon.spy();
|
||||
});
|
||||
|
||||
it('loads test data', function (done) {
|
||||
connection.loadFromAPI('data/node.xml', done);
|
||||
afterEach(function() {
|
||||
server.restore();
|
||||
});
|
||||
|
||||
|
||||
it('returns an object', function (done) {
|
||||
connection.loadFromAPI('data/node.xml', function (err, graph) {
|
||||
connection.loadFromAPI(path, function (err, xml) {
|
||||
expect(err).to.not.be.ok;
|
||||
expect(typeof graph).to.eql('object');
|
||||
expect(typeof xml).to.eql('object');
|
||||
done();
|
||||
});
|
||||
|
||||
server.respondWith('GET', 'http://www.openstreetmap.org' + path,
|
||||
[200, { 'Content-Type': 'text/xml' }, response]);
|
||||
server.respond();
|
||||
});
|
||||
|
||||
it('parses a node', function (done) {
|
||||
connection.loadFromAPI('data/node.xml', function (err, entities) {
|
||||
expect(entities[0]).to.be.instanceOf(iD.Entity);
|
||||
it('retries an authenticated call unauthenticated if 400 Bad Request', function (done) {
|
||||
login();
|
||||
connection.loadFromAPI(path, function (err, xml) {
|
||||
expect(err).to.be.not.ok;
|
||||
expect(typeof xml).to.eql('object');
|
||||
expect(connection.authenticated()).to.be.not.ok;
|
||||
done();
|
||||
});
|
||||
|
||||
server.respondWith('GET', 'http://www.openstreetmap.org' + path,
|
||||
function(request) {
|
||||
if (connection.authenticated()) {
|
||||
return request.respond(400, {});
|
||||
} else {
|
||||
return request.respond(200, { 'Content-Type': 'text/xml' }, response);
|
||||
}
|
||||
}
|
||||
);
|
||||
server.respond();
|
||||
server.respond();
|
||||
});
|
||||
|
||||
it('parses a way', function (done) {
|
||||
connection.loadFromAPI('data/way.xml', function (err, entities) {
|
||||
expect(entities[0]).to.be.instanceOf(iD.Entity);
|
||||
it('retries an authenticated call unauthenticated if 401 Unauthorized', function (done) {
|
||||
login();
|
||||
connection.loadFromAPI(path, function (err, xml) {
|
||||
expect(err).to.be.not.ok;
|
||||
expect(typeof xml).to.eql('object');
|
||||
expect(connection.authenticated()).to.be.not.ok;
|
||||
done();
|
||||
});
|
||||
|
||||
server.respondWith('GET', 'http://www.openstreetmap.org' + path,
|
||||
function(request) {
|
||||
if (connection.authenticated()) {
|
||||
return request.respond(401, {});
|
||||
} else {
|
||||
return request.respond(200, { 'Content-Type': 'text/xml' }, response);
|
||||
}
|
||||
}
|
||||
);
|
||||
server.respond();
|
||||
server.respond();
|
||||
});
|
||||
|
||||
it('retries an authenticated call unauthenticated if 403 Forbidden', function (done) {
|
||||
login();
|
||||
connection.loadFromAPI(path, function (err, xml) {
|
||||
expect(err).to.be.not.ok;
|
||||
expect(typeof xml).to.eql('object');
|
||||
expect(connection.authenticated()).to.be.not.ok;
|
||||
done();
|
||||
});
|
||||
|
||||
server.respondWith('GET', 'http://www.openstreetmap.org' + path,
|
||||
function(request) {
|
||||
if (connection.authenticated()) {
|
||||
return request.respond(403, {});
|
||||
} else {
|
||||
return request.respond(200, { 'Content-Type': 'text/xml' }, response);
|
||||
}
|
||||
}
|
||||
);
|
||||
server.respond();
|
||||
server.respond();
|
||||
});
|
||||
|
||||
|
||||
it('dispatches change event if 509 Bandwidth Limit Exceeded', function (done) {
|
||||
logout();
|
||||
connection.on('change', spy);
|
||||
connection.loadFromAPI(path, function (err) {
|
||||
expect(err).to.have.property('status', 509);
|
||||
expect(spy).to.have.been.calledOnce;
|
||||
done();
|
||||
});
|
||||
|
||||
server.respondWith('GET', 'http://www.openstreetmap.org' + path,
|
||||
function(request) {
|
||||
if (!connection.authenticated()) {
|
||||
// workaround: sinon.js seems to call error handler with a
|
||||
// sinon.Event instead of the target XMLHttpRequest object..
|
||||
var orig = request.onreadystatechange;
|
||||
request.onreadystatechange = function(o) { orig((o && o.target) || o); };
|
||||
return request.respond(509, {});
|
||||
} else {
|
||||
return request.respond(200, { 'Content-Type': 'text/xml' }, response);
|
||||
}
|
||||
}
|
||||
);
|
||||
server.respond();
|
||||
});
|
||||
|
||||
it('dispatches change event if 429 Too Many Requests', function (done) {
|
||||
logout();
|
||||
connection.on('change', spy);
|
||||
connection.loadFromAPI(path, function (err) {
|
||||
expect(err).to.have.property('status', 429);
|
||||
expect(spy).to.have.been.calledOnce;
|
||||
done();
|
||||
});
|
||||
|
||||
server.respondWith('GET', 'http://www.openstreetmap.org' + path,
|
||||
function(request) {
|
||||
if (!connection.authenticated()) {
|
||||
// workaround: sinon.js seems to call error handler with a
|
||||
// sinon.Event instead of the target XMLHttpRequest object..
|
||||
var orig = request.onreadystatechange;
|
||||
request.onreadystatechange = function(o) { orig((o && o.target) || o); };
|
||||
return request.respond(429, {});
|
||||
} else {
|
||||
return request.respond(200, { 'Content-Type': 'text/xml' }, response);
|
||||
}
|
||||
}
|
||||
);
|
||||
server.respond();
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('#loadEntity', function () {
|
||||
@@ -303,4 +445,61 @@ describe('iD.serviceOsm', function () {
|
||||
expect(connection.changesetTags('2.0.0', '', [])).not.to.have.property('comment');
|
||||
});
|
||||
});
|
||||
|
||||
describe('API capabilities', function() {
|
||||
var server,
|
||||
capabilitiesXML = '<?xml version="1.0" encoding="UTF-8"?><osm>' +
|
||||
'<api>' +
|
||||
'<version minimum="0.6" maximum="0.6"/>' +
|
||||
'<area maximum="0.25"/>' +
|
||||
'<tracepoints per_page="5000"/>' +
|
||||
'<waynodes maximum="2000"/>' +
|
||||
'<changesets maximum_elements="50000"/>' +
|
||||
'<timeout seconds="300"/>' +
|
||||
'<status database="online" api="online" gpx="online"/>' +
|
||||
'</api>' +
|
||||
'<policy><imagery>' +
|
||||
'<blacklist regex="\.foo\.com"/>' +
|
||||
'<blacklist regex="\.bar\.org"/>' +
|
||||
'</imagery></policy>' +
|
||||
'</osm>';
|
||||
|
||||
|
||||
beforeEach(function() {
|
||||
server = sinon.fakeServer.create();
|
||||
});
|
||||
|
||||
afterEach(function() {
|
||||
server.restore();
|
||||
});
|
||||
|
||||
describe('#status', function() {
|
||||
it('gets API status', function(done) {
|
||||
connection.status(function(err, val) {
|
||||
expect(val).to.eql('online');
|
||||
done();
|
||||
});
|
||||
|
||||
server.respondWith('GET', 'http://www.openstreetmap.org/api/capabilities',
|
||||
[200, { 'Content-Type': 'text/xml' }, capabilitiesXML]);
|
||||
server.respond();
|
||||
});
|
||||
});
|
||||
|
||||
describe('#imageryBlacklists', function() {
|
||||
it('updates imagery blacklists', function(done) {
|
||||
connection.status(function() {
|
||||
var blacklists = connection.imageryBlacklists();
|
||||
expect(blacklists).to.deep.equal(['\.foo\.com','\.bar\.org']);
|
||||
done();
|
||||
});
|
||||
|
||||
server.respondWith('GET', 'http://www.openstreetmap.org/api/capabilities',
|
||||
[200, { 'Content-Type': 'text/xml' }, capabilitiesXML]);
|
||||
server.respond();
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
/* globals chai:false */
|
||||
|
||||
iD.debug = true;
|
||||
iD.data.imagery = [];
|
||||
|
||||
mocha.setup({
|
||||
ui: 'bdd',
|
||||
|
||||
@@ -8,7 +8,7 @@ describe('iD.svgAreas', function () {
|
||||
none = function() { return false; };
|
||||
|
||||
beforeEach(function () {
|
||||
context = iD.Context(window);
|
||||
context = iD.Context();
|
||||
d3.select(document.createElement('div'))
|
||||
.attr('id', 'map')
|
||||
.call(context.map());
|
||||
|
||||
@@ -6,7 +6,7 @@ describe('iD.svgLayers', function () {
|
||||
.clipExtent([[0, 0], [Infinity, Infinity]]);
|
||||
|
||||
beforeEach(function () {
|
||||
context = iD.Context(window);
|
||||
context = iD.Context();
|
||||
container = d3.select(document.createElement('div'));
|
||||
});
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ describe('iD.svgLines', function () {
|
||||
none = function() { return false; };
|
||||
|
||||
beforeEach(function () {
|
||||
context = iD.Context(window);
|
||||
context = iD.Context();
|
||||
d3.select(document.createElement('div'))
|
||||
.attr('id', 'map')
|
||||
.call(context.map());
|
||||
|
||||
@@ -7,7 +7,7 @@ describe('iD.svgMidpoints', function () {
|
||||
filter = function() { return true; };
|
||||
|
||||
beforeEach(function () {
|
||||
context = iD.Context(window);
|
||||
context = iD.Context();
|
||||
d3.select(document.createElement('div'))
|
||||
.attr('id', 'map')
|
||||
.call(context.map());
|
||||
|
||||
@@ -6,7 +6,7 @@ describe('iD.svgPoints', function () {
|
||||
.clipExtent([[0, 0], [Infinity, Infinity]]);
|
||||
|
||||
beforeEach(function () {
|
||||
context = iD.Context(window);
|
||||
context = iD.Context();
|
||||
d3.select(document.createElement('div'))
|
||||
.attr('id', 'map')
|
||||
.call(context.map());
|
||||
|
||||
@@ -6,7 +6,7 @@ describe('iD.svgVertices', function () {
|
||||
.clipExtent([[0, 0], [Infinity, Infinity]]);
|
||||
|
||||
beforeEach(function () {
|
||||
context = iD.Context(window);
|
||||
context = iD.Context();
|
||||
d3.select(document.createElement('div'))
|
||||
.attr('id', 'map')
|
||||
.call(context.map());
|
||||
|
||||
@@ -2,8 +2,7 @@ describe('iD.uiFieldAccess', function() {
|
||||
var selection, field;
|
||||
beforeEach(function() {
|
||||
selection = d3.select(document.createElement('div'));
|
||||
field = iD.Context(window)
|
||||
.presets(iD.dataPresets).presets().field('access');
|
||||
field = iD.Context().presets().field('access');
|
||||
});
|
||||
|
||||
it('creates inputs for a variety of modes of access', function() {
|
||||
|
||||
@@ -11,10 +11,10 @@ describe('iD.uiFieldWikipedia', function() {
|
||||
beforeEach(function() {
|
||||
entity = iD.Node({id: 'n12345'});
|
||||
selectedId = entity.id;
|
||||
context = iD.Context(window);
|
||||
context = iD.Context();
|
||||
context.history().merge([entity]);
|
||||
selection = d3.select(document.createElement('div'));
|
||||
field = context.presets(iD.dataPresets).presets().field('wikipedia');
|
||||
field = context.presets().field('wikipedia');
|
||||
window.JSONP_DELAY = 0;
|
||||
window.JSONP_FIX = {
|
||||
entities: {
|
||||
@@ -114,7 +114,7 @@ describe('iD.uiFieldWikipedia', function() {
|
||||
// skip delayed wikidata for 'Skip' // 'Skip' wikidata +20ms
|
||||
expect(spy.getCall(4)).to.have.been.calledWith({ wikipedia: 'de:Title', wikidata: 'Q216353' }); // 'Title' wikidata +40ms
|
||||
done();
|
||||
}, 50);
|
||||
}, 100);
|
||||
});
|
||||
|
||||
it('does not set delayed wikidata tag if selected entity has changed', function(done) {
|
||||
@@ -140,7 +140,7 @@ describe('iD.uiFieldWikipedia', function() {
|
||||
expect(spy.getCall(1)).to.have.been.calledWith({ wikipedia: 'de:Title' }); // 'Title' on blur
|
||||
// wikidata tag not changed because another entity is now selected
|
||||
done();
|
||||
}, 50);
|
||||
}, 100);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
@@ -15,7 +15,7 @@ describe('iD.uiRawTagEditor', function() {
|
||||
|
||||
beforeEach(function () {
|
||||
entity = iD.Node({id: 'n12345'});
|
||||
context = iD.Context(window);
|
||||
context = iD.Context();
|
||||
context.history().merge([entity]);
|
||||
render({highway: 'residential'});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user