mirror of
https://gitlab.com/openstapps/openstapps.git
synced 2026-01-20 08:33:11 +00:00
feat: add the app
This commit is contained in:
27
src/app/modules/storage/storage.module.ts
Normal file
27
src/app/modules/storage/storage.module.ts
Normal file
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
* Copyright (C) 2018 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 { NgModule } from '@angular/core';
|
||||
import { IonicStorageModule } from '@ionic/storage';
|
||||
import { StorageProvider } from './storage.provider';
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
IonicStorageModule.forRoot()
|
||||
],
|
||||
providers: [
|
||||
StorageProvider
|
||||
]
|
||||
})
|
||||
export class StorageModule {}
|
||||
156
src/app/modules/storage/storage.provider.spec.ts
Normal file
156
src/app/modules/storage/storage.provider.spec.ts
Normal file
@@ -0,0 +1,156 @@
|
||||
/*
|
||||
* Copyright (C) 2018 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 {Storage} from '@ionic/storage';
|
||||
import {StorageModule} from './storage.module';
|
||||
import {StorageProvider} from './storage.provider';
|
||||
|
||||
describe('StorageProvider', () => {
|
||||
let storageProvider: StorageProvider;
|
||||
let storage: Storage;
|
||||
|
||||
const sampleEntries: Map<string, any> = new Map([
|
||||
['foo', 'Bar'],
|
||||
['bar', {foo: 'BarFoo'} as any],
|
||||
['foobar', 123],
|
||||
]);
|
||||
|
||||
beforeEach(async () => {
|
||||
TestBed.configureTestingModule({
|
||||
imports: [StorageModule],
|
||||
providers: [
|
||||
StorageProvider,
|
||||
// { provide: Storage, useClass: StorageMock }
|
||||
],
|
||||
});
|
||||
storageProvider = TestBed.get(StorageProvider);
|
||||
storage = TestBed.get(Storage);
|
||||
await storage.clear();
|
||||
});
|
||||
|
||||
it('should call ready method of storage on init', () => {
|
||||
spyOn(storage, 'ready');
|
||||
storageProvider.init();
|
||||
expect(storage.ready).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should call set method of storage to put a value', () => {
|
||||
spyOn(storage, 'set');
|
||||
storageProvider.put('some-uid', { some: 'thing' });
|
||||
expect(storage.set).toHaveBeenCalledWith('some-uid', { some: 'thing' });
|
||||
});
|
||||
|
||||
it('should call get method of storage to get a value', () => {
|
||||
spyOn(storage, 'get');
|
||||
storageProvider.get<any>('some-uid');
|
||||
expect(storage.get).toHaveBeenCalledWith('some-uid');
|
||||
});
|
||||
|
||||
it('should properly put and get a value', async () => {
|
||||
await storageProvider.init();
|
||||
await storageProvider.put('some-uid', {some: 'thing'});
|
||||
const result: Map<string, object> = await storageProvider.get<Map<string, object>>('some-uid');
|
||||
expect(result).toEqual({some: 'thing'});
|
||||
});
|
||||
|
||||
it('should throw an error when value is null', async () => {
|
||||
let error: Error = new Error();
|
||||
spyOn(storage, 'get').and.returnValue(Promise.resolve(null));
|
||||
try {
|
||||
await storageProvider.get('something-else');
|
||||
} catch (err) {
|
||||
error = err;
|
||||
}
|
||||
expect(error).toEqual(new Error('Value not found.'));
|
||||
});
|
||||
|
||||
it('should put multiple values into the storage', async () => {
|
||||
spyOn(storageProvider, 'put');
|
||||
await storageProvider.putMultiple(sampleEntries);
|
||||
expect((storageProvider.put as jasmine.Spy).calls.count()).toEqual(3);
|
||||
expect(storageProvider.put).toHaveBeenCalledWith('foo', 'Bar');
|
||||
expect(storageProvider.put).toHaveBeenCalledWith('bar', {foo: 'BarFoo'});
|
||||
});
|
||||
|
||||
it('should get multiple values from the storage', async () => {
|
||||
spyOn(storageProvider, 'get').and.callThrough();
|
||||
await storageProvider.putMultiple(sampleEntries);
|
||||
const entries = await storageProvider.getMultiple(['foo', 'bar']);
|
||||
expect((storageProvider.get as jasmine.Spy).calls.count()).toEqual(2);
|
||||
expect(storageProvider.get).toHaveBeenCalledWith('foo');
|
||||
expect(storageProvider.get).toHaveBeenCalledWith('bar');
|
||||
expect(Array.from(entries.values())).toEqual(['Bar', {foo: 'BarFoo'}]);
|
||||
expect(Array.from(entries.keys())).toEqual(['foo', 'bar']);
|
||||
});
|
||||
|
||||
it('should get all values from the storage', async () => {
|
||||
spyOn(storageProvider, 'get').and.callThrough();
|
||||
await storageProvider.putMultiple(sampleEntries);
|
||||
const entries = await storageProvider.getAll();
|
||||
expect(Array.from(entries.values()).map((item) => (item.foo) ? item.foo : item).sort())
|
||||
.toEqual(Array.from(sampleEntries.values()).map((item) => (item.foo) ? item.foo : item).sort());
|
||||
expect(Array.from(entries.keys()).sort()).toEqual(['bar', 'foo', 'foobar']);
|
||||
});
|
||||
|
||||
it('should delete one entry', async () => {
|
||||
spyOn(storage, 'remove').and.callThrough();
|
||||
await storageProvider.putMultiple(sampleEntries);
|
||||
let entries = await storageProvider.getAll();
|
||||
expect(Array.from(entries.values()).length).toBe(3);
|
||||
await storageProvider.delete('bar');
|
||||
|
||||
expect(storage.remove).toHaveBeenCalled();
|
||||
entries = await storageProvider.getAll();
|
||||
expect(Array.from(entries.values())).toEqual(['Bar', 123]);
|
||||
});
|
||||
|
||||
it('should delete all entries in the storage', async () => {
|
||||
spyOn(storage, 'clear').and.callThrough();
|
||||
await storageProvider.putMultiple(sampleEntries);
|
||||
let entries = await storageProvider.getAll();
|
||||
expect(Array.from(entries.values()).length).toBe(3);
|
||||
await storageProvider.deleteAll();
|
||||
|
||||
entries = await storageProvider.getAll();
|
||||
expect(storage.clear).toHaveBeenCalled();
|
||||
expect(Array.from(entries.values()).length).toBe(0);
|
||||
});
|
||||
|
||||
it('should provide number of entries', async () => {
|
||||
spyOn(storage, 'length').and.callThrough();
|
||||
|
||||
expect(await storageProvider.length()).toBe(0);
|
||||
expect(storage.length).toHaveBeenCalled();
|
||||
|
||||
await storageProvider.putMultiple(sampleEntries);
|
||||
expect(await storageProvider.length()).toBe(3);
|
||||
});
|
||||
|
||||
it('should provide information if storage is empty', async () => {
|
||||
spyOn(storage, 'length').and.callThrough();
|
||||
|
||||
expect(await storageProvider.isEmpty()).toBeTruthy();
|
||||
expect(storage.length).toHaveBeenCalled();
|
||||
|
||||
await storageProvider.putMultiple(sampleEntries);
|
||||
expect(await storageProvider.isEmpty()).toBeFalsy();
|
||||
});
|
||||
|
||||
it('should provide information if storage contains a specific entry (key)', async () => {
|
||||
spyOn(storage, 'keys').and.returnValue(Promise.resolve(Array.from(sampleEntries.keys())));
|
||||
expect(await storageProvider.has('foo')).toBeTruthy();
|
||||
expect(await storageProvider.has('something-else')).toBeFalsy();
|
||||
});
|
||||
});
|
||||
137
src/app/modules/storage/storage.provider.ts
Normal file
137
src/app/modules/storage/storage.provider.ts
Normal file
@@ -0,0 +1,137 @@
|
||||
/*
|
||||
* Copyright (C) 2018 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 {Injectable} from '@angular/core';
|
||||
import {Storage} from '@ionic/storage';
|
||||
|
||||
/**
|
||||
* Provides interaction with the (ionic) storage on the device (in the browser)
|
||||
*/
|
||||
@Injectable()
|
||||
export class StorageProvider {
|
||||
constructor(private storage: Storage) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the storage (waits until it's ready)
|
||||
*/
|
||||
async init(): Promise<any> {
|
||||
return this.storage.ready();
|
||||
}
|
||||
|
||||
/**
|
||||
* Puts a value of type T into the storage using provided key
|
||||
*
|
||||
* @param key Unique indentifier
|
||||
* @param value Resource to store under the key
|
||||
*/
|
||||
async put<T>(key: string, value: T): Promise<T> {
|
||||
return this.storage.set(key, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a value from the storage using the provided key
|
||||
*
|
||||
* @param key Unique identifier of the wanted resource in storage
|
||||
*/
|
||||
async get<T>(key: string): Promise<T> {
|
||||
const entry = await this.storage.get(key);
|
||||
if (!entry) {
|
||||
throw new Error('Value not found.');
|
||||
}
|
||||
return entry;
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes a storage entry using the key used to save it
|
||||
*
|
||||
* @param key Unique identifier of the resource
|
||||
*/
|
||||
async delete(key: string): Promise<void> {
|
||||
return this.storage.remove(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes all the entries in the storage (empty the storage)
|
||||
*/
|
||||
async deleteAll(): Promise<void> {
|
||||
return this.storage.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves multiple entries into the storage
|
||||
*
|
||||
* @param entries Resources to be put into the storage
|
||||
*/
|
||||
async putMultiple(entries: Map<string, any>): Promise<Map<string, any>> {
|
||||
const puts: Array<Promise<any>> = [];
|
||||
entries.forEach(async (value, key) => {
|
||||
puts.push(this.put(key, value));
|
||||
});
|
||||
await Promise.all(puts);
|
||||
return entries;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves multiple entries from the storage using their keys
|
||||
*
|
||||
* @param keys Unique identifiers of wanted resources from the storage
|
||||
*/
|
||||
async getMultiple(keys: string[]): Promise<Map<string, any>> {
|
||||
const gets: Array<Promise<any>> = [];
|
||||
const map = new Map();
|
||||
const getToMap = async (key: string) => {
|
||||
map.set(key, await this.get(key));
|
||||
}
|
||||
keys.forEach((key) => {
|
||||
gets.push(getToMap(key));
|
||||
});
|
||||
await Promise.all(gets);
|
||||
return map;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves all the storage entries
|
||||
*/
|
||||
async getAll(): Promise<Map<string, any>> {
|
||||
const map: Map<string, any> = new Map();
|
||||
await this.storage.forEach((value, key) => {
|
||||
map.set(key, value);
|
||||
});
|
||||
return map;
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides a number of entries in the storage (number of keys)
|
||||
*/
|
||||
async length(): Promise<number> {
|
||||
return this.storage.length();
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides information if storage is empty or not
|
||||
*/
|
||||
async isEmpty(): Promise<boolean> {
|
||||
return (await this.storage.length()) === 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides information if storage has an entry with the given key
|
||||
*
|
||||
* @param key Unique identifier of the resource in storage
|
||||
*/
|
||||
async has(key: string): Promise<boolean> {
|
||||
return (await this.storage.keys()).includes(key);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user