UNPKG

@yaga/indexed-db-tile-cache

Version:

Spatial tile cache that saves its data into the IndexedDB of your browser

208 lines (199 loc) 10.2 kB
import { Buffer } from "buffer"; import { expect } from "chai"; import { IIndexedDbTileCacheEntry, IIndexedDbTileCacheSeedProgress, IndexedDbTileCache } from "./index"; describe("IndexedDbTileCache", () => { it("should create a store", () => { expect(new IndexedDbTileCache()).to.instanceof(IndexedDbTileCache); }); it("should purge the store", (done: MochaDone) => { new IndexedDbTileCache().purgeStore().then(() => { done(); }, done); }); it("should fulfill the default values", () => { const tileCache = new IndexedDbTileCache(); expect(tileCache.options.databaseName).to.equal("tile-cache-data"); expect(tileCache.options.databaseVersion).to.equal(1); expect(tileCache.options.objectStoreName).to.equal("OSM"); expect(tileCache.options.tileUrl).to.equal("http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"); expect(tileCache.options.tileUrlSubDomains).to.deep.equal(["a", "b", "c"]); expect(tileCache.options.crawlDelay).to.equal(500); expect(tileCache.options.maxAge).to.equal(1000 * 60 * 60 * 24 * 7); }); describe(".downloadTile", () => { it("should download a tile", (done: MochaDone) => { const tileCache = new IndexedDbTileCache(); tileCache.downloadTile({x: 0, y: 0, z: 0}).then((value: IIndexedDbTileCacheEntry) => { expect(value).to.has.property("contentType"); expect(value).to.has.property("data"); expect(value).to.has.property("url"); expect(value).to.has.property("timestamp"); expect(value.contentType).to.equal("image/png"); expect(value.data).to.be.instanceOf(Uint8Array); expect(value.url).to.equal("http://{s}.tile.openstreetmap.org/0/0/0.png"); expect(value.timestamp).to.be.a("number"); done(); }, done); }); it("should have stored the before downloaded tile", (done: MochaDone) => { const dbRequest: IDBOpenDBRequest = indexedDB.open("tile-cache-data", 1); dbRequest.addEventListener("success", (dbEvent: any) => { const database: IDBDatabase = dbEvent.target.result; const tx = database.transaction(["OSM"]) .objectStore("OSM").get("http://{s}.tile.openstreetmap.org/0/0/0.png"); tx.addEventListener("success", (event: any) => { expect(event.target.result).to.has.property("data"); expect(event.target.result.data).to.be.instanceOf(Uint8Array); done(); }); }); }); }); describe(".getTileEntry", () => { it("should get the before downloaded tile", (done: MochaDone) => { const tileCache = new IndexedDbTileCache(); tileCache.getTileEntry({x: 0 , y: 0, z: 0}).then((tile: IIndexedDbTileCacheEntry) => { expect(tile.url).to.equal("http://{s}.tile.openstreetmap.org/0/0/0.png"); done(); }, done); }); it("should not get a new tile without the download flag", (done: MochaDone) => { const tileCache = new IndexedDbTileCache(); tileCache.getTileEntry({x: 0 , y: 0, z: 1}) .then(/* istanbul ignore next */(/* tile: IIndexedDbTileCacheEntry */) => { done(new Error("Received a tile")); }, (err) => { expect(err.message).to.equal("Unable to find entry"); done(); }); }); it("should get a new tile with the download flag", (done: MochaDone) => { const tileCache = new IndexedDbTileCache(); tileCache.getTileEntry({x: 0 , y: 0, z: 2}, true).then((tile: IIndexedDbTileCacheEntry) => { expect(tile.url).to.equal("http://{s}.tile.openstreetmap.org/2/0/0.png"); done(); }, done); }); it("should re-download an outdated tile", (done: MochaDone) => { const dbRequest: IDBOpenDBRequest = indexedDB.open("tile-cache-data", 1); dbRequest.addEventListener("success", (dbEvent: any) => { const database: IDBDatabase = dbEvent.target.result; const tx = database.transaction(["OSM"], "readwrite") .objectStore("OSM").put({ contentType: "wrong/one", data: new Uint8Array(0), timestamp: 123, url: "http://{s}.tile.openstreetmap.org/0/0/0.png", } as IIndexedDbTileCacheEntry); tx.addEventListener("success", () => { const tileCache = new IndexedDbTileCache(); tileCache.getTileEntry({x: 0 , y: 0, z: 0}, true).then((tile: IIndexedDbTileCacheEntry) => { expect(tile.contentType).to.not.equal("wrong/one"); expect(tile.contentType).to.equal("image/png"); expect(tile.timestamp).to.be.not.equal(123); done(); }, done); }); }); }); }); describe(".createInternalTileUrl", () => { it("should get an url that still have the sub domain as placeholder", () => { const tileCache = new IndexedDbTileCache(); expect(tileCache.createInternalTileUrl({x: 1 , y: 2, z: 3})) .to.equal("http://{s}.tile.openstreetmap.org/3/1/2.png"); }); }); describe(".createTileUrl", () => { it("should get an url without any placeholder", () => { const tileCache = new IndexedDbTileCache(); expect(tileCache.createTileUrl({x: 1 , y: 2, z: 3})) .to.be.oneOf([ "http://a.tile.openstreetmap.org/3/1/2.png", "http://b.tile.openstreetmap.org/3/1/2.png", "http://c.tile.openstreetmap.org/3/1/2.png", ]); }); }); describe(".getTileAsBuffer", () => { it("should get the already fetched tile as Buffer and Uint8Array", (done: MochaDone) => { const tileCache = new IndexedDbTileCache(); tileCache.getTileAsBuffer({x: 0, y: 0, z: 0}).then((buffer) => { expect(buffer).to.be.instanceOf(Buffer); expect(buffer).to.be.instanceOf(Uint8Array); done(); }, done); }); it("should get a tile that was not fetched before as Buffer and Uint8Array", (done: MochaDone) => { const tileCache = new IndexedDbTileCache(); tileCache.getTileAsBuffer({x: 10, y: 10, z: 10}).then((buffer) => { expect(buffer).to.be.instanceOf(Buffer); expect(buffer).to.be.instanceOf(Uint8Array); done(); }, done); }); }); describe(".getTileAsDataUrl", () => { it("should get the already fetched tile as data-url", (done: MochaDone) => { const tileCache = new IndexedDbTileCache(); tileCache.getTileAsDataUrl({x: 0, y: 0, z: 0}).then((url: string) => { expect(url).to.be.a("string"); expect(url.substr(0, 22)).to.equal("data:image/png;base64,"); expect(url.length).to.be.greaterThan(100); done(); }, done); }); it("should get a tile that was not fetched before as Buffer and Uint8Array", (done: MochaDone) => { const tileCache = new IndexedDbTileCache(); tileCache.getTileAsDataUrl({x: 20, y: 20, z: 10}).then((url: string) => { expect(url).to.be.a("string"); expect(url.substr(0, 22)).to.equal("data:image/png;base64,"); expect(url.length).to.be.greaterThan(100); done(); }, done); }); }); describe(".seedBBox", () => { it("should seed a bounding-box", (done: MochaDone) => { const tileCache = new IndexedDbTileCache(); tileCache.seedBBox({maxLat: 0, maxLng: 0, minLat: 0, minLng: 0}, 0).then(() => { done(); }, done); }); it("should emit 'seed-progress' while seeding", (done: MochaDone) => { const tileCache = new IndexedDbTileCache(); let expectedEmits: number = 2; tileCache.on("seed-progress", (progress: IIndexedDbTileCacheSeedProgress) => { expect(progress).to.has.property("remains"); expect(progress).to.has.property("total"); expect(progress.total).to.equal(1); expectedEmits -= 1; if (expectedEmits === 0) { return done(); } }); tileCache.seedBBox({maxLat: 0, maxLng: 0, minLat: 0, minLng: 0}, 0).catch(done); }); }); describe(".purgeStore", () => { it("should purge the whole store", (done: MochaDone) => { new IndexedDbTileCache().purgeStore().then(() => { const dbRequest: IDBOpenDBRequest = indexedDB.open("tile-cache-data", 1); dbRequest.addEventListener("success", (dbEvent: any) => { const database: IDBDatabase = dbEvent.target.result; const tx = database.transaction(["OSM"]) .objectStore("OSM").get("http://{s}.tile.openstreetmap.org/0/0/0.png"); tx.addEventListener("success", (event: any) => { /* istanbul ignore else */ if (event.target.result === undefined) { return done(); } /* istanbul ignore next */ done(new Error("Found removed store")); }); tx.addEventListener("error", /* istanbul ignore next */() => { done(); }); }); }, done); }); }); });