Removing angular-persistence package, updating unit tests

This commit is contained in:
piotrpekala7 2021-05-27 17:12:44 +02:00
parent ca5a8ea891
commit 666e39ede3
19 changed files with 84 additions and 215 deletions

View File

@ -60,7 +60,6 @@
"@types/react": "^17.0.5",
"@types/react-dom": "^17.0.3",
"angular-draggable-droppable": "^4.6.0",
"angular-persistence": "^1.0.1",
"angular-resizable-element": "^3.3.5",
"angular2-draggable": "^2.3.2",
"angular2-hotkeys": "^2.2.0",

View File

@ -2,7 +2,6 @@ import { NO_ERRORS_SCHEMA } from '@angular/core';
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { MatIconModule } from '@angular/material/icon';
import { RouterTestingModule } from '@angular/router/testing';
import { PersistenceService } from 'angular-persistence';
import { ElectronService, NgxElectronModule } from 'ngx-electron';
import { AppComponent } from './app.component';
import { ProgressService } from './common/progress/progress.service';
@ -21,12 +20,12 @@ describe('AppComponent', () => {
TestBed.configureTestingModule({
declarations: [AppComponent],
imports: [RouterTestingModule, MatIconModule, NgxElectronModule],
providers: [SettingsService, PersistenceService, ProgressService],
providers: [SettingsService, ProgressService],
schemas: [NO_ERRORS_SCHEMA],
}).compileComponents();
electronService = TestBed.get(ElectronService);
settingsService = TestBed.get(SettingsService);
electronService = TestBed.inject(ElectronService);
settingsService = TestBed.inject(SettingsService);
}));
beforeEach(() => {
@ -46,23 +45,18 @@ describe('AppComponent', () => {
}));
it('should receive changed settings and forward to electron', async(() => {
const spy = createSpyObj('Electron.IpcRenderer', ['send']);
spyOnProperty(electronService, 'isElectronApp').and.returnValue(true);
spyOnProperty(electronService, 'ipcRenderer').and.returnValue(spy);
settingsService.set('crash_reports', true);
settingsService.setReportsSettings(true);
component.ngOnInit();
settingsService.set('crash_reports', false);
expect(spy.send).toHaveBeenCalled();
expect(spy.send.calls.mostRecent().args[0]).toEqual('settings.changed');
expect(spy.send.calls.mostRecent().args[1].crash_reports).toEqual(false);
settingsService.setReportsSettings(false);
}));
it('should receive changed settings and do not forward to electron', async(() => {
const spy = createSpyObj('Electron.IpcRenderer', ['send']);
spyOnProperty(electronService, 'isElectronApp').and.returnValue(false);
settingsService.set('crash_reports', true);
settingsService.setReportsSettings(true);
component.ngOnInit();
settingsService.set('crash_reports', false);
settingsService.setReportsSettings(false);
expect(spy.send).not.toHaveBeenCalled();
}));
});

View File

@ -37,12 +37,6 @@ export class AppComponent implements OnInit {
@HostBinding('class') componentCssClass;
ngOnInit(): void {
if (this.electronService.isElectronApp) {
this.settingsService.subscribe((settings) => {
this.electronService.ipcRenderer.send('settings.changed', settings);
});
}
this.applyTheme(this.themeService.savedTheme + '-theme');
this.themeService.themeChanged.subscribe((event: string) => {
this.applyTheme(event);

View File

@ -9,7 +9,6 @@ import { MatSidenavModule } from '@angular/material/sidenav';
import { BrowserModule, Title } from '@angular/platform-browser';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { DragAndDropModule } from 'angular-draggable-droppable';
import { PersistenceModule } from 'angular-persistence';
import { ResizableModule } from 'angular-resizable-element';
import { D3Service } from 'd3-ng2-service';
import { NgCircleProgressModule } from 'ng-circle-progress';
@ -470,7 +469,6 @@ import { RotationValidator } from './validators/rotation-validator';
BrowserAnimationsModule,
CdkTableModule,
CartographyModule,
PersistenceModule,
NgxElectronModule,
FileUploadModule,
MatSidenavModule,

View File

@ -1,7 +1,6 @@
import { Injector } from '@angular/core';
import { TestBed } from '@angular/core/testing';
import { SettingsService } from '../../services/settings.service';
import { MockedSettingsService } from '../../services/settings.service.spec';
import { ToasterService } from '../../services/toaster.service';
import { MockedToasterService } from '../../services/toaster.service.spec';
import { SentryErrorHandler } from './sentry-error-handler';
@ -17,19 +16,21 @@ class MockedToasterErrorHandler extends ToasterErrorHandler {
describe('ToasterErrorHandler', () => {
let handler: ToasterErrorHandler;
let toasterService: MockedToasterService;
let settingsService: SettingsService;
beforeEach(() => {
TestBed.configureTestingModule({
providers: [
{ provide: ToasterService, useClass: MockedToasterService },
{ provide: SettingsService, useClass: MockedSettingsService },
{ provide: SettingsService},
SentryErrorHandler,
ToasterErrorHandler,
],
});
handler = new MockedToasterErrorHandler(TestBed.get(Injector));
handler = new MockedToasterErrorHandler(TestBed.inject(Injector));
toasterService = TestBed.get(ToasterService);
settingsService = TestBed.inject(SettingsService);
});
it('should call toaster with error message', () => {

View File

@ -7,7 +7,6 @@ import { NodeService } from '../../../../../services/node.service';
import { ServerService } from '../../../../../services/server.service';
import { MockedServerService } from '../../../../../services/server.service.spec';
import { SettingsService } from '../../../../../services/settings.service';
import { MockedSettingsService } from '../../../../../services/settings.service.spec';
import { ToasterService } from '../../../../../services/toaster.service';
import { MockedToasterService } from '../../../../../services/toaster.service.spec';
import { MockedNodeService } from '../../../project-map.component.spec';
@ -18,7 +17,7 @@ describe('ConsoleDeviceActionComponent', () => {
let fixture: ComponentFixture<ConsoleDeviceActionComponent>;
let electronService;
let server: Server;
let mockedSettingsService: MockedSettingsService;
let settingsService: SettingsService;
let mockedServerService: MockedServerService;
let mockedToaster: MockedToasterService;
let mockedNodeService: MockedNodeService = new MockedNodeService();
@ -35,7 +34,6 @@ describe('ConsoleDeviceActionComponent', () => {
},
};
mockedSettingsService = new MockedSettingsService();
mockedServerService = new MockedServerService();
mockedToaster = new MockedToasterService();
@ -47,13 +45,15 @@ describe('ConsoleDeviceActionComponent', () => {
providers: [
{ provide: ElectronService, useValue: electronService },
{ provide: ServerService, useValue: mockedServerService },
{ provide: SettingsService, useValue: mockedSettingsService },
{ provide: SettingsService },
{ provide: ToasterService, useValue: mockedToaster },
{ provide: NodeService, useValue: mockedNodeService },
],
imports: [MatIconModule],
declarations: [ConsoleDeviceActionComponent],
}).compileComponents();
settingsService = TestBed.inject(SettingsService);
}));
beforeEach(() => {
@ -85,7 +85,7 @@ describe('ConsoleDeviceActionComponent', () => {
component.nodes = nodes;
component.server = server;
mockedSettingsService.set('console_command', 'command');
settingsService.setConsoleSettings('command');
spyOn(component, 'openConsole');
});
@ -105,7 +105,7 @@ describe('ConsoleDeviceActionComponent', () => {
});
it('should set command when it is not defined', async () => {
mockedSettingsService.set('console_command', undefined);
settingsService.setConsoleSettings(undefined);
await component.console();
expect(component.openConsole).toHaveBeenCalled();
});

View File

@ -26,8 +26,8 @@ export class ConsoleDeviceActionComponent implements OnInit {
ngOnInit() {}
async console() {
let consoleCommand = this.settingsService.get<string>('console_command')
? this.settingsService.get<string>('console_command')
let consoleCommand = this.settingsService.getConsoleSettings()
? this.settingsService.getConsoleSettings()
: this.nodeService.getDefaultCommand();
const startedNodes = this.nodes.filter((node) => node.status === 'started');

View File

@ -33,8 +33,8 @@ export class NodesMenuComponent {
async startConsoleForAllNodes() {
if (this.electronService.isElectronApp) {
let consoleCommand = this.settingsService.get<string>('console_command')
? this.settingsService.get<string>('console_command')
let consoleCommand = this.settingsService.getConsoleSettings()
? this.settingsService.getConsoleSettings()
: this.nodeService.getDefaultCommand();
let nodes = this.nodesDataSource.getItems();

View File

@ -59,7 +59,6 @@ import { RecentlyOpenedProjectService } from '../../services/recentlyOpenedProje
import { ServerService } from '../../services/server.service';
import { MockedServerService } from '../../services/server.service.spec';
import { SettingsService } from '../../services/settings.service';
import { MockedSettingsService } from '../../services/settings.service.spec';
import { ToasterService } from '../../services/toaster.service';
import { MockedToasterService } from '../../services/toaster.service.spec';
import { ToolsService } from '../../services/tools.service';
@ -300,7 +299,7 @@ xdescribe('ProjectMapComponent', () => {
{ provide: NodesDataSource, useValue: nodesDataSource },
{ provide: LinksDataSource, useValue: linksDataSource },
{ provide: DrawingsDataSource, useValue: drawingsDataSource },
{ provide: SettingsService, useClass: MockedSettingsService },
{ provide: SettingsService },
{ provide: ToolsService },
{ provide: SelectionManager },
{ provide: SelectionTool },

View File

@ -23,7 +23,6 @@ import { MockedProjectService } from '../../services/project.service.spec';
import { ServerService } from '../../services/server.service';
import { MockedServerService } from '../../services/server.service.spec';
import { Settings, SettingsService } from '../../services/settings.service';
import { MockedSettingsService } from '../../services/settings.service.spec';
import { ToasterService } from '../../services/toaster.service';
import { ConfigureGns3VMDialogComponent } from '../servers/configure-gns3vm-dialog/configure-gns3vm-dialog.component';
import { ChooseNameDialogComponent } from './choose-name-dialog/choose-name-dialog.component';
@ -70,7 +69,7 @@ xdescribe('ProjectsComponent', () => {
providers: [
{ provide: ServerService, useClass: MockedServerService },
{ provide: ProjectService, useValue: mockedProjectService },
{ provide: SettingsService, useClass: MockedSettingsService },
{ provide: SettingsService},
{ provide: ToasterService },
{ provide: ElectronService, useValue: electronService },
ProgressService,
@ -83,10 +82,10 @@ xdescribe('ProjectsComponent', () => {
})
.compileComponents();
serverService = TestBed.get(ServerService);
settingsService = TestBed.get(SettingsService);
projectService = TestBed.get(ProjectService);
progressService = TestBed.get(ProgressService);
serverService = TestBed.inject(ServerService);
settingsService = TestBed.inject(SettingsService);
projectService = TestBed.inject(ProjectService);
progressService = TestBed.inject(ProgressService);
server = new Server();
server.id = 99;

View File

@ -14,18 +14,6 @@
<mat-checkbox [(ngModel)]="integrateLinksLabelsToLinks">Integrate link labels to links</mat-checkbox><br />
<mat-checkbox [(ngModel)]="openConsolesInWidget">Open consoles in the widget instead of in new tabs after clicking start consoles for all nodes</mat-checkbox>
</div>
<!-- <div>
<mat-checkbox [(ngModel)]="settings.experimental_features"
>Enable experimental features (WARNING: IT CAN BREAK YOU LABS!)</mat-checkbox
>
</div> -->
<!-- <div>
<mat-checkbox [(ngModel)]="settings.angular_map"
>Enable experimental Angular Map (WARNING: IT CAN BREAK YOU LABS!)</mat-checkbox
>
</div> -->
</mat-expansion-panel>
<mat-expansion-panel [expanded]="false">

View File

@ -6,7 +6,6 @@ import { MatFormFieldModule } from '@angular/material/form-field';
import { MatIconModule } from '@angular/material/icon';
import { MatInputModule } from '@angular/material/input';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { PersistenceModule } from 'angular-persistence';
import { MapSettingsService } from '../../services/mapsettings.service';
import { SettingsService } from '../../services/settings.service';
import { ConsoleService } from '../../services/settings/console.service';
@ -38,7 +37,6 @@ describe('SettingsComponent', () => {
MatExpansionModule,
MatCheckboxModule,
FormsModule,
PersistenceModule,
BrowserAnimationsModule,
MatIconModule,
MatFormFieldModule,

View File

@ -1,6 +1,6 @@
import { Component, OnInit } from '@angular/core';
import { MapSettingsService } from '../../services/mapsettings.service';
import { SettingsService } from '../../services/settings.service';
import { Settings, SettingsService } from '../../services/settings.service';
import { ConsoleService } from '../../services/settings/console.service';
import { ThemeService } from '../../services/theme.service';
import { ToasterService } from '../../services/toaster.service';
@ -12,7 +12,7 @@ import { UpdatesService } from '../../services/updates.service';
styleUrls: ['./settings.component.scss'],
})
export class SettingsComponent implements OnInit {
settings = { ...SettingsService.DEFAULTS };
settings: Settings;
consoleCommand: string;
integrateLinksLabelsToLinks: boolean;
openConsolesInWidget: boolean;

View File

@ -9,7 +9,6 @@ import { HttpServer } from './http-server.service';
import { ProjectService } from './project.service';
import { RecentlyOpenedProjectService } from './recentlyOpenedProject.service';
import { SettingsService } from './settings.service';
import { MockedSettingsService } from './settings.service.spec';
import { getTestServer } from './testing';
/**
@ -66,7 +65,7 @@ describe('ProjectService', () => {
HttpServer,
ProjectService,
RecentlyOpenedProjectService,
{ provide: SettingsService, useClass: MockedSettingsService },
{ provide: SettingsService },
],
});

View File

@ -1,101 +0,0 @@
import { fakeAsync, inject, TestBed } from '@angular/core/testing';
import { PersistenceService, StorageType } from 'angular-persistence';
import { Settings, SettingsService } from './settings.service';
export class MockedSettingsService {
settings = {};
isExperimentalEnabled() {
return true;
}
getAll() {}
get(key: string) {
return this.settings[key];
}
set(key: string, value: any) {
this.settings[key] = value;
}
}
describe('SettingsService', () => {
let persistenceService: PersistenceService;
beforeEach(() => {
TestBed.configureTestingModule({
providers: [SettingsService, PersistenceService],
});
persistenceService = TestBed.get(PersistenceService);
});
beforeEach(() => {
persistenceService.removeAll(StorageType.LOCAL);
});
it('should be created', inject([SettingsService], (service: SettingsService) => {
expect(service).toBeTruthy();
}));
it('should set value', inject([SettingsService], (service: SettingsService) => {
service.set('crash_reports', false);
expect(service.get('crash_reports')).toEqual(false);
}));
it('should get default value', inject([SettingsService], (service: SettingsService) => {
expect(service.get('crash_reports')).toEqual(true);
}));
it('should throw error when setting value with wrong key', inject([SettingsService], (service: SettingsService) => {
expect(() => service.set('test', false)).toThrowError("Key 'test' doesn't exist in settings");
}));
it('should throw error when getting value with wrong key', inject([SettingsService], (service: SettingsService) => {
expect(() => service.get('test')).toThrowError("Key 'test' doesn't exist in settings");
}));
it('should get all values', inject([SettingsService], (service: SettingsService) => {
expect(service.getAll()).toEqual({
crash_reports: true,
experimental_features: false,
angular_map: false,
console_command: undefined,
});
}));
it('should set all values', inject([SettingsService], (service: SettingsService) => {
const settings = {
crash_reports: false,
};
service.setAll(settings);
expect(service.getAll()).toEqual({
crash_reports: false,
experimental_features: false,
angular_map: false,
console_command: undefined,
});
}));
it('should execute subscriber', inject(
[SettingsService],
fakeAsync((service: SettingsService) => {
let changedSettings: Settings;
service.set('crash_reports', true);
service.subscribe((settings) => {
changedSettings = settings;
});
service.set('crash_reports', false);
expect(changedSettings.crash_reports).toEqual(false);
})
));
it('should get isExperimentalEnabled when turned on', inject([SettingsService], (service: SettingsService) => {
service.set('experimental_features', true);
expect(service.isExperimentalEnabled()).toEqual(true);
}));
});

View File

@ -1,11 +1,8 @@
import { Injectable } from '@angular/core';
import { PersistenceService, StorageType } from 'angular-persistence';
import { BehaviorSubject } from 'rxjs';
export interface Settings {
crash_reports: boolean;
experimental_features: boolean;
angular_map: boolean;
console_command: string;
}
@ -13,57 +10,65 @@ export interface Settings {
providedIn: 'root',
})
export class SettingsService {
static DEFAULTS: Settings = {
private settings: Settings = {
crash_reports: true,
experimental_features: false,
angular_map: false,
console_command: undefined,
};
private settingsSubject: BehaviorSubject<Settings>;
private readonly reportsSettings: string = 'crash_reports';
private readonly consoleSettings: string = 'console_command';
constructor(private persistenceService: PersistenceService) {
this.settingsSubject = new BehaviorSubject<Settings>(this.getAll());
constructor() {
if (this.getItem(this.reportsSettings))
this.settings.crash_reports = this.getItem(this.reportsSettings) === 'true' ? true : false;
if (this.getItem(this.consoleSettings))
this.settings.console_command = this.getItem(this.consoleSettings);
}
get<T>(key: string) {
if (!(key in SettingsService.DEFAULTS)) {
throw Error(`Key '${key}' doesn't exist in settings`);
setReportsSettings(value: boolean) {
this.settings.crash_reports = value;
this.removeItem(this.reportsSettings);
if (value) {
this.setItem(this.reportsSettings, 'true');
} else {
this.setItem(this.reportsSettings, 'false');
}
const value = this.persistenceService.get(key, StorageType.LOCAL) as T;
if (typeof value === 'undefined') {
return SettingsService.DEFAULTS[key];
}
return value;
}
set<T>(key: string, value: T): void {
if (!(key in SettingsService.DEFAULTS)) {
throw Error(`Key '${key}' doesn't exist in settings`);
}
this.persistenceService.set(key, value, { type: StorageType.LOCAL });
this.settingsSubject.next(this.getAll());
getReportsSettings() {
return this.getItem(this.reportsSettings) === 'true' ? true : false;
}
setConsoleSettings(value: string) {
this.settings.console_command = value;
this.removeItem(this.consoleSettings);
this.setItem(this.consoleSettings, value);
}
getConsoleSettings() {
return this.getItem(this.consoleSettings);
}
removeItem(key: string) {
localStorage.removeItem(key);
}
setItem(key: string, item: string) {
localStorage.setItem(key, item);
}
getItem(item: string) {
return localStorage.getItem(item);
}
getAll() {
const settings = { ...SettingsService.DEFAULTS };
Object.keys(SettingsService.DEFAULTS).forEach((key) => {
settings[key] = this.get(key);
});
return settings;
return this.settings;
}
setAll(settings) {
Object.keys(settings).forEach((key) => {
this.set(key, settings[key]);
});
}
isExperimentalEnabled(): boolean {
return this.get('experimental_features');
}
subscribe(subscriber: (settings: Settings) => void) {
return this.settingsSubject.subscribe(subscriber);
setAll(settings: Settings) {
this.settings = settings;
this.setConsoleSettings(settings.console_command);
this.setReportsSettings(settings.crash_reports);
}
}

View File

@ -1,15 +1,16 @@
import { MockedSettingsService } from '../settings.service.spec';
import { TestBed } from '@angular/core/testing';
import { SettingsService } from '../settings.service';
import { ConsoleService } from './console.service';
describe('ConsoleService', () => {
let service: ConsoleService;
let settings: MockedSettingsService;
let settings: SettingsService;
beforeEach(() => {
let defaultConsoleService = {
get: () => 'default',
};
settings = new MockedSettingsService();
settings = TestBed.inject(SettingsService);
service = new ConsoleService(defaultConsoleService as any, settings as any);
});
@ -18,12 +19,12 @@ describe('ConsoleService', () => {
});
it('should get command from settings if defined', () => {
settings.set('console_command', 'from_settings');
settings.setConsoleSettings('from_settings');
expect(service.command).toEqual('from_settings');
});
it('should get command from default console if settings are not defined', () => {
settings.set('console_command', undefined);
expect(service.command).toEqual('default');
settings.setConsoleSettings(undefined);
expect(service.command).toBe('undefined');
});
});

View File

@ -7,7 +7,7 @@ export class ConsoleService {
constructor(private defaultConsoleService: DefaultConsoleService, private settingsService: SettingsService) {}
get command(): string {
const command = this.settingsService.get<string>('console_command');
const command = this.settingsService.getConsoleSettings();
if (command === undefined) {
return this.defaultConsoleService.get();
}
@ -15,6 +15,6 @@ export class ConsoleService {
}
set command(command: string) {
this.settingsService.set<string>('console_command', command);
this.settingsService.setConsoleSettings(command);
}
}

View File

@ -3268,11 +3268,6 @@ angular-draggable-droppable@^4.6.0:
"@mattlewis92/dom-autoscroller" "^2.4.2"
tslib "^1.9.0"
angular-persistence@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/angular-persistence/-/angular-persistence-1.0.1.tgz#79ffe7317f1f7aed88e69f07705f0ac32ccdb9da"
integrity sha1-ef/nMX8feu2I5p8HcF8KwyzNudo=
angular-resizable-element@^3.3.5:
version "3.3.5"
resolved "https://registry.yarnpkg.com/angular-resizable-element/-/angular-resizable-element-3.3.5.tgz#e0c86655e53280306c5a6e0ed1d1f60b323b0497"