mirror of
https://gitlab.com/openstapps/openstapps.git
synced 2026-01-06 13:32:53 +00:00
306 lines
8.8 KiB
TypeScript
306 lines
8.8 KiB
TypeScript
/*
|
|
* Copyright (C) 2019 StApps
|
|
* This program is free software: you can redistribute it and/or modify it
|
|
* under the terms of the GNU General Public License as published by the Free
|
|
* Software Foundation, version 3.
|
|
*
|
|
* This program is distributed in the hope that it will be useful, but WITHOUT
|
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
|
* more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License along with
|
|
* this program. If not, see <https://www.gnu.org/licenses/>.
|
|
*/
|
|
import {TestBed} from '@angular/core/testing';
|
|
import {SCIndexResponse} from '@openstapps/core';
|
|
import {StAppsWebHttpClient} from '../data/data.provider';
|
|
import {StorageProvider} from '../storage/storage.provider';
|
|
import {ConfigProvider, STORAGE_KEY_CONFIG} from './config.provider';
|
|
import {
|
|
ConfigFetchError,
|
|
ConfigInitError,
|
|
SavedConfigNotAvailable,
|
|
WrongConfigVersionInStorage,
|
|
} from './errors';
|
|
|
|
describe('ConfigProvider', () => {
|
|
let configProvider: ConfigProvider;
|
|
let storageProviderSpy: jasmine.SpyObj<StorageProvider>;
|
|
|
|
beforeEach(() => {
|
|
const storageProviderMethodSpy = jasmine.createSpyObj('StorageProvider', ['init', 'get', 'has', 'put']);
|
|
const webHttpClientMethodSpy = jasmine.createSpyObj('StAppsWebHttpClient', ['request']);
|
|
|
|
TestBed.configureTestingModule({
|
|
imports: [],
|
|
providers: [
|
|
ConfigProvider,
|
|
{
|
|
provide: StorageProvider, useValue: storageProviderMethodSpy,
|
|
},
|
|
{
|
|
provide: StAppsWebHttpClient, useValue: webHttpClientMethodSpy,
|
|
},
|
|
],
|
|
});
|
|
|
|
configProvider = TestBed.get(ConfigProvider);
|
|
storageProviderSpy = TestBed.get(StorageProvider);
|
|
});
|
|
|
|
it('should fetch app configuration', async () => {
|
|
spyOn(configProvider.client, 'handshake').and.returnValue(sampleIndexResponse);
|
|
const result = await configProvider.fetch();
|
|
expect(result).toEqual(sampleIndexResponse);
|
|
});
|
|
|
|
it('should throw error on fetch with error response', async () => {
|
|
spyOn(configProvider.client, 'handshake').and.throwError('');
|
|
let error = new Error('');
|
|
try {
|
|
await configProvider.fetch();
|
|
} catch (err) {
|
|
error = err;
|
|
}
|
|
expect(error).toEqual(new ConfigFetchError());
|
|
});
|
|
|
|
it('should init from remote and saved config not available', async () => {
|
|
storageProviderSpy.has.and.returnValue(false);
|
|
spyOn(configProvider.client, 'handshake').and.returnValue(sampleIndexResponse);
|
|
try {
|
|
await configProvider.init();
|
|
} catch (error) {
|
|
expect(error).toEqual(new SavedConfigNotAvailable());
|
|
}
|
|
expect(storageProviderSpy.has).toHaveBeenCalled();
|
|
expect(storageProviderSpy.get).toHaveBeenCalledTimes(0);
|
|
expect(configProvider.client.handshake).toHaveBeenCalled();
|
|
expect(configProvider.initialised).toBe(true);
|
|
expect(await configProvider.getValue('name')).toEqual(sampleIndexResponse.app.name);
|
|
});
|
|
|
|
it('should init from storage with remote fails', async () => {
|
|
storageProviderSpy.has.and.returnValue(true);
|
|
storageProviderSpy.get.and.returnValue(sampleIndexResponse);
|
|
spyOn(configProvider.client, 'handshake').and.throwError('');
|
|
let error = new Error('');
|
|
try {
|
|
await configProvider.init();
|
|
} catch (err) {
|
|
error = err;
|
|
}
|
|
expect(error).toEqual(new ConfigFetchError());
|
|
expect(storageProviderSpy.has).toHaveBeenCalled();
|
|
expect(storageProviderSpy.get).toHaveBeenCalled();
|
|
expect(configProvider.initialised).toBe(true);
|
|
expect(await configProvider.getValue('name')).toEqual(sampleIndexResponse.app.name);
|
|
});
|
|
|
|
it('should throw error on failed initialisation', async () => {
|
|
storageProviderSpy.has.and.returnValue(false);
|
|
spyOn(configProvider.client, 'handshake').and.throwError('');
|
|
let error = null;
|
|
try {
|
|
await configProvider.init();
|
|
} catch (err) {
|
|
error = err;
|
|
}
|
|
expect(error).toEqual(new ConfigInitError());
|
|
});
|
|
|
|
it('should throw error on wrong config version in storage', async () => {
|
|
storageProviderSpy.has.and.returnValue(true);
|
|
const wrongConfig = JSON.parse(JSON.stringify(sampleIndexResponse));
|
|
wrongConfig.backend.SCVersion = '0.1.0';
|
|
storageProviderSpy.get.and.returnValue(wrongConfig);
|
|
spyOn(configProvider.client, 'handshake').and.returnValue(sampleIndexResponse);
|
|
let error = null;
|
|
try {
|
|
await configProvider.init();
|
|
} catch (err) {
|
|
error = err;
|
|
}
|
|
expect(error).toEqual(new WrongConfigVersionInStorage('1.0.0', '0.1.0'));
|
|
});
|
|
|
|
it('should throw error on saved app configuration not available', async () => {
|
|
storageProviderSpy.has.and.returnValue(false);
|
|
let error = new Error('');
|
|
try {
|
|
await configProvider.loadLocal();
|
|
} catch (err) {
|
|
error = err;
|
|
}
|
|
expect(error).toEqual(new SavedConfigNotAvailable());
|
|
});
|
|
|
|
it('should save app configuration', async () => {
|
|
await configProvider.save(sampleIndexResponse);
|
|
expect(storageProviderSpy.put).toHaveBeenCalledWith(STORAGE_KEY_CONFIG, sampleIndexResponse);
|
|
});
|
|
|
|
it('should set app configuration', async () => {
|
|
await configProvider.set(sampleIndexResponse);
|
|
expect(storageProviderSpy.put).toHaveBeenCalled();
|
|
});
|
|
|
|
it('should return app configuration value', async () => {
|
|
storageProviderSpy.has.and.returnValue(true);
|
|
storageProviderSpy.get.and.returnValue(sampleIndexResponse);
|
|
spyOn(configProvider.client, 'handshake').and.returnValue(sampleIndexResponse);
|
|
await configProvider.init();
|
|
expect(await configProvider.getValue('name')).toEqual(sampleIndexResponse.app.name);
|
|
});
|
|
|
|
it('should return app configuration value if only saved config is available and fetch fails', async () => {
|
|
storageProviderSpy.has.and.returnValue(true);
|
|
storageProviderSpy.get.and.returnValue(sampleIndexResponse);
|
|
spyOn(configProvider.client, 'handshake').and.throwError('');
|
|
expect(await configProvider.getValue('name')).toEqual(sampleIndexResponse.app.name);
|
|
});
|
|
});
|
|
|
|
const sampleIndexResponse: SCIndexResponse = {
|
|
app: {
|
|
campusPolygon: {
|
|
coordinates: [[[1, 2]], [[1, 2]]],
|
|
type: 'Polygon',
|
|
},
|
|
features: {
|
|
widgets: false,
|
|
},
|
|
menus: [
|
|
{
|
|
icon: 'icon',
|
|
id: 'main',
|
|
items: [
|
|
{
|
|
icon: 'icon',
|
|
route: '/index',
|
|
title: 'start',
|
|
translations: {
|
|
de: {
|
|
title: 'Start',
|
|
},
|
|
en: {
|
|
title: 'start',
|
|
},
|
|
},
|
|
},
|
|
|
|
],
|
|
name: 'main',
|
|
translations: {
|
|
de: {
|
|
name: 'Haupt',
|
|
},
|
|
en: {
|
|
name: 'main',
|
|
},
|
|
},
|
|
},
|
|
],
|
|
name: 'StApps',
|
|
privacyPolicyUrl: 'foo.bar',
|
|
settings: [
|
|
{
|
|
categories: ['credentials'],
|
|
input: {
|
|
defaultValue: '',
|
|
inputType: 'text',
|
|
},
|
|
name: 'username',
|
|
order: 0,
|
|
origin: {
|
|
indexed: '2018-09-11T12:30:00Z',
|
|
name: 'Dummy',
|
|
},
|
|
translations: {
|
|
de: {
|
|
categories: ['Anmeldedaten'],
|
|
name: 'Benutzername',
|
|
},
|
|
en: {
|
|
categories: ['Credentials'],
|
|
name: 'Username',
|
|
},
|
|
},
|
|
type: 'setting',
|
|
uid: '',
|
|
},
|
|
],
|
|
},
|
|
backend: {
|
|
SCVersion: '1.0.0',
|
|
hiddenTypes: [
|
|
'date series',
|
|
'diff',
|
|
'floor',
|
|
],
|
|
name: 'Technische Universität Berlin',
|
|
namespace: '909a8cbc-8520-456c-b474-ef1525f14209',
|
|
sortableFields: [
|
|
{
|
|
fieldName: 'name',
|
|
sortTypes: ['ducet'],
|
|
},
|
|
{
|
|
fieldName: 'type',
|
|
sortTypes: ['ducet'],
|
|
},
|
|
{
|
|
fieldName: 'categories',
|
|
onlyOnTypes: [
|
|
'academic event',
|
|
'building',
|
|
'catalog',
|
|
'dish',
|
|
'point of interest',
|
|
'room',
|
|
],
|
|
sortTypes: ['ducet'],
|
|
},
|
|
{
|
|
fieldName: 'geo.point.coordinates',
|
|
onlyOnTypes: [
|
|
'building',
|
|
'point of interest',
|
|
'room',
|
|
],
|
|
sortTypes: ['distance'],
|
|
},
|
|
{
|
|
fieldName: 'geo.point.coordinates',
|
|
onlyOnTypes: [
|
|
'building',
|
|
'point of interest',
|
|
'room',
|
|
],
|
|
sortTypes: ['distance'],
|
|
},
|
|
{
|
|
fieldName: 'inPlace.geo.point.coordinates',
|
|
onlyOnTypes: [
|
|
'date series',
|
|
'dish',
|
|
'floor',
|
|
'organization',
|
|
'point of interest',
|
|
'room',
|
|
'ticket',
|
|
],
|
|
sortTypes: ['distance'],
|
|
},
|
|
{
|
|
fieldName: 'offers',
|
|
onlyOnTypes: [
|
|
'dish',
|
|
],
|
|
sortTypes: ['price'],
|
|
},
|
|
],
|
|
},
|
|
};
|