mirror of
https://github.com/FoggedLens/iD.git
synced 2026-04-21 19:26:41 +02:00
Merge branch 'switchToKarma' into develop
This commit is contained in:
@@ -17,6 +17,8 @@ transifex.auth
|
||||
/dist/mapillary-js/
|
||||
/dist/pannellum-streetside/
|
||||
|
||||
/coverage/
|
||||
|
||||
# autogenerated symlinks
|
||||
land.html
|
||||
/img
|
||||
|
||||
@@ -12,3 +12,5 @@ transifex.auth
|
||||
|
||||
/docs/
|
||||
/test/
|
||||
|
||||
/coverage/
|
||||
|
||||
@@ -75,9 +75,11 @@ _Breaking developer changes, which may affect downstream projects or sites that
|
||||
* Radio-button based presets fields can be in an non-unique state (e.g. a tunnel which is also a ford) – this is now rendered like a multi selection with conflicting states ([#8796])
|
||||
* Add colours for preset categories ([#8799])
|
||||
#### :hammer: Development
|
||||
* switch test runner to [karma](https://karma-runner.github.io/) ([#8764], thanks [@wvanderp])
|
||||
|
||||
[#8057]: https://github.com/openstreetmap/iD/issues/8057
|
||||
[#8519]: https://github.com/openstreetmap/iD/issues/8519
|
||||
[#8764]: https://github.com/openstreetmap/iD/pull/8764
|
||||
[#8771]: https://github.com/openstreetmap/iD/issues/8771
|
||||
[#8781]: https://github.com/openstreetmap/iD/issues/8781
|
||||
[#8782]: https://github.com/openstreetmap/iD/pull/8782
|
||||
@@ -99,6 +101,7 @@ _Breaking developer changes, which may affect downstream projects or sites that
|
||||
[@k-yle]: https://github.com/k-yle
|
||||
[@tpetillon]: https://github.com/tpetillon
|
||||
[@mbrzakovic]: https://github.com/mbrzakovic
|
||||
[@wvanderp]: https://github.com/wvanderp
|
||||
|
||||
# 2.20.2
|
||||
##### 2021-Oct-28
|
||||
|
||||
+109
@@ -0,0 +1,109 @@
|
||||
// Karma configuration
|
||||
// Generated on Wed Sep 01 2021 16:45:06 GMT+0200 (Central European Summer Time)
|
||||
|
||||
module.exports = function (config) {
|
||||
config.set({
|
||||
|
||||
// base path that will be used to resolve all patterns (eg. files, exclude)
|
||||
basePath: '',
|
||||
|
||||
plugins: [
|
||||
'karma-remap-istanbul',
|
||||
'karma-coverage',
|
||||
'karma-mocha',
|
||||
'karma-chrome-launcher'
|
||||
],
|
||||
|
||||
// frameworks to use
|
||||
// available frameworks: https://www.npmjs.com/search?q=keywords:karma-adapter
|
||||
frameworks: ['mocha'],
|
||||
|
||||
|
||||
|
||||
// list of files / patterns to load in the browser
|
||||
files: [
|
||||
'node_modules/chai/chai.js',
|
||||
'node_modules/sinon/pkg/sinon.js',
|
||||
'node_modules/sinon-chai/lib/sinon-chai.js',
|
||||
'node_modules/happen/happen.js',
|
||||
'node_modules/fetch-mock/es5/client-bundle.js',
|
||||
{ pattern: 'dist/iD.js', included: true },
|
||||
{ pattern: 'dist/iD.css', included: true },
|
||||
{ pattern: 'dist/**/*', included: false },
|
||||
'test/spec/spec_helpers.js',
|
||||
'test/spec/**/*.js'
|
||||
],
|
||||
|
||||
|
||||
// list of files / patterns to exclude
|
||||
exclude: [
|
||||
'**/*.js.map'
|
||||
],
|
||||
|
||||
proxies: {
|
||||
'/dist/': 'http://localhost:9876/base/dist/',
|
||||
'/data/': 'http://localhost:9876/base/dist/data/',
|
||||
'/img/': 'http://localhost:9876/base/dist/img/'
|
||||
},
|
||||
|
||||
// preprocess matching files before serving them to the browser
|
||||
// available preprocessors: https://www.npmjs.com/search?q=keywords:karma-preprocessor
|
||||
preprocessors: {
|
||||
'dist/iD.js': ['coverage']
|
||||
},
|
||||
|
||||
|
||||
// test results reporter to use
|
||||
// possible values: 'dots', 'progress'
|
||||
// available reporters: https://www.npmjs.com/search?q=keywords:karma-reporter
|
||||
reporters: ['progress', 'coverage', 'karma-remap-istanbul'],
|
||||
|
||||
|
||||
// web server port
|
||||
port: 9876,
|
||||
|
||||
|
||||
// enable / disable colors in the output (reporters and logs)
|
||||
colors: true,
|
||||
|
||||
|
||||
// level of logging
|
||||
// possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
|
||||
logLevel: config.LOG_INFO,
|
||||
|
||||
|
||||
// enable / disable watching file and executing tests whenever any file changes
|
||||
autoWatch: true,
|
||||
|
||||
|
||||
// start these browsers
|
||||
// available browser launchers: https://www.npmjs.com/search?q=keywords:karma-launcher
|
||||
browsers: [
|
||||
'ChromeHeadless'
|
||||
],
|
||||
|
||||
|
||||
// Continuous Integration mode
|
||||
// if true, Karma captures browsers, runs the tests and exits
|
||||
singleRun: true,
|
||||
|
||||
// Concurrency level
|
||||
// how many browser instances should be started simultaneously
|
||||
concurrency: Infinity,
|
||||
|
||||
remapIstanbulReporter: {
|
||||
remapOptions: {
|
||||
exclude: [
|
||||
'node_modules'
|
||||
]
|
||||
}, //additional remap options
|
||||
reportOptions: {
|
||||
basePath: 'modules'
|
||||
}, //additional report options
|
||||
reports: {
|
||||
lcovonly: 'coverage/lcof.info',
|
||||
html: 'coverage'
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
+13
-9
@@ -37,8 +37,8 @@
|
||||
"start": "npm-run-all -s build start:server",
|
||||
"quickstart": "npm-run-all -s build:dev start:server",
|
||||
"start:server": "node scripts/server.js",
|
||||
"test": "npm-run-all -s lint build:css build:data build:legacy test:spec",
|
||||
"test:spec": "phantomjs --web-security=no node_modules/mocha-phantomjs-core/mocha-phantomjs-core.js test/index.html spec",
|
||||
"test": "npm-run-all -s lint build test:spec",
|
||||
"test:spec": "karma start karma.conf.js",
|
||||
"translations": "node scripts/update_locales.js"
|
||||
},
|
||||
"dependencies": {
|
||||
@@ -82,7 +82,7 @@
|
||||
"@rollup/plugin-node-resolve": "~13.0.5",
|
||||
"autoprefixer": "^10.0.1",
|
||||
"btoa": "^1.2.1",
|
||||
"chai": "^4.1.0",
|
||||
"chai": "^4.3.4",
|
||||
"cldr-core": "37.0.0",
|
||||
"cldr-localenames-full": "37.0.0",
|
||||
"colors": "^1.1.2",
|
||||
@@ -90,22 +90,26 @@
|
||||
"d3": "~6.6.0",
|
||||
"editor-layer-index": "github:osmlab/editor-layer-index#gh-pages",
|
||||
"eslint": "^7.1.0",
|
||||
"fetch-mock": "^9.11.0",
|
||||
"gaze": "^1.1.3",
|
||||
"glob": "^7.1.0",
|
||||
"happen": "^0.3.1",
|
||||
"happen": "^0.3.2",
|
||||
"js-yaml": "^4.0.0",
|
||||
"json-stringify-pretty-compact": "^3.0.0",
|
||||
"karma": "^6.3.5",
|
||||
"karma-chrome-launcher": "^3.1.0",
|
||||
"karma-coverage": "^2.0.3",
|
||||
"karma-mocha": "^2.0.1",
|
||||
"karma-remap-istanbul": "^0.6.0",
|
||||
"mapillary_sprite_source": "^1.8.0",
|
||||
"mapillary-js": "4.0.0",
|
||||
"minimist": "^1.2.3",
|
||||
"mocha": "^7.0.1",
|
||||
"mocha-phantomjs-core": "^2.1.0",
|
||||
"mocha": "^8.4.0",
|
||||
"name-suggestion-index": "~6.0",
|
||||
"node-fetch": "^2.6.1",
|
||||
"npm-run-all": "^4.0.0",
|
||||
"object-inspect": "1.10.3",
|
||||
"osm-community-index": "~5.1.0",
|
||||
"phantomjs-prebuilt": "~2.1.16",
|
||||
"postcss": "^8.1.1",
|
||||
"postcss-selector-prepend": "^0.5.0",
|
||||
"rollup": "~2.52.8",
|
||||
@@ -114,8 +118,8 @@
|
||||
"rollup-plugin-visualizer": "~4.2.0",
|
||||
"shelljs": "^0.8.0",
|
||||
"shx": "^0.3.0",
|
||||
"sinon": "7.5.0",
|
||||
"sinon-chai": "^3.3.0",
|
||||
"sinon": "^11.1.2",
|
||||
"sinon-chai": "^3.7.0",
|
||||
"smash": "0.0",
|
||||
"static-server": "^2.2.1",
|
||||
"svg-sprite": "1.5.1",
|
||||
|
||||
+2
-1
@@ -8,7 +8,8 @@
|
||||
"fakeFetch": true,
|
||||
"happen": false,
|
||||
"iD": false,
|
||||
"sinon": false
|
||||
"sinon": false,
|
||||
"fetchMock": true
|
||||
},
|
||||
"rules": {
|
||||
"no-unused-expressions": "off"
|
||||
|
||||
-226
@@ -1,226 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<meta charset='utf-8'>
|
||||
<title>Mocha Tests</title>
|
||||
<link rel='stylesheet' href='../node_modules/mocha/mocha.css'>
|
||||
<link rel='stylesheet' href='../dist/iD.css'>
|
||||
<!-- <script src='../node_modules/d3/build/d3.js'></script> -->
|
||||
<style type='text/css'>
|
||||
/* apply standalone iD styling when testing */
|
||||
html, body {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body style="overflow:scroll">
|
||||
<div id='mocha'></div>
|
||||
|
||||
<script src='../node_modules/mocha/mocha.js'></script>
|
||||
<script src='../node_modules/chai/chai.js'></script>
|
||||
<script src='../node_modules/sinon/pkg/sinon.js'></script>
|
||||
<script src='../node_modules/sinon-chai/lib/sinon-chai.js'></script>
|
||||
<script src='../node_modules/happen/happen.js'></script>
|
||||
|
||||
<script>
|
||||
if (typeof initMochaPhantomJS === 'function') {
|
||||
initMochaPhantomJS()
|
||||
}
|
||||
</script>
|
||||
|
||||
<script>
|
||||
var scripts = [
|
||||
'spec/actions/add_entity.js',
|
||||
'spec/actions/add_member.js',
|
||||
'spec/actions/add_midpoint.js',
|
||||
'spec/actions/change_member.js',
|
||||
'spec/actions/change_preset.js',
|
||||
'spec/actions/change_tags.js',
|
||||
'spec/actions/circularize.js',
|
||||
'spec/actions/connect.js',
|
||||
'spec/actions/copy_entities.js',
|
||||
'spec/actions/delete_member.js',
|
||||
'spec/actions/delete_multiple.js',
|
||||
'spec/actions/delete_node.js',
|
||||
'spec/actions/delete_relation.js',
|
||||
'spec/actions/delete_way.js',
|
||||
'spec/actions/discard_tags.js',
|
||||
'spec/actions/disconnect.js',
|
||||
'spec/actions/join.js',
|
||||
'spec/actions/merge.js',
|
||||
'spec/actions/merge_nodes.js',
|
||||
'spec/actions/merge_polygon.js',
|
||||
'spec/actions/merge_remote_changes.js',
|
||||
'spec/actions/move.js',
|
||||
'spec/actions/move_node.js',
|
||||
'spec/actions/noop.js',
|
||||
'spec/actions/orthogonalize.js',
|
||||
'spec/actions/restrict_turn.js',
|
||||
'spec/actions/reverse.js',
|
||||
'spec/actions/revert.js',
|
||||
'spec/actions/split.js',
|
||||
'spec/actions/straighten_nodes.js',
|
||||
'spec/actions/straighten_way.js',
|
||||
'spec/actions/unrestrict_turn.js',
|
||||
'spec/actions/reflect.js',
|
||||
'spec/actions/extract.js',
|
||||
'spec/actions/upgrade_tags.js',
|
||||
|
||||
'spec/behavior/hash.js',
|
||||
'spec/behavior/hover.js',
|
||||
'spec/behavior/select.js',
|
||||
'spec/behavior/lasso.js',
|
||||
|
||||
'spec/core/context.js',
|
||||
'spec/core/difference.js',
|
||||
'spec/core/file_fetcher.js',
|
||||
'spec/core/graph.js',
|
||||
'spec/core/history.js',
|
||||
'spec/core/locations.js',
|
||||
'spec/core/localizer.js',
|
||||
'spec/core/tree.js',
|
||||
'spec/core/validator.js',
|
||||
|
||||
'spec/geo/extent.js',
|
||||
'spec/geo/geo.js',
|
||||
'spec/geo/geom.js',
|
||||
'spec/geo/vector.js',
|
||||
|
||||
'spec/lib/locale.js',
|
||||
|
||||
'spec/modes/add_point.js',
|
||||
'spec/modes/add_note.js',
|
||||
|
||||
'spec/operations/extract.js',
|
||||
'spec/operations/straighten.js',
|
||||
|
||||
'spec/osm/changeset.js',
|
||||
'spec/osm/entity.js',
|
||||
'spec/osm/intersection.js',
|
||||
'spec/osm/multipolygon.js',
|
||||
'spec/osm/lanes.js',
|
||||
'spec/osm/node.js',
|
||||
'spec/osm/note.js',
|
||||
'spec/osm/relation.js',
|
||||
'spec/osm/way.js',
|
||||
|
||||
'spec/presets/category.js',
|
||||
'spec/presets/collection.js',
|
||||
'spec/presets/index.js',
|
||||
'spec/presets/preset.js',
|
||||
|
||||
'spec/renderer/background_source.js',
|
||||
'spec/renderer/features.js',
|
||||
'spec/renderer/map.js',
|
||||
'spec/renderer/tile_layer.js',
|
||||
|
||||
'spec/services/mapillary.js',
|
||||
'spec/services/maprules.js',
|
||||
'spec/services/nominatim.js',
|
||||
'spec/services/kartaview.js',
|
||||
'spec/services/osm.js',
|
||||
'spec/services/osm_wikibase.js',
|
||||
'spec/services/streetside.js',
|
||||
'spec/services/taginfo.js',
|
||||
|
||||
'spec/svg/areas.js',
|
||||
'spec/svg/data.js',
|
||||
'spec/svg/icon.js',
|
||||
'spec/svg/layers.js',
|
||||
'spec/svg/lines.js',
|
||||
'spec/svg/midpoints.js',
|
||||
'spec/svg/osm.js',
|
||||
'spec/svg/points.js',
|
||||
'spec/svg/svg.js',
|
||||
'spec/svg/tag_classes.js',
|
||||
'spec/svg/vertices.js',
|
||||
|
||||
'spec/ui/cmd.js',
|
||||
'spec/ui/combobox.js',
|
||||
'spec/ui/confirm.js',
|
||||
'spec/ui/flash.js',
|
||||
'spec/ui/inspector.js',
|
||||
'spec/ui/modal.js',
|
||||
|
||||
'spec/ui/sections/raw_tag_editor.js',
|
||||
|
||||
'spec/ui/fields/access.js',
|
||||
'spec/ui/fields/localized.js',
|
||||
'spec/ui/fields/wikipedia.js',
|
||||
|
||||
'spec/util/aes.js',
|
||||
'spec/util/array.js',
|
||||
'spec/util/clean_tags.js',
|
||||
'spec/util/keybinding.js',
|
||||
'spec/util/object.js',
|
||||
'spec/util/session_mutex.js',
|
||||
'spec/util/util.js',
|
||||
|
||||
'spec/validations/almost_junction.js',
|
||||
'spec/validations/crossing_ways.js',
|
||||
'spec/validations/disconnected_way.js',
|
||||
'spec/validations/incompatible_source.js',
|
||||
'spec/validations/mismatched_geometry.js',
|
||||
'spec/validations/missing_role.js',
|
||||
'spec/validations/missing_tag.js',
|
||||
'spec/validations/outdated_tags.js',
|
||||
'spec/validations/private_data.js',
|
||||
'spec/validations/suspicious_name.js'
|
||||
];
|
||||
|
||||
window.executionErrors = [];
|
||||
|
||||
window.onerror = function (message, source, line, col) {
|
||||
window.executionErrors.push("message" + message + " source" + source + " line" + line + " col" + col);
|
||||
};
|
||||
|
||||
var isPhantomJS = !!(navigator.userAgent.match(/PhantomJS/));
|
||||
var isIE11 = !!(navigator.userAgent.match(/Trident/) && !navigator.userAgent.match(/MSIE/));
|
||||
|
||||
// Prepend scripts to run at the beginning.
|
||||
|
||||
// Third Script? PhantomJS can test some other capabilities
|
||||
if (isPhantomJS) scripts.unshift('spec/phantom.js');
|
||||
|
||||
// Second Script: Always run spec helpers
|
||||
scripts.unshift('spec/spec_helpers.js');
|
||||
|
||||
// First script: Choose either modern or legacy iD build..
|
||||
scripts.unshift((isPhantomJS || isIE11) ? '../dist/iD.legacy.js' : '../dist/iD.js');
|
||||
|
||||
|
||||
// Create and execute all scripts in specified order..
|
||||
(function nextScript() {
|
||||
if (!scripts.length) {
|
||||
window.mocha.run();
|
||||
|
||||
if (window.executionErrors.length > 0){
|
||||
console.log('\n\n[Execution errors exist] Please resolve the following: \n');
|
||||
for (var i = 0; i < window.executionErrors.length; i++){
|
||||
console.log('[Execution error] ' + window.executionErrors[i]);
|
||||
}
|
||||
console.log('\n Disposing mocha. Expect mocha dispose log like: \'Uncaught error outside test suite\'... \n');
|
||||
window.mocha.dispose();
|
||||
}
|
||||
return;
|
||||
}
|
||||
var src = scripts.shift();
|
||||
var newScript;
|
||||
newScript = document.createElement('script');
|
||||
newScript.type = 'text/javascript';
|
||||
if (src.substr(0, 5) === 'spec/') {
|
||||
src = '../test/' + src;
|
||||
}
|
||||
newScript.src = src;
|
||||
newScript.onload = nextScript;
|
||||
document.getElementsByTagName('body')[0].appendChild(newScript);
|
||||
})();
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,9 +1,10 @@
|
||||
describe('iD.serviceKartaview', function() {
|
||||
var dimensions = [64, 64];
|
||||
var context, server, kartaview;
|
||||
var context, kartaview;
|
||||
|
||||
before(function() {
|
||||
iD.services.kartaview = iD.serviceKartaview;
|
||||
fetchMock.reset();
|
||||
});
|
||||
|
||||
after(function() {
|
||||
@@ -17,13 +18,13 @@ describe('iD.serviceKartaview', function() {
|
||||
.translate([-116508, 0]) // 10,0
|
||||
.clipExtent([[0,0], dimensions]);
|
||||
|
||||
server = window.fakeFetch().create();
|
||||
kartaview = iD.services.kartaview;
|
||||
kartaview.reset();
|
||||
fetchMock.reset();
|
||||
});
|
||||
|
||||
afterEach(function() {
|
||||
server.restore();
|
||||
fetchMock.reset();
|
||||
});
|
||||
|
||||
|
||||
@@ -52,13 +53,6 @@ describe('iD.serviceKartaview', function() {
|
||||
|
||||
describe('#loadImages', function() {
|
||||
it('fires loadedImages when images are loaded', function(done) {
|
||||
kartaview.on('loadedImages', function() {
|
||||
expect(server.requests().length).to.eql(1); // 1 nearby-photos
|
||||
done();
|
||||
});
|
||||
|
||||
kartaview.loadImages(context.projection);
|
||||
|
||||
var data = {
|
||||
status: { apiCode: '600', httpCode: 200, httpMessage: 'Success' },
|
||||
currentPageItems:[{
|
||||
@@ -101,18 +95,21 @@ describe('iD.serviceKartaview', function() {
|
||||
totalFilteredItems: ['3']
|
||||
};
|
||||
|
||||
server.respondWith('POST', /nearby-photos/,
|
||||
[200, { 'Content-Type': 'application/json' }, JSON.stringify(data) ]);
|
||||
server.respond();
|
||||
fetchMock.mock(new RegExp('/nearby-photos/'), {
|
||||
body: JSON.stringify(data),
|
||||
status: 200,
|
||||
headers: { 'Content-Type': 'application/json' }
|
||||
});
|
||||
|
||||
kartaview.on('loadedImages', function() {
|
||||
expect(fetchMock.calls().length).to.eql(1); // 1 nearby-photos
|
||||
done();
|
||||
});
|
||||
|
||||
kartaview.loadImages(context.projection);
|
||||
});
|
||||
|
||||
it('does not load images around null island', function(done) {
|
||||
var spy = sinon.spy();
|
||||
context.projection.translate([0,0]);
|
||||
|
||||
kartaview.on('loadedImages', spy);
|
||||
kartaview.loadImages(context.projection);
|
||||
|
||||
it('does not load images around null island', function (done) {
|
||||
var data = {
|
||||
status: { apiCode: '600', httpCode: 200, httpMessage: 'Success' },
|
||||
currentPageItems:[{
|
||||
@@ -155,25 +152,26 @@ describe('iD.serviceKartaview', function() {
|
||||
totalFilteredItems: ['3']
|
||||
};
|
||||
|
||||
server.respondWith('POST', /nearby-photos/,
|
||||
[200, { 'Content-Type': 'application/json' }, JSON.stringify(data) ]);
|
||||
server.respond();
|
||||
var spy = sinon.spy();
|
||||
fetchMock.mock(new RegExp('/nearby-photos/'), {
|
||||
body: JSON.stringify(data),
|
||||
status: 200,
|
||||
headers: { 'Content-Type': 'application/json' }
|
||||
});
|
||||
|
||||
context.projection.translate([0, 0]);
|
||||
|
||||
kartaview.on('loadedImages', spy);
|
||||
kartaview.loadImages(context.projection);
|
||||
|
||||
window.setTimeout(function() {
|
||||
expect(spy).to.have.been.not.called;
|
||||
expect(server.requests().length).to.eql(0); // no tile requests of any kind
|
||||
expect(fetchMock.calls().length).to.eql(0); // no tile requests of any kind
|
||||
done();
|
||||
}, 200);
|
||||
});
|
||||
|
||||
it('loads multiple pages of image results', function(done) {
|
||||
kartaview.on('loadedImages', function() {
|
||||
expect(server.requests().length).to.eql(2); // 2 nearby-photos
|
||||
done();
|
||||
});
|
||||
|
||||
kartaview.loadImages(context.projection);
|
||||
|
||||
var features = [];
|
||||
for (var i = 0; i < 1000; i++) {
|
||||
var key = String(i);
|
||||
@@ -191,15 +189,25 @@ describe('iD.serviceKartaview', function() {
|
||||
username: 'test'
|
||||
});
|
||||
}
|
||||
|
||||
var response = {
|
||||
status: { apiCode: '600', httpCode: 200, httpMessage: 'Success' },
|
||||
currentPageItems: features,
|
||||
totalFilteredItems: ['1000']
|
||||
};
|
||||
|
||||
server.respondWith('POST', /nearby-photos/,
|
||||
[200, { 'Content-Type': 'application/json' }, JSON.stringify(response) ]);
|
||||
server.respond();
|
||||
fetchMock.mock(new RegExp('/nearby-photos/'), {
|
||||
body: JSON.stringify(response),
|
||||
status: 200,
|
||||
headers: { 'Content-Type': 'application/json' }
|
||||
});
|
||||
|
||||
kartaview.on('loadedImages', function() {
|
||||
expect(fetchMock.calls().length).to.eql(2); // 2 nearby-photos
|
||||
done();
|
||||
});
|
||||
|
||||
kartaview.loadImages(context.projection);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
describe('iD.serviceMapillary', function() {
|
||||
var dimensions = [64, 64];
|
||||
var context, server, mapillary;
|
||||
var context, mapillary;
|
||||
|
||||
|
||||
before(function() {
|
||||
@@ -18,14 +18,11 @@ describe('iD.serviceMapillary', function() {
|
||||
.translate([-116508, 0]) // 10,0
|
||||
.clipExtent([[0,0], dimensions]);
|
||||
|
||||
server = window.fakeFetch().create();
|
||||
mapillary = iD.services.mapillary;
|
||||
mapillary.reset();
|
||||
});
|
||||
|
||||
afterEach(function() {
|
||||
server.restore();
|
||||
});
|
||||
afterEach(function() {});
|
||||
|
||||
|
||||
describe('#init', function() {
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
describe('iD.serviceNominatim', function() {
|
||||
var server, nominatim;
|
||||
|
||||
var nominatim;
|
||||
|
||||
before(function() {
|
||||
iD.services.geocoder = iD.serviceNominatim;
|
||||
fetchMock.reset();
|
||||
});
|
||||
|
||||
after(function() {
|
||||
@@ -11,32 +11,31 @@ describe('iD.serviceNominatim', function() {
|
||||
});
|
||||
|
||||
beforeEach(function() {
|
||||
server = window.fakeFetch().create();
|
||||
nominatim = iD.services.geocoder;
|
||||
nominatim.reset();
|
||||
});
|
||||
|
||||
afterEach(function() {
|
||||
server.restore();
|
||||
fetchMock.reset();
|
||||
});
|
||||
|
||||
function query(url) {
|
||||
function parseQueryString(url) {
|
||||
return iD.utilStringQs(url.substring(url.indexOf('?')));
|
||||
}
|
||||
|
||||
|
||||
describe('#countryCode', function() {
|
||||
it('calls the given callback with the results of the country code query', function(done) {
|
||||
var callback = sinon.spy();
|
||||
fetchMock.mock(new RegExp('https://nominatim.openstreetmap.org/reverse'), {
|
||||
body: '{"address":{"country_code":"at"}}',
|
||||
status: 200,
|
||||
headers: { 'Content-Type': 'application/json' }
|
||||
});
|
||||
|
||||
nominatim.countryCode([16, 48], callback);
|
||||
|
||||
server.respondWith('GET', new RegExp('https://nominatim.openstreetmap.org/reverse'),
|
||||
[200, { 'Content-Type': 'application/json' },
|
||||
'{"address":{"country_code":"at"}}']);
|
||||
server.respond();
|
||||
|
||||
window.setTimeout(function() {
|
||||
expect(query(server.requests()[0].url)).to.eql(
|
||||
expect(parseQueryString(fetchMock.calls()[0][0])).to.eql(
|
||||
{zoom: '13', format: 'json', addressdetails: '1', lat: '48', lon: '16'}
|
||||
);
|
||||
expect(callback).to.have.been.calledWithExactly(null, 'at');
|
||||
@@ -48,30 +47,32 @@ describe('iD.serviceNominatim', function() {
|
||||
describe('#reverse', function() {
|
||||
it('should not cache distant result', function(done) {
|
||||
var callback = sinon.spy();
|
||||
fetchMock.mock(new RegExp('https://nominatim.openstreetmap.org/reverse'), {
|
||||
body: '{"address":{"country_code":"at"}}',
|
||||
status: 200,
|
||||
headers: { 'Content-Type': 'application/json' }
|
||||
});
|
||||
|
||||
nominatim.reverse([16, 48], callback);
|
||||
|
||||
server.respondWith('GET', new RegExp('https://nominatim.openstreetmap.org/reverse'),
|
||||
[200, { 'Content-Type': 'application/json' }, '{"address":{"country_code":"at"}}']);
|
||||
server.respond();
|
||||
|
||||
window.setTimeout(function() {
|
||||
expect(query(server.requests()[0].url)).to.eql(
|
||||
expect(parseQueryString(fetchMock.calls()[0][0])).to.eql(
|
||||
{zoom: '13', format: 'json', addressdetails: '1', lat: '48', lon: '16'}
|
||||
);
|
||||
expect(callback).to.have.been.calledWithExactly(null, {address: {country_code:'at'}});
|
||||
|
||||
server.restore();
|
||||
server = window.fakeFetch().create();
|
||||
fetchMock.reset();
|
||||
fetchMock.mock(new RegExp('https://nominatim.openstreetmap.org/reverse'), {
|
||||
body: '{"address":{"country_code":"cz"}}',
|
||||
status: 200,
|
||||
headers: { 'Content-Type': 'application/json' }
|
||||
});
|
||||
|
||||
callback = sinon.spy();
|
||||
nominatim.reverse([17, 49], callback);
|
||||
|
||||
server.respondWith('GET', new RegExp('https://nominatim.openstreetmap.org/reverse'),
|
||||
[200, { 'Content-Type': 'application/json' }, '{"address":{"country_code":"cz"}}']);
|
||||
server.respond();
|
||||
|
||||
window.setTimeout(function() {
|
||||
expect(query(server.requests()[0].url)).to.eql(
|
||||
expect(parseQueryString(fetchMock.calls()[0][0])).to.eql(
|
||||
{zoom: '13', format: 'json', addressdetails: '1', lat: '49', lon: '17'}
|
||||
);
|
||||
expect(callback).to.have.been.calledWithExactly(null, {address: {country_code:'cz'}});
|
||||
@@ -82,28 +83,25 @@ describe('iD.serviceNominatim', function() {
|
||||
|
||||
it('should cache nearby result', function(done) {
|
||||
var callback = sinon.spy();
|
||||
fetchMock.mock(new RegExp('https://nominatim.openstreetmap.org/reverse'), {
|
||||
body: '{"address":{"country_code":"at"}}',
|
||||
status: 200,
|
||||
headers: { 'Content-Type': 'application/json' }
|
||||
});
|
||||
|
||||
nominatim.reverse([16, 48], callback);
|
||||
|
||||
server.respondWith('GET', new RegExp('https://nominatim.openstreetmap.org/reverse'),
|
||||
[200, { 'Content-Type': 'application/json' }, '{"address":{"country_code":"at"}}']);
|
||||
server.respond();
|
||||
|
||||
window.setTimeout(function() {
|
||||
expect(query(server.requests()[0].url)).to.eql(
|
||||
expect(parseQueryString(fetchMock.calls()[0][0])).to.eql(
|
||||
{zoom: '13', format: 'json', addressdetails: '1', lat: '48', lon: '16'}
|
||||
);
|
||||
expect(callback).to.have.been.calledWithExactly(null, {address: {country_code:'at'}});
|
||||
|
||||
server.restore();
|
||||
server = window.fakeFetch().create();
|
||||
fetchMock.resetHistory();
|
||||
|
||||
callback = sinon.spy();
|
||||
nominatim.reverse([16.000001, 48.000001], callback);
|
||||
|
||||
server.respondWith('GET', new RegExp('https://nominatim.openstreetmap.org/reverse'),
|
||||
[200, { 'Content-Type': 'application/json' }, '{"address":{"country_code":"cz"}}']);
|
||||
server.respond();
|
||||
|
||||
window.setTimeout(function() {
|
||||
expect(callback).to.have.been.calledWithExactly(null, {address: {country_code:'at'}});
|
||||
done();
|
||||
@@ -113,15 +111,17 @@ describe('iD.serviceNominatim', function() {
|
||||
|
||||
it('calls the given callback with an error', function(done) {
|
||||
var callback = sinon.spy();
|
||||
fetchMock.mock(new RegExp('https://nominatim.openstreetmap.org/reverse'), {
|
||||
body: '{"error":"Unable to geocode"}',
|
||||
status: 200,
|
||||
headers: { 'Content-Type': 'application/json' }
|
||||
});
|
||||
|
||||
nominatim.reverse([1000, 1000], callback);
|
||||
|
||||
server.respondWith('GET', new RegExp('https://nominatim.openstreetmap.org/reverse'),
|
||||
[200, { 'Content-Type': 'application/json' },
|
||||
'{"error":"Unable to geocode"}']);
|
||||
server.respond();
|
||||
|
||||
window.setTimeout(function() {
|
||||
expect(query(server.requests()[0].url)).to.eql(
|
||||
expect(parseQueryString(fetchMock.calls()[0][0])).to.eql(
|
||||
{zoom: '13', format: 'json', addressdetails: '1', lat: '1000', lon: '1000'}
|
||||
);
|
||||
expect(callback).to.have.been.calledWithExactly('Unable to geocode');
|
||||
@@ -134,16 +134,16 @@ describe('iD.serviceNominatim', function() {
|
||||
describe('#search', function() {
|
||||
it('calls the given callback with the results of the search query', function(done) {
|
||||
var callback = sinon.spy();
|
||||
fetchMock.mock(new RegExp('https://nominatim.openstreetmap.org/search'), {
|
||||
body: '[{"place_id":"158484588","osm_type":"relation","osm_id":"188022","boundingbox":["39.867005","40.1379593","-75.2802976","-74.9558313"],"lat":"39.9523993","lon":"-75.1635898","display_name":"Philadelphia, Philadelphia County, Pennsylvania, United States of America","class":"place","type":"city","importance":0.83238050437778}]',
|
||||
status: 200,
|
||||
headers: { 'Content-Type': 'application/json' }
|
||||
});
|
||||
|
||||
nominatim.search('philadelphia', callback);
|
||||
|
||||
server.respondWith('GET', new RegExp('https://nominatim.openstreetmap.org/search'),
|
||||
[200, { 'Content-Type': 'application/json' },
|
||||
'[{"place_id":"158484588","osm_type":"relation","osm_id":"188022","boundingbox":["39.867005","40.1379593","-75.2802976","-74.9558313"],"lat":"39.9523993","lon":"-75.1635898","display_name":"Philadelphia, Philadelphia County, Pennsylvania, United States of America","class":"place","type":"city","importance":0.83238050437778}]'
|
||||
]);
|
||||
server.respond();
|
||||
|
||||
window.setTimeout(function() {
|
||||
expect(query(server.requests()[0].url)).to.eql({format: 'json', limit: '10'});
|
||||
expect(parseQueryString(fetchMock.calls()[0][0])).to.eql({format: 'json', limit: '10'});
|
||||
expect(callback).to.have.been.calledOnce;
|
||||
done();
|
||||
}, 50);
|
||||
|
||||
+166
-108
@@ -1,6 +1,6 @@
|
||||
describe('iD.serviceOsm', function () {
|
||||
var context, connection, spy;
|
||||
var serverFetch, serverXHR;
|
||||
var serverXHR;
|
||||
|
||||
function login() {
|
||||
connection.switch({
|
||||
@@ -25,7 +25,6 @@ describe('iD.serviceOsm', function () {
|
||||
});
|
||||
|
||||
beforeEach(function () {
|
||||
serverFetch = window.fakeFetch().create(); // unauthenticated calls use d3-fetch
|
||||
serverXHR = sinon.fakeServer.create(); // authenticated calls use XHR via osm-auth
|
||||
context = iD.coreContext().assetPath('../dist/').init();
|
||||
connection = context.connection();
|
||||
@@ -35,7 +34,7 @@ describe('iD.serviceOsm', function () {
|
||||
});
|
||||
|
||||
afterEach(function() {
|
||||
serverFetch.restore();
|
||||
fetchMock.reset();
|
||||
serverXHR.restore();
|
||||
});
|
||||
|
||||
@@ -44,14 +43,6 @@ describe('iD.serviceOsm', function () {
|
||||
expect(connection).to.be.ok;
|
||||
});
|
||||
|
||||
it('allows insecure connections', function () {
|
||||
expect(connection.changesetURL(2)).to.match(/^http:/);
|
||||
});
|
||||
|
||||
it('allows secure connections', function () {
|
||||
connection.switch({ urlroot: 'https://www.openstreetmap.org'});
|
||||
expect(connection.changesetURL(2)).to.match(/^https:/);
|
||||
});
|
||||
|
||||
describe('#getConnectionId', function() {
|
||||
it('changes the connection id every time connection is reset', function() {
|
||||
@@ -60,7 +51,8 @@ describe('iD.serviceOsm', function () {
|
||||
var cid2 = connection.getConnectionId();
|
||||
expect(cid2).to.be.above(cid1);
|
||||
});
|
||||
it('changes the connection id every time connection is switched', function() {
|
||||
|
||||
it('changes the connection id every time connection is switched', function () {
|
||||
var cid1 = connection.getConnectionId();
|
||||
connection.switch({ urlroot: 'https://api06.dev.openstreetmap.org' });
|
||||
var cid2 = connection.getConnectionId();
|
||||
@@ -72,6 +64,11 @@ describe('iD.serviceOsm', function () {
|
||||
it('provides a changeset url', function() {
|
||||
expect(connection.changesetURL(2)).to.eql('http://www.openstreetmap.org/changeset/2');
|
||||
});
|
||||
|
||||
it('allows secure connections', function() {
|
||||
connection.switch({ urlroot: 'https://www.openstreetmap.org' });
|
||||
expect(connection.changesetURL(2)).to.eql('https://www.openstreetmap.org/changeset/2');
|
||||
});
|
||||
});
|
||||
|
||||
describe('#changesetsURL', function() {
|
||||
@@ -87,10 +84,12 @@ describe('iD.serviceOsm', function () {
|
||||
var e = iD.osmNode({id: 'n1'});
|
||||
expect(connection.entityURL(e)).to.eql('http://www.openstreetmap.org/node/1');
|
||||
});
|
||||
|
||||
it('provides an entity url for a way', function() {
|
||||
var e = iD.osmWay({id: 'w1'});
|
||||
expect(connection.entityURL(e)).to.eql('http://www.openstreetmap.org/way/1');
|
||||
});
|
||||
|
||||
it('provides an entity url for a relation', function() {
|
||||
var e = iD.osmRelation({id: 'r1'});
|
||||
expect(connection.entityURL(e)).to.eql('http://www.openstreetmap.org/relation/1');
|
||||
@@ -102,10 +101,12 @@ describe('iD.serviceOsm', function () {
|
||||
var e = iD.osmNode({id: 'n1'});
|
||||
expect(connection.historyURL(e)).to.eql('http://www.openstreetmap.org/node/1/history');
|
||||
});
|
||||
|
||||
it('provides a history url for a way', function() {
|
||||
var e = iD.osmWay({id: 'w1'});
|
||||
expect(connection.historyURL(e)).to.eql('http://www.openstreetmap.org/way/1/history');
|
||||
});
|
||||
|
||||
it('provides a history url for a relation', function() {
|
||||
var e = iD.osmRelation({id: 'r1'});
|
||||
expect(connection.historyURL(e)).to.eql('http://www.openstreetmap.org/relation/1/history');
|
||||
@@ -151,74 +152,94 @@ describe('iD.serviceOsm', function () {
|
||||
'}';
|
||||
|
||||
it('returns an object', function(done) {
|
||||
fetchMock.mock('http://www.openstreetmap.org' + path, {
|
||||
body: response,
|
||||
status: 200,
|
||||
headers: { 'Content-Type': 'application/json' }
|
||||
});
|
||||
|
||||
connection.loadFromAPI(path, function (err, payload) {
|
||||
expect(err).to.not.be.ok;
|
||||
expect(typeof payload).to.eql('object');
|
||||
done();
|
||||
});
|
||||
|
||||
serverFetch.respondWith('GET', 'http://www.openstreetmap.org' + path,
|
||||
[200, { 'Content-Type': 'application/json' }, response]);
|
||||
serverFetch.respond();
|
||||
});
|
||||
|
||||
it('retries an authenticated call unauthenticated if 400 Bad Request', function (done) {
|
||||
fetchMock.mock('http://www.openstreetmap.org' + path, {
|
||||
body: response,
|
||||
status: 200,
|
||||
headers: { 'Content-Type': 'application/json' }
|
||||
});
|
||||
serverXHR.respondWith('GET', 'http://www.openstreetmap.org' + path,
|
||||
[400, { 'Content-Type': 'text/plain' }, 'Bad Request']);
|
||||
|
||||
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;
|
||||
expect(fetchMock.called()).to.be.true;
|
||||
|
||||
done();
|
||||
});
|
||||
|
||||
serverXHR.respondWith('GET', 'http://www.openstreetmap.org' + path,
|
||||
[400, { 'Content-Type': 'text/plain' }, 'Bad Request']);
|
||||
serverFetch.respondWith('GET', 'http://www.openstreetmap.org' + path,
|
||||
[200, { 'Content-Type': 'application/json' }, response]);
|
||||
|
||||
serverXHR.respond();
|
||||
serverFetch.respond();
|
||||
});
|
||||
|
||||
it('retries an authenticated call unauthenticated if 401 Unauthorized', function (done) {
|
||||
fetchMock.mock('http://www.openstreetmap.org' + path, {
|
||||
body: response,
|
||||
status: 200,
|
||||
headers: { 'Content-Type': 'application/json' }
|
||||
});
|
||||
serverXHR.respondWith('GET', 'http://www.openstreetmap.org' + path,
|
||||
[401, { 'Content-Type': 'text/plain' }, 'Unauthorized']);
|
||||
|
||||
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;
|
||||
expect(fetchMock.called()).to.be.true;
|
||||
|
||||
done();
|
||||
});
|
||||
|
||||
serverXHR.respondWith('GET', 'http://www.openstreetmap.org' + path,
|
||||
[401, { 'Content-Type': 'text/plain' }, 'Unauthorized']);
|
||||
serverFetch.respondWith('GET', 'http://www.openstreetmap.org' + path,
|
||||
[200, { 'Content-Type': 'application/json' }, response]);
|
||||
|
||||
serverXHR.respond();
|
||||
serverFetch.respond();
|
||||
});
|
||||
|
||||
it('retries an authenticated call unauthenticated if 403 Forbidden', function (done) {
|
||||
fetchMock.mock('http://www.openstreetmap.org' + path, {
|
||||
body: response,
|
||||
status: 200,
|
||||
headers: { 'Content-Type': 'application/json' }
|
||||
});
|
||||
serverXHR.respondWith('GET', 'http://www.openstreetmap.org' + path,
|
||||
[403, { 'Content-Type': 'text/plain' }, 'Forbidden']);
|
||||
|
||||
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;
|
||||
expect(fetchMock.called()).to.be.true;
|
||||
|
||||
done();
|
||||
});
|
||||
|
||||
serverXHR.respondWith('GET', 'http://www.openstreetmap.org' + path,
|
||||
[403, { 'Content-Type': 'text/plain' }, 'Forbidden']);
|
||||
serverFetch.respondWith('GET', 'http://www.openstreetmap.org' + path,
|
||||
[200, { 'Content-Type': 'application/json' }, response]);
|
||||
|
||||
serverXHR.respond();
|
||||
serverFetch.respond();
|
||||
});
|
||||
|
||||
|
||||
it('dispatches change event if 509 Bandwidth Limit Exceeded', function (done) {
|
||||
fetchMock.mock('http://www.openstreetmap.org' + path, {
|
||||
body: 'Bandwidth Limit Exceeded',
|
||||
status: 509,
|
||||
headers: { 'Content-Type': 'text/plain' }
|
||||
});
|
||||
|
||||
logout();
|
||||
connection.on('change', spy);
|
||||
connection.loadFromAPI(path, function (err) {
|
||||
@@ -226,13 +247,15 @@ describe('iD.serviceOsm', function () {
|
||||
expect(spy).to.have.been.calledOnce;
|
||||
done();
|
||||
});
|
||||
|
||||
serverFetch.respondWith('GET', 'http://www.openstreetmap.org' + path,
|
||||
[509, { 'Content-Type': 'text/plain' }, 'Bandwidth Limit Exceeded']);
|
||||
serverFetch.respond();
|
||||
});
|
||||
|
||||
it('dispatches change event if 429 Too Many Requests', function (done) {
|
||||
fetchMock.mock('http://www.openstreetmap.org' + path, {
|
||||
body: '429 Too Many Requests',
|
||||
status: 429,
|
||||
headers: { 'Content-Type': 'text/plain' }
|
||||
});
|
||||
|
||||
logout();
|
||||
connection.on('change', spy);
|
||||
connection.loadFromAPI(path, function (err) {
|
||||
@@ -240,10 +263,6 @@ describe('iD.serviceOsm', function () {
|
||||
expect(spy).to.have.been.calledOnce;
|
||||
done();
|
||||
});
|
||||
|
||||
serverFetch.respondWith('GET', 'http://www.openstreetmap.org' + path,
|
||||
[429, { 'Content-Type': 'text/plain' }, '429 Too Many Requests']);
|
||||
serverFetch.respond();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -267,13 +286,15 @@ describe('iD.serviceOsm', function () {
|
||||
});
|
||||
|
||||
it('calls callback when data tiles are loaded', function(done) {
|
||||
fetchMock.mock(/map.json\?bbox/, {
|
||||
body: tileResponse,
|
||||
status: 200,
|
||||
headers: { 'Content-Type': 'application/json' }
|
||||
});
|
||||
|
||||
var spy = sinon.spy();
|
||||
connection.loadTiles(context.projection, spy);
|
||||
|
||||
serverFetch.respondWith('GET', /map.json\?bbox/,
|
||||
[200, { 'Content-Type': 'application/json' }, tileResponse]);
|
||||
serverFetch.respond();
|
||||
|
||||
window.setTimeout(function() {
|
||||
expect(spy).to.have.been.calledOnce;
|
||||
done();
|
||||
@@ -281,15 +302,27 @@ describe('iD.serviceOsm', function () {
|
||||
});
|
||||
|
||||
it('#isDataLoaded', function(done) {
|
||||
expect(connection.isDataLoaded([-74.0444216, 40.6694299])).to.be.not.ok;
|
||||
fetchMock.mock(/map.json\?bbox/, {
|
||||
body: tileResponse,
|
||||
status: 200,
|
||||
headers: { 'Content-Type': 'application/json' }
|
||||
});
|
||||
|
||||
// resetting the cache
|
||||
const caches = connection.caches('get');
|
||||
caches.tile.toLoad = {};
|
||||
caches.tile.loaded = {};
|
||||
caches.tile.inflight = {};
|
||||
caches.tile.seen = {};
|
||||
caches.tile.rtree.clear();
|
||||
|
||||
expect(connection.isDataLoaded([-74.0444216, 40.6694299])).to.be.false;
|
||||
|
||||
connection.loadTiles(context.projection);
|
||||
serverFetch.respondWith('GET', /map.json\?bbox/,
|
||||
[200, { 'Content-Type': 'application/json' }, tileResponse]);
|
||||
serverFetch.respond();
|
||||
|
||||
window.setTimeout(function() {
|
||||
expect(connection.isDataLoaded([-74.0444216, 40.6694299])).to.be.ok;
|
||||
expect(fetchMock.called()).to.be.true;
|
||||
expect(connection.isDataLoaded([-74.0444216, 40.6694299])).to.be.true;
|
||||
done();
|
||||
}, 500);
|
||||
});
|
||||
@@ -303,6 +336,7 @@ describe('iD.serviceOsm', function () {
|
||||
' {"type":"node","id":1,"visible":true,"version":1,"changeset":28924294,"timestamp":"2009-03-07T03:26:33Z","user":"peace2","uid":119748,"lat":0,"lon":0}' +
|
||||
' ]' +
|
||||
'}';
|
||||
|
||||
var wayResponse =
|
||||
'{' +
|
||||
' "version":"0.6",' +
|
||||
@@ -313,47 +347,53 @@ describe('iD.serviceOsm', function () {
|
||||
'}';
|
||||
|
||||
it('loads a node', function(done) {
|
||||
fetchMock.mock('http://www.openstreetmap.org/api/0.6/node/1.json', {
|
||||
body: nodeResponse,
|
||||
status: 200,
|
||||
headers: { 'Content-Type': 'application/json' }
|
||||
});
|
||||
|
||||
var id = 'n1';
|
||||
connection.loadEntity(id, function(err, result) {
|
||||
var entity = result.data.find(function(e) { return e.id === id; });
|
||||
expect(entity).to.be.an.instanceOf(iD.osmNode);
|
||||
done();
|
||||
});
|
||||
|
||||
serverFetch.respondWith('GET', 'http://www.openstreetmap.org/api/0.6/node/1.json',
|
||||
[200, { 'Content-Type': 'application/json' }, nodeResponse]);
|
||||
serverFetch.respond();
|
||||
});
|
||||
|
||||
it('loads a way', function(done) {
|
||||
fetchMock.mock('http://www.openstreetmap.org/api/0.6/way/1/full.json', {
|
||||
body: wayResponse,
|
||||
status: 200,
|
||||
headers: { 'Content-Type': 'application/json' }
|
||||
});
|
||||
|
||||
var id = 'w1';
|
||||
connection.loadEntity(id, function(err, result) {
|
||||
var entity = result.data.find(function(e) { return e.id === id; });
|
||||
expect(entity).to.be.an.instanceOf(iD.osmWay);
|
||||
done();
|
||||
});
|
||||
|
||||
serverFetch.respondWith('GET', 'http://www.openstreetmap.org/api/0.6/way/1/full.json',
|
||||
[200, { 'Content-Type': 'application/json' }, wayResponse]);
|
||||
serverFetch.respond();
|
||||
});
|
||||
|
||||
it('does not ignore repeat requests', function(done) {
|
||||
fetchMock.mock('http://www.openstreetmap.org/api/0.6/node/1.json', {
|
||||
body: wayResponse,
|
||||
status: 200,
|
||||
headers: { 'Content-Type': 'application/json' }
|
||||
});
|
||||
|
||||
var id = 'n1';
|
||||
connection.loadEntity(id, function(err1, result1) {
|
||||
var entity1 = result1.data.find(function(e1) { return e1.id === id; });
|
||||
expect(entity1).to.be.an.instanceOf(iD.osmNode);
|
||||
|
||||
connection.loadEntity(id, function(err2, result2) {
|
||||
var entity2 = result2.data.find(function(e2) { return e2.id === id; });
|
||||
expect(entity2).to.be.an.instanceOf(iD.osmNode);
|
||||
done();
|
||||
});
|
||||
serverFetch.respond();
|
||||
});
|
||||
|
||||
serverFetch.respondWith('GET', 'http://www.openstreetmap.org/api/0.6/node/1.json',
|
||||
[200, { 'Content-Type': 'application/json' }, nodeResponse]);
|
||||
serverFetch.respond();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -376,47 +416,53 @@ describe('iD.serviceOsm', function () {
|
||||
'}';
|
||||
|
||||
it('loads a node', function(done) {
|
||||
fetchMock.mock('http://www.openstreetmap.org/api/0.6/node/1/1.json', {
|
||||
body: nodeResponse,
|
||||
status: 200,
|
||||
headers: { 'Content-Type': 'application/json' }
|
||||
});
|
||||
|
||||
var id = 'n1';
|
||||
connection.loadEntityVersion(id, 1, function(err, result) {
|
||||
var entity = result.data.find(function(e) { return e.id === id; });
|
||||
expect(entity).to.be.an.instanceOf(iD.osmNode);
|
||||
done();
|
||||
});
|
||||
|
||||
serverFetch.respondWith('GET', 'http://www.openstreetmap.org/api/0.6/node/1/1.json',
|
||||
[200, { 'Content-Type': 'application/json' }, nodeResponse]);
|
||||
serverFetch.respond();
|
||||
});
|
||||
|
||||
it('loads a way', function(done) {
|
||||
fetchMock.mock('http://www.openstreetmap.org/api/0.6/way/1/1.json', {
|
||||
body: wayResponse,
|
||||
status: 200,
|
||||
headers: { 'Content-Type': 'application/json' }
|
||||
});
|
||||
|
||||
var id = 'w1';
|
||||
connection.loadEntityVersion(id, 1, function(err, result) {
|
||||
var entity = result.data.find(function(e) { return e.id === id; });
|
||||
expect(entity).to.be.an.instanceOf(iD.osmWay);
|
||||
done();
|
||||
});
|
||||
|
||||
serverFetch.respondWith('GET', 'http://www.openstreetmap.org/api/0.6/way/1/1.json',
|
||||
[200, { 'Content-Type': 'application/json' }, wayResponse]);
|
||||
serverFetch.respond();
|
||||
});
|
||||
|
||||
it('does not ignore repeat requests', function(done) {
|
||||
fetchMock.mock('http://www.openstreetmap.org/api/0.6/node/1/1.json', {
|
||||
body: nodeResponse,
|
||||
status: 200,
|
||||
headers: { 'Content-Type': 'application/json' }
|
||||
});
|
||||
|
||||
var id = 'n1';
|
||||
connection.loadEntityVersion(id, 1, function(err1, result1) {
|
||||
var entity1 = result1.data.find(function(e1) { return e1.id === id; });
|
||||
expect(entity1).to.be.an.instanceOf(iD.osmNode);
|
||||
|
||||
connection.loadEntityVersion(id, 1, function(err2, result2) {
|
||||
var entity2 = result2.data.find(function(e2) { return e2.id === id; });
|
||||
expect(entity2).to.be.an.instanceOf(iD.osmNode);
|
||||
done();
|
||||
});
|
||||
serverFetch.respond();
|
||||
});
|
||||
|
||||
serverFetch.respondWith('GET', 'http://www.openstreetmap.org/api/0.6/node/1/1.json',
|
||||
[200, { 'Content-Type': 'application/json' }, nodeResponse]);
|
||||
serverFetch.respond();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -605,13 +651,15 @@ describe('iD.serviceOsm', function () {
|
||||
});
|
||||
|
||||
it('fires loadedNotes when notes are loaded', function(done) {
|
||||
fetchMock.mock(/notes\?/, {
|
||||
body: notesXML,
|
||||
status: 200,
|
||||
headers: { 'Content-Type': 'text/xml' }
|
||||
});
|
||||
|
||||
connection.on('loadedNotes', spy);
|
||||
connection.loadNotes(context.projection, {});
|
||||
|
||||
serverFetch.respondWith('GET', /notes\?/,
|
||||
[200, { 'Content-Type': 'text/xml' }, notesXML ]);
|
||||
serverFetch.respond();
|
||||
|
||||
window.setTimeout(function() {
|
||||
expect(spy).to.have.been.calledOnce;
|
||||
done();
|
||||
@@ -698,50 +746,60 @@ describe('iD.serviceOsm', function () {
|
||||
|
||||
|
||||
describe('API capabilities', function() {
|
||||
var 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>';
|
||||
var capabilitiesXML = `<?xml version="1.0" encoding="UTF-8"?>
|
||||
<osm version="0.6" generator="OpenStreetMap server" copyright="OpenStreetMap and contributors" attribution="http://www.openstreetmap.org/copyright" license="http://opendatacommons.org/licenses/odbl/1-0/">
|
||||
<api>
|
||||
<version minimum="0.6" maximum="0.6"/>
|
||||
<area maximum="0.25"/>
|
||||
<note_area maximum="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>`;
|
||||
|
||||
describe('#status', function() {
|
||||
it('gets API status', function(done) {
|
||||
connection.status(function(err, val) {
|
||||
fetchMock.mock('http://www.openstreetmap.org/api/capabilities', {
|
||||
body: capabilitiesXML,
|
||||
status: 200,
|
||||
headers: { 'Content-Type': 'text/xml' }
|
||||
}, {
|
||||
overwriteRoutes: true
|
||||
});
|
||||
|
||||
connection.status(function (err, val) {
|
||||
expect(val).to.eql('online');
|
||||
done();
|
||||
});
|
||||
|
||||
serverFetch.respondWith('GET', 'http://www.openstreetmap.org/api/capabilities',
|
||||
[200, { 'Content-Type': 'text/xml' }, capabilitiesXML]);
|
||||
serverFetch.respond();
|
||||
});
|
||||
});
|
||||
|
||||
describe('#imageryBlocklists', function() {
|
||||
it('updates imagery blocklists', function(done) {
|
||||
fetchMock.mock('http://www.openstreetmap.org/api/capabilities', {
|
||||
body: capabilitiesXML,
|
||||
status: 200,
|
||||
headers: { 'Content-Type': 'text/xml' }
|
||||
}, {
|
||||
overwriteRoutes: true
|
||||
});
|
||||
|
||||
connection.status(function() {
|
||||
var blocklists = connection.imageryBlocklists();
|
||||
expect(blocklists).to.deep.equal([new RegExp('\.foo\.com'), new RegExp('\.bar\.org')]);
|
||||
done();
|
||||
});
|
||||
|
||||
serverFetch.respondWith('GET', 'http://www.openstreetmap.org/api/capabilities',
|
||||
[200, { 'Content-Type': 'text/xml' }, capabilitiesXML]);
|
||||
serverFetch.respond();
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
});
|
||||
@@ -1,5 +1,5 @@
|
||||
describe('iD.serviceOsmWikibase', function () {
|
||||
var server, wikibase;
|
||||
var wikibase;
|
||||
|
||||
before(function () {
|
||||
iD.services.osmWikibase = iD.serviceOsmWikibase;
|
||||
@@ -10,17 +10,16 @@ describe('iD.serviceOsmWikibase', function () {
|
||||
});
|
||||
|
||||
beforeEach(function () {
|
||||
server = window.fakeFetch().create();
|
||||
wikibase = iD.services.osmWikibase;
|
||||
wikibase.init();
|
||||
});
|
||||
|
||||
afterEach(function () {
|
||||
server.restore();
|
||||
fetchMock.reset();
|
||||
});
|
||||
|
||||
|
||||
function query(url) {
|
||||
function parseQueryString(url) {
|
||||
return iD.utilStringQs(url.substring(url.indexOf('?')));
|
||||
}
|
||||
|
||||
@@ -265,22 +264,23 @@ describe('iD.serviceOsmWikibase', function () {
|
||||
describe('#getEntity', function () {
|
||||
it('calls the given callback with the results of the getEntity data item query', function (done) {
|
||||
var callback = sinon.spy();
|
||||
wikibase.getEntity({key: 'amenity', value: 'parking', langCodes: ['fr']}, callback);
|
||||
|
||||
server.respondWith('GET', /action=wbgetentities/,
|
||||
[200, {'Content-Type': 'application/json'}, JSON.stringify({
|
||||
fetchMock.mock(/action=wbgetentities/, {
|
||||
body: JSON.stringify({
|
||||
entities: {
|
||||
Q42: keyData(),
|
||||
Q13: tagData(),
|
||||
Q7792: localeData,
|
||||
},
|
||||
success: 1
|
||||
})]
|
||||
);
|
||||
server.respond();
|
||||
}),
|
||||
status: 200,
|
||||
headers: { 'Content-Type': 'application/json' }
|
||||
});
|
||||
|
||||
window.setTimeout(function() {
|
||||
expect(query(server.requests()[0].url)).to.eql(
|
||||
wikibase.getEntity({ key: 'amenity', value: 'parking', langCodes: ['fr'] }, callback);
|
||||
|
||||
window.setTimeout(function () {
|
||||
expect(parseQueryString(fetchMock.calls()[0][0])).to.eql(
|
||||
{
|
||||
action: 'wbgetentities',
|
||||
sites: 'wiki',
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
describe('iD.serviceStreetside', function() {
|
||||
var dimensions = [64, 64];
|
||||
var context, server, streetside;
|
||||
var context, streetside;
|
||||
|
||||
before(function() {
|
||||
iD.services.streetside = iD.serviceStreetside;
|
||||
@@ -17,14 +17,12 @@ describe('iD.serviceStreetside', function() {
|
||||
.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();
|
||||
});
|
||||
|
||||
|
||||
|
||||
+158
-161
@@ -1,5 +1,5 @@
|
||||
describe('iD.serviceTaginfo', function() {
|
||||
var server, taginfo;
|
||||
var taginfo;
|
||||
|
||||
|
||||
before(function() {
|
||||
@@ -11,43 +11,40 @@ describe('iD.serviceTaginfo', function() {
|
||||
});
|
||||
|
||||
beforeEach(function() {
|
||||
server = window.fakeFetch().create();
|
||||
taginfo = iD.services.taginfo;
|
||||
|
||||
fetchMock.mock(new RegExp('\/keys\/all.*sortname=values_all'), {
|
||||
body: '{"data":[{"count_all":56136034,"key":"name","count_all_fraction":0.0132}]}',
|
||||
status: 200,
|
||||
headers: { 'Content-Type': 'application/json' }
|
||||
});
|
||||
|
||||
// prepopulate popular keys list with "name"
|
||||
taginfo.init();
|
||||
server.respondWith('GET',
|
||||
new RegExp('\/keys\/all.*sortname=values_all'),
|
||||
[200, { 'Content-Type': 'application/json' },
|
||||
'{"data":[{"count_all":56136034,"key":"name","count_all_fraction":0.0132}]}']
|
||||
);
|
||||
server.respond();
|
||||
server.restore();
|
||||
server = window.fakeFetch().create();
|
||||
fetchMock.reset();
|
||||
});
|
||||
|
||||
afterEach(function() {
|
||||
server.restore();
|
||||
fetchMock.reset();
|
||||
});
|
||||
|
||||
function query(url) {
|
||||
function parseQueryString(url) {
|
||||
return iD.utilStringQs(url.substring(url.indexOf('?')));
|
||||
}
|
||||
|
||||
|
||||
describe('#keys', function() {
|
||||
it('calls the given callback with the results of the keys query', function(done) {
|
||||
var callback = sinon.spy();
|
||||
taginfo.keys({query: 'amen'}, callback);
|
||||
fetchMock.mock(/\/keys\/all/, {
|
||||
body: '{"data":[{"count_all":5190337,"key":"amenity","count_all_fraction":1.0}]}',
|
||||
status: 200,
|
||||
headers: { 'Content-Type': 'application/json' }
|
||||
});
|
||||
|
||||
server.respondWith('GET', /\/keys\/all/,
|
||||
[200, { 'Content-Type': 'application/json' },
|
||||
'{"data":[{"count_all":5190337,"key":"amenity","count_all_fraction":1.0}]}']
|
||||
);
|
||||
server.respond();
|
||||
var callback = sinon.spy();
|
||||
taginfo.keys({ query: 'amen' }, callback);
|
||||
|
||||
window.setTimeout(function() {
|
||||
expect(query(server.requests()[0].url)).to.eql(
|
||||
expect(parseQueryString(fetchMock.calls()[0][0])).to.eql(
|
||||
{query: 'amen', page: '1', rp: '10', sortname: 'count_all', sortorder: 'desc', lang: 'en'}
|
||||
);
|
||||
expect(callback).to.have.been.calledWith(
|
||||
@@ -58,15 +55,15 @@ describe('iD.serviceTaginfo', function() {
|
||||
});
|
||||
|
||||
it('includes popular keys', function(done) {
|
||||
var callback = sinon.spy();
|
||||
taginfo.keys({query: 'amen'}, callback);
|
||||
fetchMock.mock(/\/keys\/all/, {
|
||||
body: '{"data":[{"count_all":5190337,"count_nodes":500000,"key":"amenity","count_all_fraction":1.0, "count_nodes_fraction":1.0},'
|
||||
+ '{"count_all":1,"key":"amenityother","count_all_fraction":0.0, "count_nodes":100}]}',
|
||||
status: 200,
|
||||
headers: { 'Content-Type': 'application/json' }
|
||||
});
|
||||
|
||||
server.respondWith('GET', /\/keys\/all/,
|
||||
[200, { 'Content-Type': 'application/json' },
|
||||
'{"data":[{"count_all":5190337,"key":"amenity","count_all_fraction":1.0,"count_nodes_fraction":1.0},'
|
||||
+ '{"count_all":1,"key":"amenityother","count_all_fraction":0.0,"count_nodes_fraction":0.0}]}']
|
||||
);
|
||||
server.respond();
|
||||
var callback = sinon.spy();
|
||||
taginfo.keys({ query: 'amen' }, callback);
|
||||
|
||||
window.setTimeout(function() {
|
||||
expect(callback).to.have.been.calledWith(
|
||||
@@ -77,15 +74,15 @@ describe('iD.serviceTaginfo', function() {
|
||||
});
|
||||
|
||||
it('includes popular keys with an entity type filter', function(done) {
|
||||
var callback = sinon.spy();
|
||||
taginfo.keys({query: 'amen', filter: 'nodes'}, callback);
|
||||
fetchMock.mock(/\/keys\/all/, {
|
||||
body: '{"data":[{"count_all":5190337,"count_nodes":500000,"key":"amenity","count_all_fraction":1.0, "count_nodes_fraction":1.0},'
|
||||
+ '{"count_all":1,"key":"amenityother","count_all_fraction":0.0, "count_nodes":100}]}',
|
||||
status: 200,
|
||||
headers: { 'Content-Type': 'application/json' }
|
||||
});
|
||||
|
||||
server.respondWith('GET', /\/keys\/all/,
|
||||
[200, { 'Content-Type': 'application/json' },
|
||||
'{"data":[{"count_all":5190337,"count_nodes":500000,"key":"amenity","count_all_fraction":1.0, "count_nodes_fraction":1.0},'
|
||||
+ '{"count_all":1,"key":"amenityother","count_all_fraction":0.0, "count_nodes":100}]}']
|
||||
);
|
||||
server.respond();
|
||||
var callback = sinon.spy();
|
||||
taginfo.keys({ query: 'amen', filter: 'nodes' }, callback);
|
||||
|
||||
window.setTimeout(function() {
|
||||
expect(callback).to.have.been.calledWith(
|
||||
@@ -96,15 +93,15 @@ describe('iD.serviceTaginfo', function() {
|
||||
});
|
||||
|
||||
it('includes unpopular keys with a wiki page', function(done) {
|
||||
var callback = sinon.spy();
|
||||
taginfo.keys({query: 'amen'}, callback);
|
||||
fetchMock.mock(/\/keys\/all/, {
|
||||
body: '{"data":[{"count_all":5190337,"key":"amenity","count_all_fraction":1.0, "count_nodes_fraction":1.0},'
|
||||
+ '{"count_all":1,"key":"amenityother","count_all_fraction":0.0, "count_nodes_fraction":0.0, "in_wiki": true}]}',
|
||||
status: 200,
|
||||
headers: { 'Content-Type': 'application/json' }
|
||||
});
|
||||
|
||||
server.respondWith('GET', /\/keys\/all/,
|
||||
[200, { 'Content-Type': 'application/json' },
|
||||
'{"data":[{"count_all":5190337,"key":"amenity","count_all_fraction":1.0, "count_nodes_fraction":1.0},'
|
||||
+ '{"count_all":1,"key":"amenityother","count_all_fraction":0.0, "count_nodes_fraction":0.0, "in_wiki": true}]}']
|
||||
);
|
||||
server.respond();
|
||||
var callback = sinon.spy();
|
||||
taginfo.keys({ query: 'amen' }, callback);
|
||||
|
||||
window.setTimeout(function() {
|
||||
expect(callback).to.have.been.calledWith(null, [
|
||||
@@ -116,15 +113,15 @@ describe('iD.serviceTaginfo', function() {
|
||||
});
|
||||
|
||||
it('sorts keys with \':\' below keys without \':\'', function(done) {
|
||||
var callback = sinon.spy();
|
||||
taginfo.keys({query: 'ref'}, callback);
|
||||
fetchMock.mock(/\/keys\/all/, {
|
||||
body: '{"data":[{"key":"ref:bag","count_all":9790586,"count_all_fraction":0.0028},' +
|
||||
'{"key":"ref","count_all":7933528,"count_all_fraction":0.0023}]}',
|
||||
status: 200,
|
||||
headers: { 'Content-Type': 'application/json' }
|
||||
});
|
||||
|
||||
server.respondWith('GET', /\/keys\/all/,
|
||||
[200, { 'Content-Type': 'application/json' },
|
||||
'{"data":[{"key":"ref:bag","count_all":9790586,"count_all_fraction":0.0028},' +
|
||||
'{"key":"ref","count_all":7933528,"count_all_fraction":0.0023}]}']
|
||||
);
|
||||
server.respond();
|
||||
var callback = sinon.spy();
|
||||
taginfo.keys({ query: 'ref' }, callback);
|
||||
|
||||
window.setTimeout(function() {
|
||||
expect(callback).to.have.been.calledWith(
|
||||
@@ -137,17 +134,17 @@ describe('iD.serviceTaginfo', function() {
|
||||
|
||||
describe('#multikeys', function() {
|
||||
it('calls the given callback with the results of the multikeys query', function(done) {
|
||||
var callback = sinon.spy();
|
||||
taginfo.multikeys({query: 'recycling:'}, callback);
|
||||
fetchMock.mock(/\/keys\/all/, {
|
||||
body: '{"data":[{"count_all":69593,"key":"recycling:glass","count_all_fraction":0.0}]}',
|
||||
status: 200,
|
||||
headers: { 'Content-Type': 'application/json' }
|
||||
});
|
||||
|
||||
server.respondWith('GET', /\/keys\/all/,
|
||||
[200, { 'Content-Type': 'application/json' },
|
||||
'{"data":[{"count_all":69593,"key":"recycling:glass","count_all_fraction":0.0}]}']
|
||||
);
|
||||
server.respond();
|
||||
var callback = sinon.spy();
|
||||
taginfo.multikeys({ query: 'recycling:' }, callback);
|
||||
|
||||
window.setTimeout(function() {
|
||||
expect(query(server.requests()[0].url)).to.eql(
|
||||
expect(parseQueryString(fetchMock.calls()[0][0])).to.eql(
|
||||
{query: 'recycling:', page: '1', rp: '25', sortname: 'count_all', sortorder: 'desc', lang: 'en'}
|
||||
);
|
||||
expect(callback).to.have.been.calledWith(
|
||||
@@ -158,15 +155,15 @@ describe('iD.serviceTaginfo', function() {
|
||||
});
|
||||
|
||||
it('excludes multikeys with extra colons', function(done) {
|
||||
var callback = sinon.spy();
|
||||
taginfo.multikeys({query: 'service:bicycle:'}, callback);
|
||||
fetchMock.mock(/\/keys\/all/, {
|
||||
body: '{"data":[{"count_all":4426,"key":"service:bicycle:retail","count_all_fraction":0.0},' +
|
||||
'{"count_all":22,"key":"service:bicycle:retail:ebikes","count_all_fraction":0.0}]}',
|
||||
status: 200,
|
||||
headers: { 'Content-Type': 'application/json' }
|
||||
});
|
||||
|
||||
server.respondWith('GET', /\/keys\/all/,
|
||||
[200, { 'Content-Type': 'application/json' },
|
||||
'{"data":[{"count_all":4426,"key":"service:bicycle:retail","count_all_fraction":0.0},' +
|
||||
'{"count_all":22,"key":"service:bicycle:retail:ebikes","count_all_fraction":0.0}]}']
|
||||
);
|
||||
server.respond();
|
||||
var callback = sinon.spy();
|
||||
taginfo.multikeys({ query: 'service:bicycle:' }, callback);
|
||||
|
||||
window.setTimeout(function() {
|
||||
expect(callback).to.have.been.calledWith(
|
||||
@@ -177,15 +174,15 @@ describe('iD.serviceTaginfo', function() {
|
||||
});
|
||||
|
||||
it('excludes multikeys with wrong prefix', function(done) {
|
||||
var callback = sinon.spy();
|
||||
taginfo.multikeys({query: 'service:bicycle:'}, callback);
|
||||
fetchMock.mock(/\/keys\/all/, {
|
||||
body: '{"data":[{"count_all":4426,"key":"service:bicycle:retail","count_all_fraction":0.0},' +
|
||||
'{"count_all":22,"key":"disused:service:bicycle","count_all_fraction":0.0}]}',
|
||||
status: 200,
|
||||
headers: { 'Content-Type': 'application/json' }
|
||||
});
|
||||
|
||||
server.respondWith('GET', /\/keys\/all/,
|
||||
[200, { 'Content-Type': 'application/json' },
|
||||
'{"data":[{"count_all":4426,"key":"service:bicycle:retail","count_all_fraction":0.0},' +
|
||||
'{"count_all":22,"key":"disused:service:bicycle","count_all_fraction":0.0}]}']
|
||||
);
|
||||
server.respond();
|
||||
var callback = sinon.spy();
|
||||
taginfo.multikeys({ query: 'service:bicycle:' }, callback);
|
||||
|
||||
window.setTimeout(function() {
|
||||
expect(callback).to.have.been.calledWith(
|
||||
@@ -198,17 +195,17 @@ describe('iD.serviceTaginfo', function() {
|
||||
|
||||
describe('#values', function() {
|
||||
it('calls the given callback with the results of the values query', function(done) {
|
||||
var callback = sinon.spy();
|
||||
taginfo.values({key: 'amenity', query: 'par'}, callback);
|
||||
fetchMock.mock(/\/key\/values/, {
|
||||
body: '{"data":[{"value":"parking","description":"A place for parking cars", "fraction":0.1}]}',
|
||||
status: 200,
|
||||
headers: { 'Content-Type': 'application/json' }
|
||||
});
|
||||
|
||||
server.respondWith('GET', /\/key\/values/,
|
||||
[200, { 'Content-Type': 'application/json' },
|
||||
'{"data":[{"value":"parking","description":"A place for parking cars", "fraction":0.1}]}']
|
||||
);
|
||||
server.respond();
|
||||
var callback = sinon.spy();
|
||||
taginfo.values({ key: 'amenity', query: 'par' }, callback);
|
||||
|
||||
window.setTimeout(function() {
|
||||
expect(query(server.requests()[0].url)).to.eql(
|
||||
expect(parseQueryString(fetchMock.calls()[0][0])).to.eql(
|
||||
{key: 'amenity', query: 'par', page: '1', rp: '25', sortname: 'count_all', sortorder: 'desc', lang: 'en'}
|
||||
);
|
||||
expect(callback).to.have.been.calledWith(
|
||||
@@ -219,15 +216,15 @@ describe('iD.serviceTaginfo', function() {
|
||||
});
|
||||
|
||||
it('includes popular values', function(done) {
|
||||
var callback = sinon.spy();
|
||||
taginfo.values({key: 'amenity', query: 'par'}, callback);
|
||||
fetchMock.mock(/\/key\/values/, {
|
||||
body: '{"data":[{"value":"parking","description":"A place for parking cars", "fraction":1.0},' +
|
||||
'{"value":"party","description":"A place for partying", "fraction":0.0}]}',
|
||||
status: 200,
|
||||
headers: { 'Content-Type': 'application/json' }
|
||||
});
|
||||
|
||||
server.respondWith('GET', /\/key\/values/,
|
||||
[200, { 'Content-Type': 'application/json' },
|
||||
'{"data":[{"value":"parking","description":"A place for parking cars", "fraction":1.0},' +
|
||||
'{"value":"party","description":"A place for partying", "fraction":0.0}]}']
|
||||
);
|
||||
server.respond();
|
||||
var callback = sinon.spy();
|
||||
taginfo.values({ key: 'amenity', query: 'par' }, callback);
|
||||
|
||||
window.setTimeout(function() {
|
||||
expect(callback).to.have.been.calledWith(
|
||||
@@ -238,15 +235,15 @@ describe('iD.serviceTaginfo', function() {
|
||||
});
|
||||
|
||||
it('does not get values for extremely unpopular keys', function(done) {
|
||||
var callback = sinon.spy();
|
||||
taginfo.values({key: 'name', query: 'ste'}, callback);
|
||||
fetchMock.mock(/\/key\/values/, {
|
||||
body: '{"data":[{"value":"Rue Pasteur","description":"", "fraction":0.0001},' +
|
||||
'{"value":"Via Trieste","description":"", "fraction":0.0001}]}',
|
||||
status: 200,
|
||||
headers: { 'Content-Type': 'application/json' }
|
||||
});
|
||||
|
||||
server.respondWith('GET', /\/key\/values/,
|
||||
[200, { 'Content-Type': 'application/json' },
|
||||
'{"data":[{"value":"Rue Pasteur","description":"", "fraction":0.0001},' +
|
||||
'{"value":"Via Trieste","description":"", "fraction":0.0001}]}']
|
||||
);
|
||||
server.respond();
|
||||
var callback = sinon.spy();
|
||||
taginfo.values({ key: 'name', query: 'ste' }, callback);
|
||||
|
||||
window.setTimeout(function() {
|
||||
expect(callback).to.have.been.calledWith(null, []);
|
||||
@@ -255,18 +252,18 @@ describe('iD.serviceTaginfo', function() {
|
||||
});
|
||||
|
||||
it('excludes values with capital letters and some punctuation', function(done) {
|
||||
var callback = sinon.spy();
|
||||
taginfo.values({key: 'amenity', query: 'par'}, callback);
|
||||
fetchMock.mock(/\/key\/values/, {
|
||||
body: '{"data":[{"value":"parking","description":"A place for parking cars", "fraction":0.2},'
|
||||
+ '{"value":"PArking","description":"A common misspelling", "fraction":0.2},'
|
||||
+ '{"value":"parking;partying","description":"A place for parking cars *and* partying", "fraction":0.2},'
|
||||
+ '{"value":"parking, partying","description":"A place for parking cars *and* partying", "fraction":0.2},'
|
||||
+ '{"value":"*","description":"", "fraction":0.2}]}',
|
||||
status: 200,
|
||||
headers: { 'Content-Type': 'application/json' }
|
||||
});
|
||||
|
||||
server.respondWith('GET', /\/key\/values/,
|
||||
[200, { 'Content-Type': 'application/json' },
|
||||
'{"data":[{"value":"parking","description":"A place for parking cars", "fraction":0.2},'
|
||||
+ '{"value":"PArking","description":"A common misspelling", "fraction":0.2},'
|
||||
+ '{"value":"parking;partying","description":"A place for parking cars *and* partying", "fraction":0.2},'
|
||||
+ '{"value":"parking, partying","description":"A place for parking cars *and* partying", "fraction":0.2},'
|
||||
+ '{"value":"*","description":"", "fraction":0.2}]}']
|
||||
);
|
||||
server.respond();
|
||||
var callback = sinon.spy();
|
||||
taginfo.values({ key: 'amenity', query: 'par' }, callback);
|
||||
|
||||
window.setTimeout(function() {
|
||||
expect(callback).to.have.been.calledWith(
|
||||
@@ -277,18 +274,18 @@ describe('iD.serviceTaginfo', function() {
|
||||
});
|
||||
|
||||
it('includes network values with capital letters and some punctuation', function(done) {
|
||||
var callback = sinon.spy();
|
||||
taginfo.values({key: 'network', query: 'us'}, callback);
|
||||
fetchMock.mock(/\/key\/values/, {
|
||||
body: '{"data":[{"value":"US:TX:FM","description":"Farm to Market Roads in the U.S. state of Texas.", "fraction":0.34},'
|
||||
+ '{"value":"US:KY","description":"Primary and secondary state highways in the U.S. state of Kentucky.", "fraction":0.31},'
|
||||
+ '{"value":"US:US","description":"U.S. routes in the United States.", "fraction":0.19},'
|
||||
+ '{"value":"US:I","description":"Interstate highways in the United States.", "fraction":0.11},'
|
||||
+ '{"value":"US:MD","description":"State highways in the U.S. state of Maryland.", "fraction":0.06}]}',
|
||||
status: 200,
|
||||
headers: { 'Content-Type': 'application/json' }
|
||||
});
|
||||
|
||||
server.respondWith('GET', /\/key\/values/,
|
||||
[200, { 'Content-Type': 'application/json' },
|
||||
'{"data":[{"value":"US:TX:FM","description":"Farm to Market Roads in the U.S. state of Texas.", "fraction":0.34},'
|
||||
+ '{"value":"US:KY","description":"Primary and secondary state highways in the U.S. state of Kentucky.", "fraction":0.31},'
|
||||
+ '{"value":"US:US","description":"U.S. routes in the United States.", "fraction":0.19},'
|
||||
+ '{"value":"US:I","description":"Interstate highways in the United States.", "fraction":0.11},'
|
||||
+ '{"value":"US:MD","description":"State highways in the U.S. state of Maryland.", "fraction":0.06}]}']
|
||||
);
|
||||
server.respond();
|
||||
var callback = sinon.spy();
|
||||
taginfo.values({ key: 'network', query: 'us' }, callback);
|
||||
|
||||
window.setTimeout(function() {
|
||||
expect(callback).to.have.been.calledWith(null, [
|
||||
@@ -303,14 +300,14 @@ describe('iD.serviceTaginfo', function() {
|
||||
});
|
||||
|
||||
it('includes biological genus values with capital letters', function(done) {
|
||||
var callback = sinon.spy();
|
||||
taginfo.values({key: 'genus', query: 'qu'}, callback);
|
||||
fetchMock.mock(/\/key\/values/, {
|
||||
body: '{"data":[{"value":"Quercus","description":"Oak", "fraction":0.5}]}',
|
||||
status: 200,
|
||||
headers: { 'Content-Type': 'application/json' }
|
||||
});
|
||||
|
||||
server.respondWith('GET', /\/key\/values/,
|
||||
[200, { 'Content-Type': 'application/json' },
|
||||
'{"data":[{"value":"Quercus","description":"Oak", "fraction":0.5}]}']
|
||||
);
|
||||
server.respond();
|
||||
var callback = sinon.spy();
|
||||
taginfo.values({ key: 'genus', query: 'qu' }, callback);
|
||||
|
||||
window.setTimeout(function() {
|
||||
expect(callback).to.have.been.calledWith(
|
||||
@@ -321,14 +318,14 @@ describe('iD.serviceTaginfo', function() {
|
||||
});
|
||||
|
||||
it('includes biological taxon values with capital letters', function(done) {
|
||||
var callback = sinon.spy();
|
||||
taginfo.values({key: 'taxon', query: 'qu'}, callback);
|
||||
fetchMock.mock(/\/key\/values/, {
|
||||
body: '{"data":[{"value":"Quercus robur","description":"Oak", "fraction":0.5}]}',
|
||||
status: 200,
|
||||
headers: { 'Content-Type': 'application/json' }
|
||||
});
|
||||
|
||||
server.respondWith('GET', /\/key\/values/,
|
||||
[200, { 'Content-Type': 'application/json' },
|
||||
'{"data":[{"value":"Quercus robur","description":"Oak", "fraction":0.5}]}']
|
||||
);
|
||||
server.respond();
|
||||
var callback = sinon.spy();
|
||||
taginfo.values({ key: 'taxon', query: 'qu' }, callback);
|
||||
|
||||
window.setTimeout(function() {
|
||||
expect(callback).to.have.been.calledWith(
|
||||
@@ -339,14 +336,14 @@ describe('iD.serviceTaginfo', function() {
|
||||
});
|
||||
|
||||
it('includes biological species values with capital letters', function(done) {
|
||||
var callback = sinon.spy();
|
||||
taginfo.values({key: 'species', query: 'qu'}, callback);
|
||||
fetchMock.mock(/\/key\/values/, {
|
||||
body: '{"data":[{"value":"Quercus robur","description":"Oak", "fraction":0.5}]}',
|
||||
status: 200,
|
||||
headers: { 'Content-Type': 'application/json' }
|
||||
});
|
||||
|
||||
server.respondWith('GET', /\/key\/values/,
|
||||
[200, { 'Content-Type': 'application/json' },
|
||||
'{"data":[{"value":"Quercus robur","description":"Oak", "fraction":0.5}]}']
|
||||
);
|
||||
server.respond();
|
||||
var callback = sinon.spy();
|
||||
taginfo.values({ key: 'species', query: 'qu' }, callback);
|
||||
|
||||
window.setTimeout(function() {
|
||||
expect(callback).to.have.been.calledWith(
|
||||
@@ -359,18 +356,18 @@ describe('iD.serviceTaginfo', function() {
|
||||
|
||||
describe('#roles', function() {
|
||||
it('calls the given callback with the results of the roles query', function(done) {
|
||||
var callback = sinon.spy();
|
||||
taginfo.roles({rtype: 'route', query: 's', geometry: 'relation'}, callback);
|
||||
fetchMock.mock(/\/relation\/roles/, {
|
||||
body: '{"data":[{"role":"stop","count_relation_members_fraction":0.1757},' +
|
||||
'{"role":"south","count_relation_members_fraction":0.0035}]}',
|
||||
status: 200,
|
||||
headers: { 'Content-Type': 'application/json' }
|
||||
});
|
||||
|
||||
server.respondWith('GET', /\/relation\/roles/,
|
||||
[200, { 'Content-Type': 'application/json' },
|
||||
'{"data":[{"role":"stop","count_relation_members_fraction":0.1757},' +
|
||||
'{"role":"south","count_relation_members_fraction":0.0035}]}']
|
||||
);
|
||||
server.respond();
|
||||
var callback = sinon.spy();
|
||||
taginfo.roles({ rtype: 'route', query: 's', geometry: 'relation' }, callback);
|
||||
|
||||
window.setTimeout(function() {
|
||||
expect(query(server.requests()[0].url)).to.eql(
|
||||
expect(parseQueryString(fetchMock.calls()[0][0])).to.eql(
|
||||
{rtype: 'route', query: 's', page: '1', rp: '25', sortname: 'count_relation_members', sortorder: 'desc', lang: 'en'}
|
||||
);
|
||||
expect(callback).to.have.been.calledWith(null, [
|
||||
@@ -384,17 +381,17 @@ describe('iD.serviceTaginfo', function() {
|
||||
|
||||
describe('#docs', function() {
|
||||
it('calls the given callback with the results of the docs query', function(done) {
|
||||
var callback = sinon.spy();
|
||||
taginfo.docs({key: 'amenity', value: 'parking'}, callback);
|
||||
fetchMock.mock(/\/tag\/wiki_page/, {
|
||||
body: '{"data":[{"on_way":false,"lang":"en","on_area":true,"image":"File:Car park2.jpg"}]}',
|
||||
status: 200,
|
||||
headers: { 'Content-Type': 'application/json' }
|
||||
});
|
||||
|
||||
server.respondWith('GET', /\/tag\/wiki_page/,
|
||||
[200, { 'Content-Type': 'application/json' },
|
||||
'{"data":[{"on_way":false,"lang":"en","on_area":true,"image":"File:Car park2.jpg"}]}']
|
||||
);
|
||||
server.respond();
|
||||
var callback = sinon.spy();
|
||||
taginfo.docs({ key: 'amenity', value: 'parking' }, callback);
|
||||
|
||||
window.setTimeout(function() {
|
||||
expect(query(server.requests()[0].url)).to.eql(
|
||||
expect(parseQueryString(fetchMock.calls()[0][0])).to.eql(
|
||||
{key: 'amenity', value: 'parking'}
|
||||
);
|
||||
expect(callback).to.have.been.calledWith(
|
||||
|
||||
+25
-141
@@ -112,146 +112,30 @@ expect = chai.expect;
|
||||
window.d3 = iD.d3; // Remove this if we can avoid exporting all of d3.js
|
||||
delete window.PointerEvent; // force the browser to use mouse events
|
||||
|
||||
// Workaround for `Array.from` polyfill in PhantomJS
|
||||
// https://github.com/openstreetmap/iD/issues/6087#issuecomment-476219308
|
||||
var __arrayfrom = Array.from;
|
||||
Array.from = function(what) {
|
||||
if (what instanceof Set) {
|
||||
var arr = [];
|
||||
what.forEach(function(v) { arr.push(v); });
|
||||
return arr;
|
||||
} else {
|
||||
return __arrayfrom.apply(null, arguments);
|
||||
}
|
||||
};
|
||||
// some sticky fallbacks
|
||||
const capabilities = `<?xml version="1.0" encoding="UTF-8"?>
|
||||
<osm version="0.6" generator="OpenStreetMap server" copyright="OpenStreetMap and contributors" attribution="http://www.openstreetmap.org/copyright" license="http://opendatacommons.org/licenses/odbl/1-0/">
|
||||
<api>
|
||||
<version minimum="0.6" maximum="0.6"/>
|
||||
<area maximum="0.25"/>
|
||||
<note_area maximum="25"/>
|
||||
<tracepoints per_page="5000"/>
|
||||
<waynodes maximum="2000"/>
|
||||
<changesets maximum_elements="10000"/>
|
||||
<timeout seconds="300"/>
|
||||
<status database="online" api="online" gpx="online"/>
|
||||
</api>
|
||||
<policy>
|
||||
<imagery>
|
||||
<blacklist regex=".*\.google(apis)?\..*/(vt|kh)[\?/].*([xyz]=.*){3}.*"/>
|
||||
<blacklist regex="http://xdworld\.vworld\.kr:8080/.*"/>
|
||||
<blacklist regex=".*\.here\.com[/:].*"/>
|
||||
</imagery>
|
||||
</policy>
|
||||
</osm>`;
|
||||
|
||||
// Workaround for `ArrayBuffer.isView` in PhantomJS
|
||||
// https://github.com/openstreetmap/iD/issues/7072
|
||||
if (typeof ArrayBuffer.isView === 'undefined') {
|
||||
ArrayBuffer.isView = function() { return false; };
|
||||
}
|
||||
fetchMock.sticky('https://www.openstreetmap.org/api/capabilities', capabilities, {sticky: true});
|
||||
fetchMock.sticky('http://www.openstreetmap.org/api/capabilities', capabilities, {sticky: true});
|
||||
|
||||
// Polyfill for `Math.sign()` in PhantomJS
|
||||
// From https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/sign#Polyfill
|
||||
if (!Math.sign) {
|
||||
Math.sign = function(x) {
|
||||
return ((x > 0) - (x < 0)) || +x;
|
||||
};
|
||||
}
|
||||
|
||||
// Add support for sinon-stubbing `fetch` API
|
||||
// (sinon fakeServer works only on `XMLHttpRequest`)
|
||||
// see https://github.com/sinonjs/nise/issues/7
|
||||
//
|
||||
// None of the alternatives really worked well,
|
||||
// so I'm just wrapping the `fake-fetch` methods in here.
|
||||
// - https://github.com/msn0/fake-fetch
|
||||
// - https://github.com/wheresrhys/fetch-mock
|
||||
|
||||
window.fakeFetch = function() {
|
||||
var _responders = [];
|
||||
var _requests = [];
|
||||
|
||||
function fake(url, options) {
|
||||
options = Object.assign({ method: 'get', headers: {}, body: '' }, options);
|
||||
return new Promise(function(resolve, reject) {
|
||||
_requests.push({
|
||||
url: url, options: options, resolve: resolve, reject: reject, processed: false
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
return {
|
||||
requests: function() {
|
||||
return _requests;
|
||||
},
|
||||
|
||||
create: function () {
|
||||
_responders = [];
|
||||
_requests = [];
|
||||
sinon.stub(window, 'fetch').callsFake(fake);
|
||||
return this;
|
||||
},
|
||||
|
||||
restore: function () {
|
||||
window.fetch.restore();
|
||||
},
|
||||
|
||||
getUrl: function () {
|
||||
return window.fetch.firstCall.args[0];
|
||||
},
|
||||
|
||||
getOptions: function () {
|
||||
return window.fetch.firstCall.args[1] || {};
|
||||
},
|
||||
|
||||
getMethod: function () {
|
||||
return this.getOptions().method || 'get';
|
||||
},
|
||||
|
||||
getBody: function () {
|
||||
return this.getOptions().body || '';
|
||||
},
|
||||
|
||||
getRequestHeaders: function () {
|
||||
return this.getOptions().headers || {};
|
||||
},
|
||||
|
||||
respondWith: function(method, match, response) {
|
||||
var status = 200;
|
||||
var headers = { 'Content-Type': 'text/html' };
|
||||
var body = 'OK';
|
||||
|
||||
if (typeof response === 'string') {
|
||||
body = response;
|
||||
} else if (Array.isArray(response) && response.length === 3) {
|
||||
status = response[0];
|
||||
headers = Object.assign(headers, response[1] || {});
|
||||
body = response[2];
|
||||
}
|
||||
|
||||
headers['Content-Length'] = body.length;
|
||||
var data = new Blob([body], { type: headers['Content-Type'] });
|
||||
var options = { status: status, headers: headers };
|
||||
|
||||
_responders.push({
|
||||
method: method,
|
||||
match: match,
|
||||
respond: function() { return new Response(data, options); }
|
||||
});
|
||||
},
|
||||
|
||||
respond: function () {
|
||||
_requests.forEach(function(request) {
|
||||
if (request.processed) return;
|
||||
|
||||
var didMatch = false;
|
||||
for (var i = 0; i < _responders.length; i++) {
|
||||
var responder = _responders[i];
|
||||
if (responder.method.toLowerCase() !== request.options.method.toLowerCase()) {
|
||||
continue; // skip if method doesn't match (get/post)
|
||||
}
|
||||
|
||||
if (responder.match.constructor.name === 'RegExp') {
|
||||
didMatch = responder.match.test(request.url);
|
||||
} else if (typeof responder.match === 'string') {
|
||||
didMatch = (request.url.indexOf(responder.match) !== -1);
|
||||
}
|
||||
|
||||
if (didMatch) {
|
||||
request.processed = true;
|
||||
request.resolve(responder.respond());
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!didMatch) {
|
||||
request.processed = true;
|
||||
request.reject(new Response(
|
||||
new Blob(['404'], { type: 'text/plain' }),
|
||||
{ status: 404, statusText: 'Not Found' }
|
||||
));
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
};
|
||||
fetchMock.config.fallbackToNetwork = true;
|
||||
fetchMock.config.overwriteRoutes = false;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
describe('iD.uiFieldWikipedia', function() {
|
||||
var entity, context, selection, field, server;
|
||||
var entity, context, selection, field;
|
||||
|
||||
before(function() {
|
||||
iD.fileFetcher.cache().wmf_sitematrix = [
|
||||
@@ -26,11 +26,16 @@ describe('iD.uiFieldWikipedia', function() {
|
||||
keys: ['wikipedia', 'wikidata'],
|
||||
type: 'wikipedia'
|
||||
});
|
||||
server = createServer({ respondImmediately: true });
|
||||
fetchMock.reset();
|
||||
fetchMock.mock(new RegExp('\/w\/api\.php.*action=wbgetentities'), {
|
||||
body: '{"entities":{"Q216353":{"id":"Q216353"}}}',
|
||||
status: 200,
|
||||
headers: { 'Content-Type': 'application/json' }
|
||||
});
|
||||
});
|
||||
|
||||
afterEach(function() {
|
||||
server.restore();
|
||||
fetchMock.reset();
|
||||
});
|
||||
|
||||
|
||||
@@ -55,19 +60,6 @@ describe('iD.uiFieldWikipedia', function() {
|
||||
}
|
||||
}
|
||||
|
||||
function createServer(options) { // eslint-disable-line no-unused-vars
|
||||
// note - currently skipping the tests that use `options` to delay responses
|
||||
// var server = sinon.fakeServer.create(options);
|
||||
var server = window.fakeFetch().create();
|
||||
server.respondWith('GET',
|
||||
new RegExp('\/w\/api\.php.*action=wbgetentities'),
|
||||
[200, { 'Content-Type': 'application/json' },
|
||||
'{"entities":{"Q216353":{"id":"Q216353"}}}']
|
||||
);
|
||||
return server;
|
||||
}
|
||||
|
||||
|
||||
it('recognizes lang:title format', function(done) {
|
||||
var wikipedia = iD.uiFieldWikipedia(field, context);
|
||||
window.setTimeout(function() { // async, so data will be available
|
||||
@@ -121,6 +113,7 @@ describe('iD.uiFieldWikipedia', function() {
|
||||
}, 20);
|
||||
});
|
||||
|
||||
// note - currently skipping the tests that use `options` to delay responses
|
||||
it('preserves existing language', function(done) {
|
||||
var wikipedia1 = iD.uiFieldWikipedia(field, context);
|
||||
window.setTimeout(function() { // async, so data will be available
|
||||
@@ -146,7 +139,14 @@ describe('iD.uiFieldWikipedia', function() {
|
||||
wikipedia.on('change.spy', spy);
|
||||
|
||||
// Create an XHR server that will respond after 60ms
|
||||
createServer({ autoRespond: true, autoRespondAfter: 60 });
|
||||
fetchMock.reset();
|
||||
fetchMock.mock(new RegExp('\/w\/api\.php.*action=wbgetentities'), {
|
||||
body: '{"entities":{"Q216353":{"id":"Q216353"}}}',
|
||||
status: 200,
|
||||
headers: { 'Content-Type': 'application/json' }
|
||||
}, {
|
||||
delay: 60
|
||||
});
|
||||
|
||||
// Set title to "Skip"
|
||||
iD.utilGetSetValue(selection.selectAll('.wiki-lang'), 'Deutsch');
|
||||
@@ -159,7 +159,14 @@ describe('iD.uiFieldWikipedia', function() {
|
||||
|
||||
// Create a new XHR server that will respond after 60ms to
|
||||
// separate requests after this point from those before
|
||||
createServer({ autoRespond: true, autoRespondAfter: 60 });
|
||||
fetchMock.reset();
|
||||
fetchMock.mock(new RegExp('\/w\/api\.php.*action=wbgetentities'), {
|
||||
body: '{"entities":{"Q216353":{"id":"Q216353"}}}',
|
||||
status: 200,
|
||||
headers: { 'Content-Type': 'application/json' }
|
||||
}, {
|
||||
delay: 60
|
||||
});
|
||||
|
||||
// t30: graph change - Set title to "Title"
|
||||
window.setTimeout(function() {
|
||||
|
||||
@@ -78,7 +78,7 @@ describe('iD.util', function() {
|
||||
expect(iD.utilTagText({tags:{foo:'bar',two:'three'}})).to.eql('foo=bar, two=three');
|
||||
});
|
||||
|
||||
it('utilStringQs', function() {
|
||||
describe('utilStringQs', function() {
|
||||
it('splits a parameter string into k=v pairs', function() {
|
||||
expect(iD.utilStringQs('foo=bar')).to.eql({foo: 'bar'});
|
||||
expect(iD.utilStringQs('foo=bar&one=2')).to.eql({foo: 'bar', one: '2' });
|
||||
|
||||
Reference in New Issue
Block a user