Files
openstapps/src/app/modules/config/config.provider.spec.ts
2019-04-09 14:57:06 +00:00

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'],
},
],
},
};