diff --git a/examples/offscreen-canvas.worker.js b/examples/offscreen-canvas.worker.js index b375ad9632..91fad6f627 100644 --- a/examples/offscreen-canvas.worker.js +++ b/examples/offscreen-canvas.worker.js @@ -5,9 +5,9 @@ import TileQueue, { import VectorTileLayer from '../src/ol/layer/VectorTile.js'; import VectorTileSource from '../src/ol/source/VectorTile.js'; import stringify from 'json-stringify-safe'; -import styleFunction from 'ol-mapbox-style/dist/stylefunction.js'; import {get} from '../src/ol/proj.js'; import {inView} from '../src/ol/layer/Layer.js'; +import {stylefunction} from 'ol-mapbox-style'; /** @type {any} */ const worker = self; @@ -95,7 +95,7 @@ function loadStyles() { }; rendererTransform = transform; }; - styleFunction( + stylefunction( layer, styleJson, bucket.layers, diff --git a/examples/vector-tiles-4326.js b/examples/vector-tiles-4326.js index d527140ea9..801a657a67 100644 --- a/examples/vector-tiles-4326.js +++ b/examples/vector-tiles-4326.js @@ -1,55 +1,36 @@ -import MVT from '../src/ol/format/MVT.js'; -import TileGrid from '../src/ol/tilegrid/TileGrid.js'; +import VectorTileLayer from '../src/ol/layer/VectorTile.js'; import VectorTileSource from '../src/ol/source/VectorTile.js'; -import View from '../src/ol/View.js'; - -import olms from 'ol-mapbox-style'; -import {defaultResolutions} from 'ol-mapbox-style/dist/util.js'; +import {Map, View} from '../src/ol/index.js'; +import {applyBackground, applyStyle} from 'ol-mapbox-style'; +import {createXYZ} from '../src/ol/tilegrid.js'; const key = 'get_your_own_D6rA4zTHduk6KOKTXzGB'; +const url = 'https://api.maptiler.com/maps/basic-4326/style.json?key=' + key; // Match the server resolutions -const maxResolution = 360 / 512; -defaultResolutions.length = 14; -for (let i = 0; i < 14; ++i) { - defaultResolutions[i] = maxResolution / Math.pow(2, i + 1); -} - -olms( - 'map', - 'https://api.maptiler.com/maps/basic-4326/style.json?key=' + key -).then(function (map) { - // Custom tile grid for the EPSG:4326 projection - const tileGrid = new TileGrid({ - extent: [-180, -90, 180, 90], - tileSize: 512, - resolutions: defaultResolutions, - }); - - const mapboxStyle = map.get('mapbox-style'); - - // Replace the source with a EPSG:4326 projection source for each vector tile layer - map.getLayers().forEach(function (layer) { - const mapboxSource = layer.get('mapbox-source'); - if (mapboxSource && mapboxStyle.sources[mapboxSource].type === 'vector') { - const source = layer.getSource(); - layer.setSource( - new VectorTileSource({ - format: new MVT(), - projection: 'EPSG:4326', - urls: source.getUrls(), - tileGrid: tileGrid, - }) - ); - } - }); - - // Configure the map with a view with EPSG:4326 projection - map.setView( - new View({ - projection: 'EPSG:4326', - zoom: mapboxStyle.zoom, - center: mapboxStyle.center, - }) - ); +const tileGrid = createXYZ({ + extent: [-180, -90, 180, 90], + tileSize: 512, + maxResolution: 180 / 512, + maxZoom: 13, +}); + +const layer = new VectorTileLayer({ + declutter: true, + source: new VectorTileSource({ + projection: 'EPSG:4326', + tileGrid: tileGrid, + }), +}); +applyStyle(layer, url, '', {resolutions: tileGrid.getResolutions()}); +applyBackground(layer, url); + +const map = new Map({ + target: 'map', + layers: [layer], + view: new View({ + projection: 'EPSG:4326', + zoom: 0, + center: [0, 30], + }), }); diff --git a/package-lock.json b/package-lock.json index cf79d716c1..3dfbc6e5fd 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,7 +10,7 @@ "license": "BSD-2-Clause", "dependencies": { "geotiff": "^2.0.2", - "ol-mapbox-style": "^7.1.1", + "ol-mapbox-style": "^8.0.4", "pbf": "3.2.1", "rbush": "^3.0.1" }, @@ -1785,9 +1785,9 @@ } }, "node_modules/@mapbox/mapbox-gl-style-spec": { - "version": "13.20.1", - "resolved": "https://registry.npmjs.org/@mapbox/mapbox-gl-style-spec/-/mapbox-gl-style-spec-13.20.1.tgz", - "integrity": "sha512-xVCJ3IbKoPwcPrxxtGAxUqHEVxXi1hnJtLIFqgkuZfnzj0KeRbk3dZlDr/KNo1/doJjIoFgPFUO/HMOT+wXGPA==", + "version": "13.24.0", + "resolved": "https://registry.npmjs.org/@mapbox/mapbox-gl-style-spec/-/mapbox-gl-style-spec-13.24.0.tgz", + "integrity": "sha512-9yhRSqnKX+59MrG647x2pACfR2Ewk8Ii5X75Ag8oToEKZU+PSY0+r10EirIVCTDwuHPzp/VuuN3j6n+Hv/gGpQ==", "dependencies": { "@mapbox/jsonlint-lines-primitives": "~2.0.2", "@mapbox/point-geometry": "^0.1.0", @@ -1799,10 +1799,10 @@ "sort-object": "^0.3.2" }, "bin": { - "gl-style-composite": "bin/gl-style-composite", - "gl-style-format": "bin/gl-style-format", - "gl-style-migrate": "bin/gl-style-migrate", - "gl-style-validate": "bin/gl-style-validate" + "gl-style-composite": "bin/gl-style-composite.js", + "gl-style-format": "bin/gl-style-format.js", + "gl-style-migrate": "bin/gl-style-migrate.js", + "gl-style-validate": "bin/gl-style-validate.js" } }, "node_modules/@mapbox/point-geometry": { @@ -7451,11 +7451,11 @@ "dev": true }, "node_modules/ol-mapbox-style": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/ol-mapbox-style/-/ol-mapbox-style-7.1.1.tgz", - "integrity": "sha512-GLTEYiH/Ec9Zn1eS4S/zXyR2sierVrUc+OLVP8Ra0FRyqRhoYbXdko0b7OIeSHWdtJfHssWYefDOGxfTRUUZ/A==", + "version": "8.0.4", + "resolved": "https://registry.npmjs.org/ol-mapbox-style/-/ol-mapbox-style-8.0.4.tgz", + "integrity": "sha512-Tvjy3reugxZ1CO+PzngdbCwBgEBfHJI7gBTk0RUhj6o01OZKbjr+9obqPav22TLhQB4f/8w+RPUF/M8+bnqtiQ==", "dependencies": { - "@mapbox/mapbox-gl-style-spec": "^13.20.1", + "@mapbox/mapbox-gl-style-spec": "^13.23.1", "mapbox-to-css-font": "^2.4.1", "webfont-matcher": "^1.1.0" } @@ -11802,9 +11802,9 @@ "integrity": "sha1-zlblOfg1UrWNENZy6k1vya3HsjQ=" }, "@mapbox/mapbox-gl-style-spec": { - "version": "13.20.1", - "resolved": "https://registry.npmjs.org/@mapbox/mapbox-gl-style-spec/-/mapbox-gl-style-spec-13.20.1.tgz", - "integrity": "sha512-xVCJ3IbKoPwcPrxxtGAxUqHEVxXi1hnJtLIFqgkuZfnzj0KeRbk3dZlDr/KNo1/doJjIoFgPFUO/HMOT+wXGPA==", + "version": "13.24.0", + "resolved": "https://registry.npmjs.org/@mapbox/mapbox-gl-style-spec/-/mapbox-gl-style-spec-13.24.0.tgz", + "integrity": "sha512-9yhRSqnKX+59MrG647x2pACfR2Ewk8Ii5X75Ag8oToEKZU+PSY0+r10EirIVCTDwuHPzp/VuuN3j6n+Hv/gGpQ==", "requires": { "@mapbox/jsonlint-lines-primitives": "~2.0.2", "@mapbox/point-geometry": "^0.1.0", @@ -16194,11 +16194,11 @@ "dev": true }, "ol-mapbox-style": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/ol-mapbox-style/-/ol-mapbox-style-7.1.1.tgz", - "integrity": "sha512-GLTEYiH/Ec9Zn1eS4S/zXyR2sierVrUc+OLVP8Ra0FRyqRhoYbXdko0b7OIeSHWdtJfHssWYefDOGxfTRUUZ/A==", + "version": "8.0.4", + "resolved": "https://registry.npmjs.org/ol-mapbox-style/-/ol-mapbox-style-8.0.4.tgz", + "integrity": "sha512-Tvjy3reugxZ1CO+PzngdbCwBgEBfHJI7gBTk0RUhj6o01OZKbjr+9obqPav22TLhQB4f/8w+RPUF/M8+bnqtiQ==", "requires": { - "@mapbox/mapbox-gl-style-spec": "^13.20.1", + "@mapbox/mapbox-gl-style-spec": "^13.23.1", "mapbox-to-css-font": "^2.4.1", "webfont-matcher": "^1.1.0" } diff --git a/package.json b/package.json index b11e8fc4c5..d0acb76f94 100644 --- a/package.json +++ b/package.json @@ -46,7 +46,7 @@ }, "dependencies": { "geotiff": "^2.0.2", - "ol-mapbox-style": "^7.1.1", + "ol-mapbox-style": "^8.0.4", "pbf": "3.2.1", "rbush": "^3.0.1" }, diff --git a/src/ol/layer/MapboxVector.js b/src/ol/layer/MapboxVector.js index 324d2c079e..67f3736323 100644 --- a/src/ol/layer/MapboxVector.js +++ b/src/ol/layer/MapboxVector.js @@ -7,110 +7,7 @@ import MVT from '../format/MVT.js'; import SourceState from '../source/State.js'; import VectorTileLayer from '../layer/VectorTile.js'; import VectorTileSource from '../source/VectorTile.js'; -import {applyBackground, applyStyle, setupVectorSource} from 'ol-mapbox-style'; - -const mapboxBaseUrl = 'https://api.mapbox.com'; - -/** - * Gets the path from a mapbox:// URL. - * @param {string} url The Mapbox URL. - * @return {string} The path. - * @private - */ -export function getMapboxPath(url) { - const startsWith = 'mapbox://'; - if (url.indexOf(startsWith) !== 0) { - return ''; - } - return url.slice(startsWith.length); -} - -/** - * Turns mapbox:// sprite URLs into resolvable URLs. - * @param {string} url The sprite URL. - * @param {string} token The access token. - * @param {string} styleUrl The style URL. - * @return {string} A resolvable URL. - * @private - */ -export function normalizeSpriteUrl(url, token, styleUrl) { - const mapboxPath = getMapboxPath(url); - if (!mapboxPath) { - return decodeURI(new URL(url, styleUrl).href); - } - const startsWith = 'sprites/'; - if (mapboxPath.indexOf(startsWith) !== 0) { - throw new Error(`unexpected sprites url: ${url}`); - } - const sprite = mapboxPath.slice(startsWith.length); - - return `${mapboxBaseUrl}/styles/v1/${sprite}/sprite?access_token=${token}`; -} - -/** - * Turns mapbox:// glyphs URLs into resolvable URLs. - * @param {string} url The glyphs URL. - * @param {string} token The access token. - * @param {string} styleUrl The style URL. - * @return {string} A resolvable URL. - * @private - */ -export function normalizeGlyphsUrl(url, token, styleUrl) { - const mapboxPath = getMapboxPath(url); - if (!mapboxPath) { - return decodeURI(new URL(url, styleUrl).href); - } - const startsWith = 'fonts/'; - if (mapboxPath.indexOf(startsWith) !== 0) { - throw new Error(`unexpected fonts url: ${url}`); - } - const font = mapboxPath.slice(startsWith.length); - - return `${mapboxBaseUrl}/fonts/v1/${font}/0-255.pbf?access_token=${token}`; -} - -/** - * Turns mapbox:// style URLs into resolvable URLs. - * @param {string} url The style URL. - * @param {string} token The access token. - * @return {string} A resolvable URL. - * @private - */ -export function normalizeStyleUrl(url, token) { - const mapboxPath = getMapboxPath(url); - if (!mapboxPath) { - return decodeURI(new URL(url, location.href).href); - } - const startsWith = 'styles/'; - if (mapboxPath.indexOf(startsWith) !== 0) { - throw new Error(`unexpected style url: ${url}`); - } - const style = mapboxPath.slice(startsWith.length); - - return `${mapboxBaseUrl}/styles/v1/${style}?&access_token=${token}`; -} - -/** - * Turns mapbox:// source URLs into vector tile URL templates. - * @param {string} url The source URL. - * @param {string} token The access token. - * @param {string} tokenParam The access token key. - * @param {string} styleUrl The style URL. - * @return {string} A vector tile template. - * @private - */ -export function normalizeSourceUrl(url, token, tokenParam, styleUrl) { - const urlObject = new URL(url, styleUrl); - const mapboxPath = getMapboxPath(url); - if (!mapboxPath) { - if (!token) { - return decodeURI(urlObject.href); - } - urlObject.searchParams.set(tokenParam, token); - return decodeURI(urlObject.href); - } - return `https://{a-d}.tiles.mapbox.com/v4/${mapboxPath}/{z}/{x}/{y}.vector.pbf?access_token=${token}`; -} +import {applyBackground, applyStyle} from 'ol-mapbox-style'; /** * @classdesc @@ -130,38 +27,6 @@ class ErrorEvent extends BaseEvent { } } -/** - * @typedef {Object} StyleObject - * @property {Object} sources The style sources. - * @property {string} sprite The sprite URL. - * @property {string} glyphs The glyphs URL. - * @property {Array} layers The style layers. - */ - -/** - * @typedef {Object} SourceObject - * @property {string} url The source URL. - * @property {SourceType} type The source type. - * @property {Array} [tiles] TileJSON tiles. - */ - -/** - * The Mapbox source type. - * @enum {string} - */ -const SourceType = { - VECTOR: 'vector', -}; - -/** - * @typedef {Object} LayerObject - * @property {string} id The layer id. - * @property {string} type The layer type. - * @property {string} source The source id. - * @property {Object} layout The layout. - * @property {Object} paint The paint. - */ - /** * @typedef {Object} Options * @property {string} styleUrl The URL of the Mapbox style object to use for this layer. For a @@ -306,211 +171,26 @@ class MapboxVectorLayer extends VectorTileLayer { properties: options.properties, }); - this.setMaxResolutionFromTileGrid_ = - options.maxResolution === undefined && options.minZoom === undefined; - - this.sourceId = options.source; - this.layers = options.layers; - if (options.accessToken) { this.accessToken = options.accessToken; - } else { - const url = new URL(options.styleUrl, location.href); - // The last search parameter is the access token - url.searchParams.forEach((value, key) => { - this.accessToken = value; - this.accessTokenParam_ = key; - }); } - this.fetchStyle(options.styleUrl); - } - - /** - * Fetch the style object. - * @param {string} styleUrl The URL of the style to load. - * @protected - */ - fetchStyle(styleUrl) { - const url = normalizeStyleUrl(styleUrl, this.accessToken); - fetch(url) - .then((response) => { - if (!response.ok) { - throw new Error( - `unexpected response when fetching style: ${response.status}` - ); - } - return response.json(); - }) - .then((style) => { - this.onStyleLoad(style, url.startsWith('data:') ? location.href : url); + const url = options.styleUrl; + applyStyle(this, url, options.layers || options.source, { + accessToken: this.accessToken, + }) + .then(() => { + source.setState(SourceState.READY); }) .catch((error) => { - this.handleError(error); + this.dispatchEvent(new ErrorEvent(error)); + const source = this.getSource(); + source.setState(SourceState.ERROR); }); - } - - /** - * Handle the loaded style object. - * @param {StyleObject} style The loaded style. - * @param {string} styleUrl The URL of the style. - * @protected - */ - onStyleLoad(style, styleUrl) { - let sourceId; - let sourceIdOrLayersList; - if (this.layers) { - // confirm all layers share the same source - const lookup = {}; - for (let i = 0; i < style.layers.length; ++i) { - const layer = style.layers[i]; - if (layer.source) { - lookup[layer.id] = layer.source; - } - } - let firstSource; - for (let i = 0; i < this.layers.length; ++i) { - const candidate = lookup[this.layers[i]]; - if (!candidate) { - this.handleError( - new Error(`could not find source for ${this.layers[i]}`) - ); - return; - } - if (!firstSource) { - firstSource = candidate; - } else if (firstSource !== candidate) { - this.handleError( - new Error( - `layers can only use a single source, found ${firstSource} and ${candidate}` - ) - ); - return; - } - } - sourceId = firstSource; - sourceIdOrLayersList = this.layers; - } else { - sourceId = this.sourceId; - sourceIdOrLayersList = sourceId; - } - - if (!sourceIdOrLayersList) { - // default to the first source in the style - sourceId = Object.keys(style.sources)[0]; - sourceIdOrLayersList = sourceId; - } - - if (style.sprite) { - style.sprite = normalizeSpriteUrl( - style.sprite, - this.accessToken, - styleUrl - ); - } - - if (style.glyphs) { - style.glyphs = normalizeGlyphsUrl( - style.glyphs, - this.accessToken, - styleUrl - ); - } - - const styleSource = style.sources[sourceId]; - if (styleSource.type !== SourceType.VECTOR) { - this.handleError( - new Error(`only works for vector sources, found ${styleSource.type}`) - ); - return; - } - - const source = this.getSource(); - if (styleSource.url && styleSource.url.indexOf('mapbox://') === 0) { - // Tile source url, handle it directly - source.setUrl( - normalizeSourceUrl( - styleSource.url, - this.accessToken, - this.accessTokenParam_, - styleUrl - ) - ); - applyStyle(this, style, sourceIdOrLayersList) - .then(() => { - this.configureSource(source, style); - }) - .catch((error) => { - this.handleError(error); - }); - } else { - // TileJSON url, let ol-mapbox-style handle it - if (styleSource.tiles) { - styleSource.tiles = styleSource.tiles.map((url) => - normalizeSourceUrl( - url, - this.accessToken, - this.accessTokenParam_, - styleUrl - ) - ); - } - setupVectorSource( - styleSource, - styleSource.url - ? normalizeSourceUrl( - styleSource.url, - this.accessToken, - this.accessTokenParam_, - styleUrl - ) - : undefined - ).then((source) => { - applyStyle(this, style, sourceIdOrLayersList) - .then(() => { - this.configureSource(source, style); - }) - .catch((error) => { - this.configureSource(source, style); - this.handleError(error); - }); - }); - } - } - - /** - * Applies configuration from the provided source to this layer's source, - * and reconfigures the loader to add a feature that renders the background, - * if the style is configured with a background. - * @param {import("../source/VectorTile.js").default} source The source to configure from. - * @param {StyleObject} style The style to configure the background from. - */ - configureSource(source, style) { - const targetSource = this.getSource(); - if (source !== targetSource) { - targetSource.setAttributions(source.getAttributions()); - targetSource.setTileUrlFunction(source.getTileUrlFunction()); - targetSource.setTileLoadFunction(source.getTileLoadFunction()); - targetSource.tileGrid = source.tileGrid; - } if (this.getBackground() === undefined) { - applyBackground(this, style); + applyBackground(this, options.styleUrl, { + accessToken: this.accessToken, + }); } - if (this.setMaxResolutionFromTileGrid_) { - const tileGrid = targetSource.getTileGrid(); - this.setMaxResolution(tileGrid.getResolution(tileGrid.getMinZoom())); - } - targetSource.setState(SourceState.READY); - } - - /** - * Handle configuration or loading error. - * @param {Error} error The error. - * @protected - */ - handleError(error) { - this.dispatchEvent(new ErrorEvent(error)); - const source = this.getSource(); - source.setState(SourceState.ERROR); } } diff --git a/test/browser/spec/ol/layer/MapboxVector.test.js b/test/browser/spec/ol/layer/MapboxVector.test.js index 1079f06d52..6be026839a 100644 --- a/test/browser/spec/ol/layer/MapboxVector.test.js +++ b/test/browser/spec/ol/layer/MapboxVector.test.js @@ -1,123 +1,9 @@ -import MapboxVectorLayer, { - getMapboxPath, - normalizeSourceUrl, - normalizeSpriteUrl, - normalizeStyleUrl, -} from '../../../../../src/ol/layer/MapboxVector.js'; +import MapboxVectorLayer from '../../../../../src/ol/layer/MapboxVector.js'; import {asString} from '../../../../../src/ol/color.js'; +import {strokeInstruction} from '../../../../../src/ol/render/canvas/Instruction.js'; import {unByKey} from '../../../../../src/ol/Observable.js'; describe('ol/layer/MapboxVector', () => { - describe('getMapboxPath()', () => { - const cases = [ - { - url: 'mapbox://path/to/resource', - expected: 'path/to/resource', - }, - { - url: 'mapbox://path/to/resource?query', - expected: 'path/to/resource?query', - }, - { - url: 'https://example.com/resource', - expected: '', - }, - ]; - - for (const c of cases) { - it(`works for ${c.url}`, () => { - expect(getMapboxPath(c.url)).to.be(c.expected); - }); - } - }); - - describe('normalizeStyleUrl()', () => { - const cases = [ - { - url: 'mapbox://styles/mapbox/bright-v9', - expected: - 'https://api.mapbox.com/styles/v1/mapbox/bright-v9?&access_token=test-token', - }, - { - url: 'https://example.com/style', - expected: 'https://example.com/style', - }, - ]; - - const token = 'test-token'; - for (const c of cases) { - it(`works for ${c.url}`, () => { - expect(normalizeStyleUrl(c.url, token)).to.be(c.expected); - }); - } - }); - - describe('normalizeSpriteUrl()', () => { - const cases = [ - { - url: 'mapbox://sprites/mapbox/bright-v9', - expected: - 'https://api.mapbox.com/styles/v1/mapbox/bright-v9/sprite?access_token=test-token', - }, - { - url: 'https://example.com/sprite', - expected: 'https://example.com/sprite', - }, - { - url: '../sprite', - expected: 'https://example.com:8000/sprite', - }, - { - url: '/sprite', - expected: 'https://example.com:8000/sprite', - }, - { - url: './sprite', - expected: 'https://example.com:8000/mystyle/sprite', - }, - ]; - - const token = 'test-token'; - for (const c of cases) { - it(`works for ${c.url}`, () => { - expect( - normalizeSpriteUrl( - c.url, - token, - 'https://example.com:8000/mystyle/style.json' - ) - ).to.be(c.expected); - }); - } - }); - - describe('normalizeSourceUrl()', () => { - const cases = [ - { - url: 'mapbox://mapbox.mapbox-streets-v7', - expected: - 'https://{a-d}.tiles.mapbox.com/v4/mapbox.mapbox-streets-v7/{z}/{x}/{y}.vector.pbf?access_token=test-token', - }, - { - url: 'https://example.com/source/{z}/{x}/{y}.pbf', - expected: 'https://example.com/source/{z}/{x}/{y}.pbf?token=test-token', - }, - { - url: 'https://example.com/source/{z}/{x}/{y}.pbf?foo=bar', - expected: - 'https://example.com/source/{z}/{x}/{y}.pbf?foo=bar&token=test-token', - }, - ]; - - const token = 'test-token'; - const tokenParam = 'token'; - for (const c of cases) { - it(`works for ${c.url}`, () => { - expect(normalizeSourceUrl(c.url, token, tokenParam)).to.be(c.expected); - }); - } - }); - describe('TileJSON', function () { it('lets ol-mapbox-style handle TileJSON URLs', function (done) { const layer = new MapboxVectorLayer({ @@ -136,6 +22,9 @@ describe('ol/layer/MapboxVector', () => { }) ), }); + layer.on('error', function (e) { + done(e.error); + }); const source = layer.getSource(); const key = source.on('change', function () { if (source.getState() === 'ready') { @@ -185,6 +74,9 @@ describe('ol/layer/MapboxVector', () => { const layer = new MapboxVectorLayer({ styleUrl: styleUrl, }); + layer.on('error', function (e) { + done(e.error); + }); const source = layer.getSource(); source.on('change', function onchange() { if (source.getState() === 'ready') { @@ -312,20 +204,31 @@ describe('ol/layer/MapboxVector', () => { }); describe('Access token', function () { - it('applies correct access token from access_token', function () { - const layer = new MapboxVectorLayer({ + let originalFetch, fetchUrl; + beforeEach(function () { + originalFetch = fetch; + window.fetch = function (url) { + fetchUrl = url; + return Promise.resolve(); + }; + }); + afterEach(function () { + window.fetch = originalFetch; + }); + it('applies correct access token', function () { + new MapboxVectorLayer({ styleUrl: 'mapbox://styles/mapbox/streets-v7', accessToken: '123', }); - expect(layer.accessToken).to.be('123'); - expect(layer.accessTokenParam_).to.be(undefined); + expect(fetchUrl.url).to.be( + 'https://api.mapbox.com/styles/v1/mapbox/streets-v7?&access_token=123' + ); }); it('applies correct access token from url', function () { - const layer = new MapboxVectorLayer({ + new MapboxVectorLayer({ styleUrl: 'foo?key=123', }); - expect(layer.accessToken).to.be('123'); - expect(layer.accessTokenParam_).to.be('key'); + expect(fetchUrl.url).to.be(`${location.origin}/foo?key=123`); }); }); });