From b9888e45e46148a0334081e62ed3c1a21072cb82 Mon Sep 17 00:00:00 2001 From: Bryan Housel Date: Sat, 3 Dec 2016 19:22:06 -0500 Subject: [PATCH] Add imageryBlacklists function to get blacklists from OSM API (for #3623) --- modules/services/osm.js | 36 +++++++++++++++++++++++++- test/spec/services/osm.js | 54 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 89 insertions(+), 1 deletion(-) diff --git a/modules/services/osm.js b/modules/services/osm.js index e55f29a91..aaa2162ad 100644 --- a/modules/services/osm.js +++ b/modules/services/osm.js @@ -25,6 +25,7 @@ var dispatch = d3.dispatch('authLoading', 'authDone', 'change', 'loading', 'load }), rateLimitError, userDetails, + capabilities, off; @@ -161,6 +162,7 @@ export default { reset: function() { userDetails = undefined; rateLimitError = undefined; + capabilities = undefined; _.forEach(inflight, abortRequest); loadedTiles = {}; inflight = {}; @@ -429,22 +431,54 @@ export default { }, + // `status` will always request the `api/capabilities` resource.. status: function(callback) { - function done(capabilities) { + function done(xml) { + capabilities = xml; + if (rateLimitError) { callback(rateLimitError, 'rateLimited'); } else { var apiStatus = capabilities.getElementsByTagName('status'), val = apiStatus[0].getAttribute('api'); + callback(undefined, val); } } + d3.xml(urlroot + '/api/capabilities').get() .on('load', done) .on('error', callback); }, + // `imageryBlacklists` will reuse the previous `api/capabilities` result, if available.. + imageryBlacklists: function(callback) { + function done(xml) { + capabilities = xml; + + var elements = capabilities.getElementsByTagName('blacklist'), + blacklists = []; + for (var i = 0; i < elements.length; i++) { + var regex = elements[i].getAttribute('regex'); // needs unencode? + if (regex) { + blacklists.push(regex); + } + } + + callback(undefined, blacklists); + } + + if (capabilities) { + done(capabilities); + } else { + d3.xml(urlroot + '/api/capabilities').get() + .on('load', done) + .on('error', callback); + } + }, + + tileZoom: function(_) { if (!arguments.length) return tileZoom; tileZoom = _; diff --git a/test/spec/services/osm.js b/test/spec/services/osm.js index fce8e6d68..bd5d75fb9 100644 --- a/test/spec/services/osm.js +++ b/test/spec/services/osm.js @@ -445,4 +445,58 @@ describe('iD.serviceOsm', function () { expect(connection.changesetTags('2.0.0', '', [])).not.to.have.property('comment'); }); }); + + describe('API capabilities', function() { + var server, + capabilitiesXML = '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + ''; + + + beforeEach(function() { + server = sinon.fakeServer.create(); + // connection.reset(); + }); + + 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('gets imagery blacklists', function(done) { + connection.imageryBlacklists(function(err, val) { + expect(val).to.eql(['.*\.google(apis)?\..*/(vt|kh)[\?/].*([xyz]=.*){3}.*']); + done(); + }); + + server.respondWith('GET', 'http://www.openstreetmap.org/api/capabilities', + [200, { 'Content-Type': 'text/xml' }, capabilitiesXML]); + server.respond(); + }); + }); + + }); + });