diff --git a/.gitmodules b/.gitmodules index 9059e8a..7d99113 100644 --- a/.gitmodules +++ b/.gitmodules @@ -7,3 +7,6 @@ [submodule "vendor/IndexedDBShim"] path = vendor/IndexedDBShim url = https://github.com/axemclion/IndexedDBShim +[submodule "vendor/jasmine.async"] + path = vendor/jasmine.async + url = https://github.com/derickbailey/jasmine.async.git diff --git a/test/jasmine/SpecRunner.html b/test/jasmine/SpecRunner.html index 25d3261..ea45da3 100755 --- a/test/jasmine/SpecRunner.html +++ b/test/jasmine/SpecRunner.html @@ -4,10 +4,10 @@ Jasmine Spec Runner - - - - + + + + diff --git a/test/jasmine/SpecRunner.tiles.html b/test/jasmine/SpecRunner.tiles.html new file mode 100755 index 0000000..bdb7fd7 --- /dev/null +++ b/test/jasmine/SpecRunner.tiles.html @@ -0,0 +1,95 @@ + + + + Jasmine Spec Runner - Tiles + + + + + + + + + + + + + + + + + + + + +
+ + + diff --git a/test/jasmine/spec/offlineEnablerSpec.js b/test/jasmine/spec/offlineEnablerSpec.js new file mode 100644 index 0000000..e1995e1 --- /dev/null +++ b/test/jasmine/spec/offlineEnablerSpec.js @@ -0,0 +1,155 @@ +"use strict" + +describe("offline enabler library", function() +{ + var async = new AsyncSpec(this); + + async.it("validate map", function(done) + { + expect(g_map).toEqual(jasmine.any(Object)); + expect(g_map.id).toEqual("map"); + done(); + }); + + async.it("validate tiled layer", function(done) + { + expect(g_basemapLayer).toEqual(jasmine.any(Object)); + expect(g_basemapLayer.tileInfo).toEqual(jasmine.any(Object)); + done(); + }); + + async.it("extends the tiled layer object", function(done) + { + expect(g_basemapLayer.goOffline).toBeUndefined(); + g_offlineEnabler.extend(g_basemapLayer,function(success) + { + expect(success).toEqual(true); + expect(g_basemapLayer.goOffline).toEqual(jasmine.any(Function)); + expect(g_basemapLayer.goOnline).toEqual(jasmine.any(Function)); + expect(g_basemapLayer.getTileUrl).toEqual(jasmine.any(Function)); + expect(g_basemapLayer._getTileUrl).toEqual(jasmine.any(Function)); + expect(g_basemapLayer.prepareForOffline).toEqual(jasmine.any(Function)); + expect(g_basemapLayer.storeTile).toEqual(jasmine.any(Function)); + expect(g_basemapLayer.deleteAllTiles).toEqual(jasmine.any(Function)); + expect(g_basemapLayer.offline).toEqual(jasmine.any(Object)); + expect(g_basemapLayer.offline.store).toEqual(jasmine.any(Object)); + + g_basemapLayer.offline.proxyPath = "../../tiles/proxy.php"; + done(); + }); + }); + + async.it("can go offline", function(done) + { + expect(g_basemapLayer.goOffline).toEqual(jasmine.any(Function)); + expect(g_basemapLayer.offline.online).toEqual(true); + g_basemapLayer.goOffline(); + expect(g_basemapLayer.offline.online).toEqual(false); + done(); + }); + + async.it("can go online", function(done) + { + expect(g_basemapLayer.goOffline).toEqual(jasmine.any(Function)); + expect(g_basemapLayer.offline.online).toEqual(false); + g_basemapLayer.goOnline(); + expect(g_basemapLayer.offline.online).toEqual(true); + done(); + }) + + async.it("delete all tiles", function(done) + { + g_basemapLayer.deleteAllTiles(function(success) + { + expect(success).toEqual(true); + setTimeout(function() + { + g_basemapLayer.getOfflineUsage(function(usage) + { + expect(usage.tileCount).toEqual(0); + done(); + }); + },1); + }); + }); + + async.it("stores one tile", function(done) + { + g_basemapLayer.getOfflineUsage(function(usage) + { + expect(usage.tileCount).toEqual(0); + g_basemapLayer.storeTile(14,6177,8023, function(success) + { + expect(success).toEqual(true); + g_basemapLayer.getOfflineUsage(function(usage) + { + expect(usage.tileCount).toEqual(1); + done(); + }); + }); + }); + }); + + async.it("gets level estimation", function(done) + { + require(["esri/geometry/Extent"],function(Extent) + { + var extent = new Extent({"xmin":-822542.2830377579,"ymin":4580841.761960262,"xmax":94702.05638410954,"ymax":5131188.365613382,"spatialReference":{"wkid":102100}}); + var tileSize = g_basemapLayer.estimateTileSize(); + var estimation = g_basemapLayer.getLevelEstimation(extent,10); + expect(estimation.tileCount).toEqual(375); + expect(estimation.sizeBytes).toEqual(estimation.tileCount * tileSize); + var estimation = g_basemapLayer.getLevelEstimation(extent,8); + expect(estimation.tileCount).toEqual(28); + expect(estimation.sizeBytes).toEqual(estimation.tileCount * tileSize); + var estimation = g_basemapLayer.getLevelEstimation(extent,2); + expect(estimation.tileCount).toEqual(2); + expect(estimation.sizeBytes).toEqual(estimation.tileCount * tileSize); + done(); + }); + }); + + async.it("prepares the layer for offline usage", function(done) + { + require(["esri/geometry/Extent"], function(Extent) + { + g_basemapLayer.deleteAllTiles(function(success) + { + var extent = new Extent({"xmin":-822542.2830377579,"ymin":4580841.761960262,"xmax":94702.05638410954,"ymax":5131188.365613382,"spatialReference":{"wkid":102100}}); + var reportProgress = jasmine.createSpy(); + var finishedDownloading = function(err) + { + expect(err).not.toBeTruthy(); + expect(reportProgress).toHaveBeenCalled(); + expect(reportProgress.callCount).toEqual(28); + + g_basemapLayer.getOfflineUsage(function(usage) + { + expect(usage.tileCount).toEqual(28); + done(); + }); + } + + g_basemapLayer.prepareForOffline(8,8,extent,reportProgress, finishedDownloading); + }); + }); + }); + + async.it("returns placeholder urls when offline", function(done) + { + require(["dojo/dom"], function(dom) + { + var fakeTile = dom.byId('fakeTile'); + + g_basemapLayer.goOnline(); + var onlineUrl = g_basemapLayer.getTileUrl(14,6178,8023); + expect(onlineUrl).toEqual('http://services.arcgisonline.com/ArcGIS/rest/services/Canvas/World_Light_Gray_Base/MapServer/tile/14/6178/8023'); + + g_basemapLayer.goOffline(); + var offlineUrl = fakeTile.src = g_basemapLayer.getTileUrl(14,6178,8023); + expect(offlineUrl).toEqual('void:14-6178-8023'); + done(); + }) + }); + +}); \ No newline at end of file diff --git a/tiles/ISSUES.md b/tiles/ISSUES.md index dece3ba..f846bb6 100644 --- a/tiles/ISSUES.md +++ b/tiles/ISSUES.md @@ -16,9 +16,12 @@ + better dependency management - [x] remove unused files (ioWorker, OfflineTileStore) - [x] test iPad/iPhone **DONE**, it works! +- [x] unit testing -- [ ] unit testing +- [ ] update README.md - [ ] better tile estimation and limits +- [ ] keep on downloading tiles even if one of them fails +- [ ] add message telling that something failed while initing the indexedDB - [ ] allow naming caches? - [ ] more general proxy.php diff --git a/tiles/index.html b/tiles/index.html index b700e59..4e06bd7 100644 --- a/tiles/index.html +++ b/tiles/index.html @@ -56,6 +56,7 @@

Map:[none]

+

[none]

@@ -134,6 +135,13 @@ + + + diff --git a/tiles/main.js b/tiles/main.js index 3c9ba65..286d85a 100644 --- a/tiles/main.js +++ b/tiles/main.js @@ -12,7 +12,7 @@ require(["esri/map", "dojo/dom", "dojo/on", "dojo/query", "../vendor/bootstrap-map-js/src/js/bootstrapmap.js", "esri/urlUtils", "esri/geometry/webMercatorUtils", - "/offline/tiles/src/offlineEnabler.js", + "tiles/offlineEnabler", "dojo/dom-construct", "dojo/domReady!"], function(Map, GraphicsLayer, Graphic, SimpleFillSymbol, @@ -36,8 +36,7 @@ require(["esri/map", function loadWebmap(webmapid) { - //webmapid = webmapid || "1d2a47c27ffc433fa4a278841544f427"; //for testing only - webmapid = webmapid || "f58996878ac24702afef792e52a07e55"; + webmapid = webmapid || "bbc1a04a3eca4430be144d7a08b43a17"; // Get new webmap and extract map and map parts var mapDeferred = esriUtils.createMap(webmapid, "mapDiv", { mapOptions: { @@ -54,8 +53,9 @@ require(["esri/map", // Bind to map BootstrapMap.bindTo(map); - // Add title + // Add title and description dom.byId("mapTitle").innerHTML = response.itemInfo.item.title; + dom.byId("mapDescription").innerHTML = response.itemInfo.item.snippet; if(map.loaded) { @@ -136,6 +136,11 @@ require(["esri/map", else { dojo.byId('prepare-for-offline-btn').disabled = true; + dojo.byId('delete-all-tiles-btn').disabled = true; + dojo.byId('go-offline-btn').disabled = true; + dojo.byId('go-online-btn').disabled = true; + dojo.byId('update-offline-usage').disabled = true; + dojo.byId('show-stored-tiles').disabled = true; esri.hide(dojo.byId('downloading-ui')); /* JAMI: TODO add message telling that something failed while initing the indexedDB */ } diff --git a/tiles/proxy.php b/tiles/proxy.php index 3ebc95b..45c05b9 100755 --- a/tiles/proxy.php +++ b/tiles/proxy.php @@ -42,9 +42,10 @@ array( 'url' => 'http://tiles4.arcgis.com/tiles/', 'matchAll' => true, 'token' => '' ), array( 'url' => 'http://www.mapabase.es/ArcGIS/', 'matchAll' => true, 'token' => '' ), array( 'url' => 'http://server.arcgisonline.com/ArcGIS/rest/services/', 'matchAll' => true, 'token' => '' ), - array( 'url' => 'http://sampleserver1.arcgisonline.com/ArcGIS/rest/services/', 'matchAll' => true, 'token' => '' ), array( 'url' => 'http://services.arcgisonline.com/ArcGIS/rest/services/', 'matchAll' => true, 'token' => '' ), + array( 'url' => 'http://sampleserver1.arcgisonline.com/ArcGIS/rest/services/', 'matchAll' => true, 'token' => '' ), array( 'url' => 'http://sampleserver2.arcgisonline.com/ArcGIS/rest/services/', 'matchAll' => true, 'token' => '' ), + array( 'url' => 'http://sampleserver5.arcgisonline.com/ArcGIS/rest/services/', 'matchAll' => true, 'token' => '' ), array( 'url' => 'http://sampleserver1a.arcgisonline.com/arcgisoutput/', 'matchAll' => true, 'token' => '' ), array( 'url' => 'http://sampleserver1b.arcgisonline.com/arcgisoutput/', 'matchAll' => true, 'token' => '' ), array( 'url' => 'http://sampleserver1c.arcgisonline.com/arcgisoutput/', 'matchAll' => true, 'token' => '' ) diff --git a/tiles/src/Blob.js b/tiles/tiles/Blob.js similarity index 100% rename from tiles/src/Blob.js rename to tiles/tiles/Blob.js diff --git a/tiles/src/FileSaver.js b/tiles/tiles/FileSaver.js similarity index 100% rename from tiles/src/FileSaver.js rename to tiles/tiles/FileSaver.js diff --git a/tiles/src/base64utils.js b/tiles/tiles/base64utils.js similarity index 100% rename from tiles/src/base64utils.js rename to tiles/tiles/base64utils.js diff --git a/tiles/src/dbStore.js b/tiles/tiles/dbStore.js similarity index 97% rename from tiles/src/dbStore.js rename to tiles/tiles/dbStore.js index 2217d6d..9606eff 100644 --- a/tiles/src/dbStore.js +++ b/tiles/tiles/dbStore.js @@ -6,7 +6,7 @@ * Author: Andy Gup (@agup) * Contributor: Javier Abadia (@javierabadia) */ -define(["/offline/tiles/src/phoneGapConnector.js"],function(phonegap) +define(["tiles/phoneGapConnector"],function(phonegap) { var DbStore = function() { @@ -37,7 +37,6 @@ define(["/offline/tiles/src/phoneGapConnector.js"],function(phonegap) * @returns {boolean} */ this.isSupported = function(){ - window.indexedDB = window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB; if(!window.indexedDB){ return false; diff --git a/tiles/src/offlineEnabler.js b/tiles/tiles/offlineEnabler.js similarity index 96% rename from tiles/src/offlineEnabler.js rename to tiles/tiles/offlineEnabler.js index 83960cf..0fe87a2 100644 --- a/tiles/src/offlineEnabler.js +++ b/tiles/tiles/offlineEnabler.js @@ -3,9 +3,9 @@ define([ "dojo/query", "esri/geometry", - "/offline//tiles/src/base64utils.js", - "/offline/tiles/src/dbStore.js", - "/offline/tiles/src/tilingScheme.js" + "tiles/base64utils", + "tiles/dbStore", + "tiles/tilingScheme" ], function(query, geometry,Base64Utils,DbStore,TilingScheme) { return { @@ -34,10 +34,11 @@ define([ layer._getTileUrl = layer.getTileUrl; layer.offline = { online: true, - store: new DbStore() + store: new DbStore(), + proxyPath: "proxy.php" }; - if( layer.offline.store.isSupported() ) + if( /*false &&*/ layer.offline.store.isSupported() ) layer.offline.store.init(callback); else return callback(false, "indexedDB not supported"); @@ -178,7 +179,7 @@ define([ url = url.split('?')[0]; /* download the tile */ - var imgurl = "../tiles/proxy.php?" + url; + var imgurl = this.offline.proxyPath + "?" + url; var req = new XMLHttpRequest(); req.open("GET", imgurl, true); req.overrideMimeType("text/plain; charset=x-user-defined"); // https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/Using_XMLHttpRequest?redirectlocale=en-US&redirectslug=DOM%2FXMLHttpRequest%2FUsing_XMLHttpRequest#Handling_binary_data diff --git a/tiles/src/phoneGapConnector.js b/tiles/tiles/phoneGapConnector.js similarity index 100% rename from tiles/src/phoneGapConnector.js rename to tiles/tiles/phoneGapConnector.js diff --git a/tiles/src/tilingScheme.js b/tiles/tiles/tilingScheme.js similarity index 100% rename from tiles/src/tilingScheme.js rename to tiles/tiles/tilingScheme.js diff --git a/test/jasmine/lib/jasmine-1.3.1/MIT.LICENSE b/vendor/jasmine-1.3.1/MIT.LICENSE similarity index 100% rename from test/jasmine/lib/jasmine-1.3.1/MIT.LICENSE rename to vendor/jasmine-1.3.1/MIT.LICENSE diff --git a/test/jasmine/lib/jasmine-1.3.1/jasmine-html.js b/vendor/jasmine-1.3.1/jasmine-html.js similarity index 100% rename from test/jasmine/lib/jasmine-1.3.1/jasmine-html.js rename to vendor/jasmine-1.3.1/jasmine-html.js diff --git a/test/jasmine/lib/jasmine-1.3.1/jasmine.css b/vendor/jasmine-1.3.1/jasmine.css similarity index 100% rename from test/jasmine/lib/jasmine-1.3.1/jasmine.css rename to vendor/jasmine-1.3.1/jasmine.css diff --git a/test/jasmine/lib/jasmine-1.3.1/jasmine.js b/vendor/jasmine-1.3.1/jasmine.js similarity index 100% rename from test/jasmine/lib/jasmine-1.3.1/jasmine.js rename to vendor/jasmine-1.3.1/jasmine.js diff --git a/vendor/jasmine.async b/vendor/jasmine.async new file mode 160000 index 0000000..f6f159d --- /dev/null +++ b/vendor/jasmine.async @@ -0,0 +1 @@ +Subproject commit f6f159d49415442b7bdff06c912e53ed4320bb94