326 lines
13 KiB
JavaScript
326 lines
13 KiB
JavaScript
defineSuite([
|
|
'Core/IonResource',
|
|
'Core/Ion',
|
|
'Core/RequestErrorEvent',
|
|
'Core/Resource',
|
|
'Core/RuntimeError',
|
|
'ThirdParty/when'
|
|
], function(
|
|
IonResource,
|
|
Ion,
|
|
RequestErrorEvent,
|
|
Resource,
|
|
RuntimeError,
|
|
when) {
|
|
'use strict';
|
|
|
|
var assetId = 123890213;
|
|
var endpoint = {
|
|
type: '3DTILES',
|
|
url: 'https://assets.cesium.com/' + assetId + '/tileset.json',
|
|
accessToken: 'not_really_a_refresh_token',
|
|
attributions: []
|
|
};
|
|
|
|
it('constructs with expected values', function() {
|
|
spyOn(Resource, 'call').and.callThrough();
|
|
|
|
var endpointResource = IonResource._createEndpointResource(assetId);
|
|
var resource = new IonResource(endpoint, endpointResource);
|
|
expect(resource).toBeInstanceOf(Resource);
|
|
expect(resource._ionEndpoint).toEqual(endpoint);
|
|
expect(Resource.call).toHaveBeenCalledWith(resource, {
|
|
url: endpoint.url,
|
|
retryCallback: resource.retryCallback,
|
|
retryAttempts: 1
|
|
});
|
|
});
|
|
|
|
it('clone works', function() {
|
|
var endpointResource = IonResource._createEndpointResource(assetId);
|
|
var resource = new IonResource(endpoint, endpointResource);
|
|
var cloned = resource.clone();
|
|
expect(cloned).not.toBe(resource);
|
|
expect(cloned._ionRoot).toBe(resource);
|
|
cloned._ionRoot = undefined;
|
|
expect(cloned.retryCallback).toBe(resource.retryCallback);
|
|
expect(cloned.headers.Authorization).toBe(resource.headers.Authorization);
|
|
expect(cloned).toEqual(resource);
|
|
});
|
|
|
|
it('create creates the expected resource', function() {
|
|
var endpointResource = IonResource._createEndpointResource(assetId);
|
|
var resource = new IonResource(endpoint, endpointResource);
|
|
expect(resource.getUrlComponent()).toEqual(endpoint.url);
|
|
expect(resource._ionEndpoint).toBe(endpoint);
|
|
expect(resource._ionEndpointResource).toEqual(endpointResource);
|
|
expect(resource.retryCallback).toBeDefined();
|
|
expect(resource.retryAttempts).toBe(1);
|
|
});
|
|
|
|
it('fromAssetId calls constructor for non-external endpoint with expected parameters', function() {
|
|
var tilesAssetId = 123890213;
|
|
var tilesEndpoint = {
|
|
type: '3DTILES',
|
|
url: 'https://assets.cesium.com/' + tilesAssetId + '/tileset.json',
|
|
accessToken: 'not_really_a_refresh_token',
|
|
attributions: []
|
|
};
|
|
|
|
var options = {};
|
|
var resourceEndpoint = IonResource._createEndpointResource(tilesAssetId, options);
|
|
spyOn(IonResource, '_createEndpointResource').and.returnValue(resourceEndpoint);
|
|
spyOn(resourceEndpoint, 'fetchJson').and.returnValue(when.resolve(tilesEndpoint));
|
|
|
|
return IonResource.fromAssetId(tilesAssetId, options)
|
|
.then(function(resource) {
|
|
expect(IonResource._createEndpointResource).toHaveBeenCalledWith(tilesAssetId, options);
|
|
expect(resourceEndpoint.fetchJson).toHaveBeenCalled();
|
|
expect(resource._ionEndpointResource).toEqual(resourceEndpoint);
|
|
expect(resource._ionEndpoint).toEqual(tilesEndpoint);
|
|
});
|
|
});
|
|
|
|
function testNonImageryExternalResource(externalEndpoint) {
|
|
var resourceEndpoint = IonResource._createEndpointResource(123890213);
|
|
spyOn(IonResource, '_createEndpointResource').and.returnValue(resourceEndpoint);
|
|
spyOn(resourceEndpoint, 'fetchJson').and.returnValue(when.resolve(externalEndpoint));
|
|
|
|
return IonResource.fromAssetId(123890213)
|
|
.then(function(resource) {
|
|
expect(resource.url).toEqual(externalEndpoint.options.url);
|
|
expect(resource.headers.Authorization).toBeUndefined();
|
|
expect(resource.retryCallback).toBeUndefined();
|
|
});
|
|
}
|
|
|
|
it('fromAssetId returns basic Resource for external 3D tilesets', function() {
|
|
return testNonImageryExternalResource({
|
|
type: '3DTILES',
|
|
externalType: '3DTILES',
|
|
options: { url: 'http://test.invalid/tileset.json' },
|
|
attributions: []
|
|
});
|
|
});
|
|
|
|
it('fromAssetId returns basic Resource for external 3D tilesets', function() {
|
|
return testNonImageryExternalResource({
|
|
type: 'TERRAIN',
|
|
externalType: 'STK_TERRAIN_SERVER',
|
|
options: { url: 'http://test.invalid/world' },
|
|
attributions: []
|
|
});
|
|
});
|
|
|
|
it('fromAssetId rejects for external imagery', function() {
|
|
return testNonImageryExternalResource({
|
|
type: 'IMAGERY',
|
|
externalType: 'URL_TEMPLATE',
|
|
url: 'http://test.invalid/world',
|
|
attributions: []
|
|
})
|
|
.then(fail)
|
|
.otherwise(function(e) {
|
|
expect(e).toBeInstanceOf(RuntimeError);
|
|
});
|
|
});
|
|
|
|
it('createEndpointResource creates expected values with default parameters', function() {
|
|
var assetId = 2348234;
|
|
var resource = IonResource._createEndpointResource(assetId);
|
|
expect(resource.url).toBe(Ion.defaultServer.url + 'v1/assets/' + assetId + '/endpoint?access_token=' + Ion.defaultAccessToken);
|
|
});
|
|
|
|
it('createEndpointResource creates expected values with overridden options', function() {
|
|
var serverUrl = 'https://api.cesium.test/';
|
|
var accessToken = 'not_a_token';
|
|
|
|
var assetId = 2348234;
|
|
var resource = IonResource._createEndpointResource(assetId, { server: serverUrl, accessToken: accessToken });
|
|
expect(resource.url).toBe(serverUrl + 'v1/assets/' + assetId + '/endpoint?access_token=' + accessToken);
|
|
});
|
|
|
|
it('createEndpointResource creates expected values with overridden defaults', function() {
|
|
var defaultServer = Ion.defaultServer;
|
|
var defaultAccessToken = Ion.defaultAccessToken;
|
|
|
|
Ion.defaultServer = new Resource({ url: 'https://api.cesium.test/' });
|
|
Ion.defaultAccessToken = 'not_a_token';
|
|
|
|
var assetId = 2348234;
|
|
var resource = IonResource._createEndpointResource(assetId);
|
|
expect(resource.url).toBe(Ion.defaultServer.url + 'v1/assets/' + assetId + '/endpoint?access_token=' + Ion.defaultAccessToken);
|
|
|
|
Ion.defaultServer = defaultServer;
|
|
Ion.defaultAccessToken = defaultAccessToken;
|
|
});
|
|
|
|
it('Calls base _makeRequest with expected options when resource no Accept header is already defined', function() {
|
|
var originalOptions = {};
|
|
var expectedOptions = {
|
|
headers: {
|
|
Accept: '*/*;access_token=' + endpoint.accessToken
|
|
}
|
|
};
|
|
|
|
var _makeRequest = spyOn(Resource.prototype, '_makeRequest');
|
|
var endpointResource = IonResource._createEndpointResource(assetId);
|
|
var resource = new IonResource(endpoint, endpointResource);
|
|
resource._makeRequest(originalOptions);
|
|
expect(_makeRequest).toHaveBeenCalledWith(expectedOptions);
|
|
});
|
|
|
|
it('Calls base _makeRequest with expected options when resource Accept header is already defined', function() {
|
|
var originalOptions = {};
|
|
var expectedOptions = {
|
|
headers: {
|
|
Accept: 'application/json,*/*;access_token=' + endpoint.accessToken
|
|
}
|
|
};
|
|
|
|
var _makeRequest = spyOn(Resource.prototype, '_makeRequest');
|
|
var endpointResource = IonResource._createEndpointResource(assetId);
|
|
var resource = new IonResource(endpoint, endpointResource);
|
|
resource.headers.Accept = 'application/json';
|
|
resource._makeRequest(originalOptions);
|
|
expect(_makeRequest).toHaveBeenCalledWith(expectedOptions);
|
|
});
|
|
|
|
it('Calls base _makeRequest with expected options when options header.Accept is already defined', function() {
|
|
var originalOptions = {
|
|
headers: {
|
|
Accept: 'application/json'
|
|
}
|
|
};
|
|
var expectedOptions = {
|
|
headers: {
|
|
Accept: 'application/json,*/*;access_token=' + endpoint.accessToken
|
|
}
|
|
};
|
|
|
|
var _makeRequest = spyOn(Resource.prototype, '_makeRequest');
|
|
var endpointResource = IonResource._createEndpointResource(assetId);
|
|
var resource = new IonResource(endpoint, endpointResource);
|
|
resource._makeRequest(originalOptions);
|
|
expect(_makeRequest).toHaveBeenCalledWith(expectedOptions);
|
|
});
|
|
|
|
it('Calls base _makeRequest with no changes for external assets', function() {
|
|
var externalEndpoint = {
|
|
type: '3DTILES',
|
|
externalType: '3DTILES',
|
|
options: { url: 'http://test.invalid/tileset.json' },
|
|
attributions: []
|
|
};
|
|
var options = {};
|
|
|
|
var _makeRequest = spyOn(Resource.prototype, '_makeRequest');
|
|
var endpointResource = IonResource._createEndpointResource(assetId);
|
|
var resource = new IonResource(externalEndpoint, endpointResource);
|
|
resource._makeRequest(options);
|
|
expect(_makeRequest.calls.argsFor(0)[0]).toBe(options);
|
|
});
|
|
|
|
it('Calls base fetchImage with preferBlob for ion assets', function() {
|
|
var fetchImage = spyOn(Resource.prototype, 'fetchImage');
|
|
var endpointResource = IonResource._createEndpointResource(assetId);
|
|
var resource = new IonResource(endpoint, endpointResource);
|
|
resource.fetchImage(false, true);
|
|
expect(fetchImage).toHaveBeenCalledWith(true, true);
|
|
});
|
|
|
|
it('Calls base fetchImage with no changes for external assets', function() {
|
|
var externalEndpoint = {
|
|
type: '3DTILES',
|
|
externalType: '3DTILES',
|
|
options: { url: 'http://test.invalid/tileset.json' },
|
|
attributions: []
|
|
};
|
|
|
|
var fetchImage = spyOn(Resource.prototype, 'fetchImage');
|
|
var endpointResource = IonResource._createEndpointResource(assetId);
|
|
var resource = new IonResource(externalEndpoint, endpointResource);
|
|
resource.fetchImage(false, true);
|
|
expect(fetchImage).toHaveBeenCalledWith(false, true);
|
|
});
|
|
|
|
describe('retryCallback', function() {
|
|
var endpointResource;
|
|
var resource;
|
|
var retryCallback;
|
|
|
|
beforeEach(function() {
|
|
endpointResource = new Resource({ url: 'https://api.test.invalid', access_token: 'not_the_token' });
|
|
resource = new IonResource(endpoint, endpointResource);
|
|
retryCallback = resource.retryCallback;
|
|
});
|
|
|
|
it('returns false when error is undefined', function() {
|
|
return retryCallback(resource, undefined).then(function(result) {
|
|
expect(result).toBe(false);
|
|
});
|
|
});
|
|
|
|
it('returns false when error is non-401', function() {
|
|
var error = new RequestErrorEvent(404);
|
|
return retryCallback(resource, error).then(function(result) {
|
|
expect(result).toBe(false);
|
|
});
|
|
});
|
|
|
|
it('returns false when error is event with non-Image target', function() {
|
|
var event = { target: {} };
|
|
return retryCallback(resource, event).then(function(result) {
|
|
expect(result).toBe(false);
|
|
});
|
|
});
|
|
|
|
function testCallback(resource, event) {
|
|
var deferred = when.defer();
|
|
spyOn(endpointResource, 'fetchJson').and.returnValue(deferred.promise);
|
|
|
|
var newEndpoint = {
|
|
type: '3DTILES',
|
|
url: 'https://assets.cesium.com/' + assetId,
|
|
accessToken: 'not_not_really_a_refresh_token'
|
|
};
|
|
|
|
var promise = retryCallback(resource, event);
|
|
var resultPromise = promise.then(function(result) {
|
|
expect(result).toBe(true);
|
|
expect(resource._ionEndpoint).toBe(newEndpoint);
|
|
});
|
|
|
|
expect(endpointResource.fetchJson).toHaveBeenCalledWith();
|
|
|
|
//A second retry should re-use the same pending promise
|
|
var promise2 = retryCallback(resource, event);
|
|
expect(promise._pendingPromise).toBe(promise2._pendingPromise);
|
|
|
|
deferred.resolve(newEndpoint);
|
|
|
|
return resultPromise;
|
|
}
|
|
|
|
it('works when error is a 401', function() {
|
|
var error = new RequestErrorEvent(401);
|
|
return testCallback(resource, error);
|
|
});
|
|
|
|
it('works when error is event with Image target', function() {
|
|
var event = { target: new Image() };
|
|
return testCallback(resource, event);
|
|
});
|
|
|
|
it('works with derived resource and sets root access_token', function() {
|
|
var derived = resource.getDerivedResource('1');
|
|
var error = new RequestErrorEvent(401);
|
|
return testCallback(derived, error)
|
|
.then(function(){
|
|
expect(derived._ionEndpoint).toBe(resource._ionEndpoint);
|
|
expect(derived.headers.Authorization).toEqual(resource.headers.Authorization);
|
|
});
|
|
});
|
|
});
|
|
});
|