mirror of
https://gitlab.com/openstapps/openstapps.git
synced 2026-01-20 08:33:11 +00:00
398 lines
14 KiB
TypeScript
398 lines
14 KiB
TypeScript
/*
|
|
* Copyright (C) 2018, 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 {SCSetting, SCThingOriginType, SCThingType, SCSettingInputType} from '@openstapps/core';
|
|
import {ConfigProvider} from '../config/config.provider';
|
|
import {StorageProvider} from '../storage/storage.provider';
|
|
import {SettingsProvider, SettingValuesContainer, STORAGE_KEY_SETTING_VALUES} from './settings.provider';
|
|
import {Geolocation} from '@ionic-native/geolocation/ngx';
|
|
|
|
describe('SettingsProvider', () => {
|
|
let configProviderSpy: jasmine.SpyObj<ConfigProvider>;
|
|
let settingsProvider: SettingsProvider;
|
|
let storageProviderSpy: jasmine.SpyObj<StorageProvider>;
|
|
|
|
beforeEach(async () => {
|
|
const storageProviderMethodSpy = jasmine.createSpyObj('StorageProvider', ['init', 'get', 'has', 'put']);
|
|
const configProviderMethodSpy = jasmine.createSpyObj('ConfigProvider', ['getValue']);
|
|
|
|
TestBed.configureTestingModule({
|
|
imports: [],
|
|
providers: [
|
|
SettingsProvider,
|
|
{
|
|
provide: StorageProvider, useValue: storageProviderMethodSpy,
|
|
},
|
|
{
|
|
provide: ConfigProvider, useValue: configProviderMethodSpy,
|
|
},
|
|
Geolocation,
|
|
],
|
|
});
|
|
configProviderSpy = TestBed.get(ConfigProvider);
|
|
// set settings returned from config
|
|
configProviderSpy.getValue.and.returnValue(Promise.resolve(CONFIG_SETTINGS_MOCK));
|
|
settingsProvider = TestBed.get(SettingsProvider);
|
|
storageProviderSpy = TestBed.get(StorageProvider);
|
|
storageProviderMethodSpy.has.and.returnValue(false);
|
|
});
|
|
|
|
it('should provide and get setting', async () => {
|
|
await settingsProvider.provideSetting(JSON.parse(JSON.stringify(CONFIG_SETTINGS_MOCK[0])));
|
|
const setting: SCSetting = await settingsProvider
|
|
.getSetting(CONFIG_SETTINGS_MOCK[0].categories[0], CONFIG_SETTINGS_MOCK[0].name);
|
|
await expect(setting.value).toBeDefined();
|
|
});
|
|
|
|
it('should provide and get settings value', async () => {
|
|
await settingsProvider.provideSetting(JSON.parse(JSON.stringify(CONFIG_SETTINGS_MOCK[0])));
|
|
const value = await settingsProvider
|
|
.getValue(CONFIG_SETTINGS_MOCK[0].categories[0], CONFIG_SETTINGS_MOCK[0].name);
|
|
await expect(value).toEqual(CONFIG_SETTINGS_MOCK[0].defaultValue);
|
|
});
|
|
|
|
it('should get persisted setting value', async () => {
|
|
// set return values of storage
|
|
storageProviderSpy.has.and.returnValue(Promise.resolve(true));
|
|
storageProviderSpy.get.and.returnValue(Promise.resolve(SETTING_VALUES_MOCK));
|
|
|
|
const value = await settingsProvider
|
|
.getValue(CONFIG_SETTINGS_MOCK[3].categories[0], CONFIG_SETTINGS_MOCK[3].name);
|
|
await expect(value).toEqual(SETTING_VALUES_MOCK.profile.group);
|
|
});
|
|
|
|
it('should set default setting value if no persisted value exist', async () => {
|
|
// set return values of spy objects
|
|
storageProviderSpy.has.and.returnValue(Promise.resolve(true));
|
|
storageProviderSpy.get.and.returnValue(Promise.resolve([]));
|
|
const value = await settingsProvider
|
|
.getValue(CONFIG_SETTINGS_MOCK[3].categories[0], CONFIG_SETTINGS_MOCK[3].name);
|
|
await expect(value).toEqual(CONFIG_SETTINGS_MOCK[3].defaultValue);
|
|
});
|
|
|
|
it('should keep persisted setting values from settings that are not contained in loaded config', async () => {
|
|
const settings = [
|
|
CONFIG_SETTINGS_MOCK[4],
|
|
CONFIG_SETTINGS_MOCK[5],
|
|
];
|
|
configProviderSpy.getValue.and.returnValue(Promise.resolve(settings));
|
|
storageProviderSpy.has.and.returnValue(Promise.resolve(true));
|
|
storageProviderSpy.get.and.returnValue(Promise.resolve(SETTING_VALUES_MOCK));
|
|
await settingsProvider.init();
|
|
await expect(storageProviderSpy.put).toHaveBeenCalledWith(STORAGE_KEY_SETTING_VALUES, SETTING_VALUES_MOCK);
|
|
});
|
|
|
|
it('should set value of a provided setting', async () => {
|
|
await settingsProvider.provideSetting(JSON.parse(JSON.stringify(CONFIG_SETTINGS_MOCK[1])));
|
|
await settingsProvider
|
|
.setSettingValue(CONFIG_SETTINGS_MOCK[1].categories[0], CONFIG_SETTINGS_MOCK[1].name, 'updated');
|
|
const value = await settingsProvider
|
|
.getValue(CONFIG_SETTINGS_MOCK[1].categories[0], CONFIG_SETTINGS_MOCK[1].name);
|
|
await expect(value).toEqual('updated');
|
|
});
|
|
|
|
it('should return copy of settingsCache', async () => {
|
|
const category = CONFIG_SETTINGS_MOCK[0].categories[0];
|
|
const name = CONFIG_SETTINGS_MOCK[0].name;
|
|
await settingsProvider.provideSetting(JSON.parse(JSON.stringify(CONFIG_SETTINGS_MOCK[0])));
|
|
const settings = await settingsProvider.getCache();
|
|
settings[category].settings[name].value = 'testValue';
|
|
// cached setting value should still be defaultValue
|
|
await expect((await settingsProvider.getValue(category, name)))
|
|
.toEqual(CONFIG_SETTINGS_MOCK[0].defaultValue);
|
|
});
|
|
|
|
it('should call storage put on setSettingValue', async () => {
|
|
await settingsProvider.provideSetting(JSON.parse(JSON.stringify(CONFIG_SETTINGS_MOCK[0])));
|
|
await settingsProvider
|
|
.setSettingValue(CONFIG_SETTINGS_MOCK[0].categories[0], CONFIG_SETTINGS_MOCK[0].name, '');
|
|
await expect(storageProviderSpy.put).toHaveBeenCalled();
|
|
});
|
|
|
|
it('should clear settings', async () => {
|
|
await settingsProvider.reset();
|
|
await expect(storageProviderSpy.put).toHaveBeenCalledWith(STORAGE_KEY_SETTING_VALUES, {});
|
|
});
|
|
|
|
it('should reset settings', async () => {
|
|
const category = CONFIG_SETTINGS_MOCK[0].categories[0];
|
|
const name = CONFIG_SETTINGS_MOCK[0].name;
|
|
await settingsProvider.provideSetting(JSON.parse(JSON.stringify(CONFIG_SETTINGS_MOCK[0])));
|
|
await settingsProvider.setSettingValue(category, name, 'guest');
|
|
await settingsProvider.resetDefault();
|
|
const value = await settingsProvider
|
|
.getValue(CONFIG_SETTINGS_MOCK[0].categories[0], CONFIG_SETTINGS_MOCK[0].name);
|
|
await expect(value).toEqual(CONFIG_SETTINGS_MOCK[0].defaultValue);
|
|
});
|
|
|
|
it('should validate wrong values for inputType text', async () => {
|
|
await testValue(CONFIG_SETTINGS_MOCK[0], 123456789);
|
|
await testValue(CONFIG_SETTINGS_MOCK[0], false);
|
|
await testValue(CONFIG_SETTINGS_MOCK[0], []);
|
|
});
|
|
|
|
it('should validate wrong values for inputType password', async () => {
|
|
await testValue(CONFIG_SETTINGS_MOCK[0], 123456789);
|
|
await testValue(CONFIG_SETTINGS_MOCK[0], false);
|
|
await testValue(CONFIG_SETTINGS_MOCK[0], []);
|
|
});
|
|
|
|
it('should validate wrong values for inputType number', async () => {
|
|
await testValue(CONFIG_SETTINGS_MOCK[2], '');
|
|
await testValue(CONFIG_SETTINGS_MOCK[2], false);
|
|
await testValue(CONFIG_SETTINGS_MOCK[2], []);
|
|
});
|
|
|
|
it('should validate wrong values for inputType singleChoice text', async () => {
|
|
await testValue(CONFIG_SETTINGS_MOCK[3], '');
|
|
await testValue(CONFIG_SETTINGS_MOCK[3], 123456);
|
|
await testValue(CONFIG_SETTINGS_MOCK[3], false);
|
|
await testValue(CONFIG_SETTINGS_MOCK[3], []);
|
|
});
|
|
|
|
it('should validate wrong values for inputType singleChoice boolean', async () => {
|
|
await testValue(CONFIG_SETTINGS_MOCK[5], '');
|
|
await testValue(CONFIG_SETTINGS_MOCK[5], 123456);
|
|
await testValue(CONFIG_SETTINGS_MOCK[5], []);
|
|
});
|
|
|
|
it('should validate wrong values for inputType multipleChoice', async () => {
|
|
await testValue(CONFIG_SETTINGS_MOCK[6], '');
|
|
await testValue(CONFIG_SETTINGS_MOCK[6], 123456);
|
|
await testValue(CONFIG_SETTINGS_MOCK[6], false);
|
|
await testValue(CONFIG_SETTINGS_MOCK[6], [1, 9]);
|
|
});
|
|
|
|
async function testValue(setting: SCSetting, value: any) {
|
|
let error: Error;
|
|
await settingsProvider.provideSetting(JSON.parse(JSON.stringify(setting)));
|
|
try {
|
|
await settingsProvider.setSettingValue(setting.categories[0], setting.name, value);
|
|
} catch (err) {
|
|
error = err;
|
|
}
|
|
// @ts-ignore
|
|
await expect(error).toBeDefined();
|
|
// @ts-ignore
|
|
await expect(error.message).toMatch(/is not valid/);
|
|
}
|
|
|
|
const CONFIG_SETTINGS_MOCK: SCSetting[] = [
|
|
{
|
|
categories: ['credentials'],
|
|
defaultValue: '',
|
|
inputType: SCSettingInputType.Text,
|
|
name: 'username',
|
|
order: 0,
|
|
origin: {
|
|
indexed: '2018-09-11T12:30:00Z',
|
|
name: 'Dummy',
|
|
type: SCThingOriginType.Remote,
|
|
},
|
|
translations: {
|
|
de: {
|
|
categories: ['Anmeldedaten'],
|
|
name: 'Benutzername',
|
|
},
|
|
en: {
|
|
categories: ['Credentials'],
|
|
name: 'Username',
|
|
},
|
|
},
|
|
type: SCThingType.Setting,
|
|
uid: '',
|
|
},
|
|
{
|
|
categories: ['credentials'],
|
|
description: '',
|
|
defaultValue: '',
|
|
inputType: SCSettingInputType.Password,
|
|
name: 'password',
|
|
order: 1,
|
|
origin: {
|
|
indexed: '2018-09-11T12:30:00Z',
|
|
name: 'Dummy',
|
|
type: SCThingOriginType.Remote,
|
|
},
|
|
translations: {
|
|
de: {
|
|
categories: ['Anmeldedaten'],
|
|
name: 'Passwort',
|
|
},
|
|
en: {
|
|
categories: ['Credentials'],
|
|
name: 'Password',
|
|
},
|
|
},
|
|
type: SCThingType.Setting,
|
|
uid: '',
|
|
},
|
|
{
|
|
categories: ['profile'],
|
|
description: '',
|
|
defaultValue: 0,
|
|
inputType: SCSettingInputType.Number,
|
|
name: 'age',
|
|
order: 0,
|
|
origin: {
|
|
indexed: '2018-09-11T12:30:00Z',
|
|
name: 'Dummy',
|
|
type: SCThingOriginType.Remote,
|
|
},
|
|
translations: {
|
|
de: {
|
|
categories: ['Profil'],
|
|
name: 'Alter',
|
|
},
|
|
en: {
|
|
categories: ['Profile'],
|
|
name: 'Age',
|
|
},
|
|
},
|
|
type: SCThingType.Setting,
|
|
uid: '',
|
|
},
|
|
{
|
|
categories: ['profile'],
|
|
description: '',
|
|
defaultValue: 'student',
|
|
inputType: SCSettingInputType.SingleChoice,
|
|
name: 'group',
|
|
order: 1,
|
|
origin: {
|
|
indexed: '2018-09-11T12:30:00Z',
|
|
name: 'Dummy',
|
|
type: SCThingOriginType.Remote,
|
|
},
|
|
translations: {
|
|
de: {
|
|
categories: ['Benutzer'],
|
|
description: 'Mit welcher Benutzergruppe soll die App verwendet werden?'
|
|
+ ' Die Einstellung wird beispielsweise für die Vorauswahl der Preiskategorie der Mensa verwendet.',
|
|
name: 'Gruppe',
|
|
},
|
|
en: {
|
|
categories: ['User'],
|
|
description: 'The user group the app is going to be used.'
|
|
+ 'This settings for example is getting used for the predefined price category of mensa meals.',
|
|
name: 'Group',
|
|
},
|
|
},
|
|
type: SCThingType.Setting,
|
|
uid: '',
|
|
values: ['student', 'employee', 'guest'],
|
|
},
|
|
{
|
|
categories: ['profile'],
|
|
description: '',
|
|
defaultValue: 'en',
|
|
inputType: SCSettingInputType.SingleChoice,
|
|
name: 'language',
|
|
order: 0,
|
|
origin: {
|
|
indexed: '2018-09-11T12:30:00Z',
|
|
name: 'Dummy',
|
|
type: SCThingOriginType.Remote,
|
|
},
|
|
translations: {
|
|
de: {
|
|
categories: ['Benutzer'],
|
|
description: 'Die Sprache in der die App angezeigt werden soll',
|
|
name: 'Sprache',
|
|
},
|
|
en: {
|
|
categories: ['User'],
|
|
description: 'The language this app is going to use',
|
|
name: 'Language',
|
|
},
|
|
},
|
|
type: SCThingType.Setting,
|
|
uid: '',
|
|
values: ['en', 'de'],
|
|
},
|
|
{
|
|
categories: ['privacy'],
|
|
description: '',
|
|
defaultValue: false,
|
|
inputType: SCSettingInputType.SingleChoice,
|
|
name: 'geoLocation',
|
|
order: 0,
|
|
origin: {
|
|
indexed: '2018-09-11T12:30:00Z',
|
|
name: 'Dummy',
|
|
type: SCThingOriginType.Remote,
|
|
},
|
|
translations: {
|
|
de: {
|
|
categories: ['Privatsphäre'],
|
|
description: 'Berechtigung für die Verwendung des Ortungsdienstes, für die Anzeige der aktuellen ' +
|
|
'Position \'\n auf der Karte und zur Berechnung der Entfernung zu Gebäuden und Orten des Campus',
|
|
name: 'Position',
|
|
},
|
|
en: {
|
|
categories: ['Privacy'],
|
|
description: 'Allow the App to use the device location to provide additional informationsbased ' +
|
|
'on your actual location',
|
|
name: 'Position',
|
|
},
|
|
},
|
|
type: SCThingType.Setting,
|
|
uid: '',
|
|
values: [true, false],
|
|
},
|
|
{
|
|
categories: ['others'],
|
|
description: '',
|
|
defaultValue: [],
|
|
inputType: SCSettingInputType.MultipleChoice,
|
|
name: 'numbers',
|
|
order: 0,
|
|
origin: {
|
|
indexed: '2018-09-11T12:30:00Z',
|
|
name: 'Dummy',
|
|
type: SCThingOriginType.Remote,
|
|
},
|
|
translations: {
|
|
de: {
|
|
categories: ['Sonstiges'],
|
|
description: 'Test für multiple select Feld',
|
|
name: 'Nummern',
|
|
},
|
|
en: {
|
|
categories: ['Others'],
|
|
description: 'Test for multiple select field',
|
|
name: 'Numbers',
|
|
},
|
|
},
|
|
type: SCThingType.Setting,
|
|
uid: '',
|
|
values: [1, 2, 3, 4, 5, 6, 7, 8],
|
|
},
|
|
];
|
|
});
|
|
|
|
const SETTING_VALUES_MOCK: SettingValuesContainer = {
|
|
foo: {
|
|
bar: 'foo-bar',
|
|
},
|
|
privacy: {
|
|
geoLocation: 'true',
|
|
},
|
|
profile: {
|
|
group: 'employee',
|
|
language: 'de',
|
|
},
|
|
};
|