From 646718e2e07df15f5b73b79461dfb21cd6952683 Mon Sep 17 00:00:00 2001 From: Simon Date: Tue, 30 May 2023 14:02:00 +0200 Subject: [PATCH 1/7] refactor: moved app initialisation steps to APP_INITIALIZER --- src/app/app.component.ts | 75 +--------------------- src/app/app.module.ts | 73 ++++++++++++++++++++- src/app/core/demo-data/demo-data.module.ts | 8 ++- 3 files changed, 79 insertions(+), 77 deletions(-) diff --git a/src/app/app.component.ts b/src/app/app.component.ts index 340d76407c..f78b371f37 100644 --- a/src/app/app.component.ts +++ b/src/app/app.component.ts @@ -15,24 +15,7 @@ * along with ndb-core. If not, see . */ -import { - Component, - Injector, - ViewContainerRef, - ɵcreateInjector as createInjector, -} from "@angular/core"; -import { AnalyticsService } from "./core/analytics/analytics.service"; -import { ConfigService } from "./core/config/config.service"; -import { RouterService } from "./core/view/dynamic-routing/router.service"; -import { EntityConfigService } from "./core/entity/entity-config.service"; -import { SessionService } from "./core/session/session-service/session.service"; -import { ActivatedRoute, Router } from "@angular/router"; -import { environment } from "../environments/environment"; -import { Child } from "./child-dev-project/children/model/child"; -import { School } from "./child-dev-project/schools/model/school"; -import { LoginState } from "./core/session/session-states/login-state.enum"; -import { LoggingService } from "./core/logging/logging.service"; -import { EntityRegistry } from "./core/entity/database-entity.decorator"; +import { Component } from "@angular/core"; /** * Component as the main entry point for the app. @@ -42,58 +25,4 @@ import { EntityRegistry } from "./core/entity/database-entity.decorator"; selector: "app-root", template: "", }) -export class AppComponent { - constructor( - private viewContainerRef: ViewContainerRef, // need this small hack in order to catch application root view container ref - private analyticsService: AnalyticsService, - private configService: ConfigService, - private routerService: RouterService, - private entityConfigService: EntityConfigService, - private sessionService: SessionService, - private activatedRoute: ActivatedRoute, - private router: Router, - private entities: EntityRegistry, - private injector: Injector - ) { - this.initBasicServices(); - } - - private async initBasicServices() { - // TODO: remove this after issue #886 now in next release (keep as fallback for one version) - this.entities.add("Participant", Child); - this.entities.add("Team", School); - - // first register to events - - // Re-trigger services that depend on the config when something changes - this.configService.configUpdates.subscribe(() => { - this.routerService.initRouting(); - this.entityConfigService.setupEntitiesFromConfig(); - this.router.navigate([], { - relativeTo: this.activatedRoute, - queryParamsHandling: "preserve", - }); - }); - - // update the user context for remote error logging and tracking and load config initially - this.sessionService.loginState.subscribe((newState) => { - if (newState === LoginState.LOGGED_IN) { - const username = this.sessionService.getCurrentUser().name; - LoggingService.setLoggingContextUser(username); - this.analyticsService.setUser(username); - } else { - LoggingService.setLoggingContextUser(undefined); - this.analyticsService.setUser(undefined); - } - }); - - if (environment.production) { - this.analyticsService.init(); - } - - if (environment.demo_mode) { - const m = await import("./core/demo-data/demo-data.module"); - createInjector(m.DemoDataModule, this.injector); - } - } -} +export class AppComponent {} diff --git a/src/app/app.module.ts b/src/app/app.module.ts index 3e871d9c96..49f9b5a406 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -17,7 +17,14 @@ import { BrowserModule } from "@angular/platform-browser"; import { BrowserAnimationsModule } from "@angular/platform-browser/animations"; -import { ErrorHandler, LOCALE_ID, NgModule } from "@angular/core"; +import { + APP_INITIALIZER, + ErrorHandler, + Injector, + LOCALE_ID, + NgModule, + ɵcreateInjector as createInjector, +} from "@angular/core"; import { HttpClientModule } from "@angular/common/http"; import { AppComponent } from "./app.component"; @@ -73,11 +80,15 @@ import { HistoricalDataModule } from "./features/historical-data/historical-data import { MatchingEntitiesModule } from "./features/matching-entities/matching-entities.module"; import { ProgressDashboardWidgetModule } from "./features/progress-dashboard-widget/progress-dashboard-widget.module"; import { ReportingModule } from "./features/reporting/reporting.module"; -import { RouterModule } from "@angular/router"; +import { ActivatedRoute, Router, RouterModule } from "@angular/router"; import { TodosModule } from "./features/todos/todos.module"; import { SessionService } from "./core/session/session-service/session.service"; import { waitForChangeTo } from "./core/session/session-states/session-utils"; import { LoginState } from "./core/session/session-states/login-state.enum"; +import { EntityConfigService } from "./core/entity/entity-config.service"; +import { ConfigService } from "./core/config/config.service"; +import { LoggingService } from "./core/logging/logging.service"; +import { RouterService } from "./core/view/dynamic-routing/router.service"; /** * Main entry point of the application. @@ -154,6 +165,64 @@ import { LoginState } from "./core/session/session-states/login-state.enum"; }), deps: [SessionService], }, + { + provide: APP_INITIALIZER, + useFactory: + ( + injector: Injector, + configService: ConfigService, + routerService: RouterService, + entityConfigService: EntityConfigService, + router: Router, + sessionService: SessionService, + analyticsService: AnalyticsService, + activatedRoute: ActivatedRoute + ) => + async () => { + // Re-trigger services that depend on the config when something changes + configService.configUpdates.subscribe(() => { + routerService.initRouting(); + entityConfigService.setupEntitiesFromConfig(); + router.navigate([], { + relativeTo: activatedRoute, + queryParamsHandling: "preserve", + }); + }); + + // update the user context for remote error logging and tracking and load config initially + sessionService.loginState.subscribe((newState) => { + if (newState === LoginState.LOGGED_IN) { + const username = sessionService.getCurrentUser().name; + LoggingService.setLoggingContextUser(username); + analyticsService.setUser(username); + } else { + LoggingService.setLoggingContextUser(undefined); + analyticsService.setUser(undefined); + } + }); + + if (environment.production) { + analyticsService.init(); + } + if (environment.demo_mode) { + const m = await import("./core/demo-data/demo-data.module"); + await createInjector(m.DemoDataModule, injector) + .get(m.DemoDataModule) + .publishDemoData(); + } + }, + deps: [ + Injector, + ConfigService, + RouterService, + EntityConfigService, + Router, + SessionService, + AnalyticsService, + ActivatedRoute, + ], + multi: true, + }, ], bootstrap: [AppComponent], }) diff --git a/src/app/core/demo-data/demo-data.module.ts b/src/app/core/demo-data/demo-data.module.ts index 6a27664c86..be0a55c18a 100644 --- a/src/app/core/demo-data/demo-data.module.ts +++ b/src/app/core/demo-data/demo-data.module.ts @@ -106,7 +106,11 @@ const demoDataGeneratorProviders = [ exports: [DemoDataGeneratingProgressDialogComponent], }) export class DemoDataModule { - constructor(demoDataInitializer: DemoDataInitializerService) { - demoDataInitializer.run(); + constructor(private demoDataInitializer: DemoDataInitializerService) {} + + publishDemoData() { + return this.demoDataInitializer + .run() + .then(() => console.log("demo data initialised")); } } From f45e6e984c18988ce776b7f5761461093e0b11a0 Mon Sep 17 00:00:00 2001 From: Simon Date: Tue, 30 May 2023 14:02:13 +0200 Subject: [PATCH 2/7] fix: demo config is generated first --- src/app/core/demo-data/demo-data.module.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/app/core/demo-data/demo-data.module.ts b/src/app/core/demo-data/demo-data.module.ts index be0a55c18a..cce2d1d069 100644 --- a/src/app/core/demo-data/demo-data.module.ts +++ b/src/app/core/demo-data/demo-data.module.ts @@ -40,6 +40,7 @@ import { DemoConfigurableEnumGeneratorService } from "../configurable-enum/demo- import { DemoPublicFormGeneratorService } from "../../features/public-form/demo-public-form-generator.service"; const demoDataGeneratorProviders = [ + ...DemoConfigGeneratorService.provider(), ...DemoPermissionGeneratorService.provider(), ...DemoPublicFormGeneratorService.provider(), ...DemoUserGeneratorService.provider(), @@ -66,8 +67,6 @@ const demoDataGeneratorProviders = [ maxCountAttributes: 5, }), ...DemoTodoGeneratorService.provider(), - // keep Demo service last to ensure all entities are already initialized - ...DemoConfigGeneratorService.provider(), ]; /** From 4c41da3b9050b712e962a7d5ba2a4b4387565178 Mon Sep 17 00:00:00 2001 From: Simon Date: Tue, 30 May 2023 15:01:43 +0200 Subject: [PATCH 3/7] cleaned up app module --- src/app/app-initializers.ts | 73 ++++++++++++++++++++++++++++++++++++ src/app/app.module.ts | 75 ++----------------------------------- 2 files changed, 77 insertions(+), 71 deletions(-) create mode 100644 src/app/app-initializers.ts diff --git a/src/app/app-initializers.ts b/src/app/app-initializers.ts new file mode 100644 index 0000000000..1c99e39de5 --- /dev/null +++ b/src/app/app-initializers.ts @@ -0,0 +1,73 @@ +import { + APP_INITIALIZER, + Injector, + ɵcreateInjector as createInjector, +} from "@angular/core"; +import { ConfigService } from "./core/config/config.service"; +import { RouterService } from "./core/view/dynamic-routing/router.service"; +import { EntityConfigService } from "./core/entity/entity-config.service"; +import { ActivatedRoute, Router } from "@angular/router"; +import { SessionService } from "./core/session/session-service/session.service"; +import { AnalyticsService } from "./core/analytics/analytics.service"; +import { LoginState } from "./core/session/session-states/login-state.enum"; +import { LoggingService } from "./core/logging/logging.service"; +import { environment } from "../environments/environment"; + +export const appInitializers = { + provide: APP_INITIALIZER, + useFactory: + ( + injector: Injector, + configService: ConfigService, + routerService: RouterService, + entityConfigService: EntityConfigService, + router: Router, + sessionService: SessionService, + analyticsService: AnalyticsService, + activatedRoute: ActivatedRoute + ) => + async () => { + // Re-trigger services that depend on the config when something changes + configService.configUpdates.subscribe(() => { + routerService.initRouting(); + entityConfigService.setupEntitiesFromConfig(); + router.navigate([], { + relativeTo: activatedRoute, + queryParamsHandling: "preserve", + }); + }); + + // update the user context for remote error logging and tracking and load config initially + sessionService.loginState.subscribe((newState) => { + if (newState === LoginState.LOGGED_IN) { + const username = sessionService.getCurrentUser().name; + LoggingService.setLoggingContextUser(username); + analyticsService.setUser(username); + } else { + LoggingService.setLoggingContextUser(undefined); + analyticsService.setUser(undefined); + } + }); + + if (environment.production) { + analyticsService.init(); + } + if (environment.demo_mode) { + const m = await import("./core/demo-data/demo-data.module"); + await createInjector(m.DemoDataModule, injector) + .get(m.DemoDataModule) + .publishDemoData(); + } + }, + deps: [ + Injector, + ConfigService, + RouterService, + EntityConfigService, + Router, + SessionService, + AnalyticsService, + ActivatedRoute, + ], + multi: true, +}; diff --git a/src/app/app.module.ts b/src/app/app.module.ts index 49f9b5a406..f06a805547 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -17,14 +17,7 @@ import { BrowserModule } from "@angular/platform-browser"; import { BrowserAnimationsModule } from "@angular/platform-browser/animations"; -import { - APP_INITIALIZER, - ErrorHandler, - Injector, - LOCALE_ID, - NgModule, - ɵcreateInjector as createInjector, -} from "@angular/core"; +import { ErrorHandler, LOCALE_ID, NgModule } from "@angular/core"; import { HttpClientModule } from "@angular/common/http"; import { AppComponent } from "./app.component"; @@ -80,15 +73,12 @@ import { HistoricalDataModule } from "./features/historical-data/historical-data import { MatchingEntitiesModule } from "./features/matching-entities/matching-entities.module"; import { ProgressDashboardWidgetModule } from "./features/progress-dashboard-widget/progress-dashboard-widget.module"; import { ReportingModule } from "./features/reporting/reporting.module"; -import { ActivatedRoute, Router, RouterModule } from "@angular/router"; +import { RouterModule } from "@angular/router"; import { TodosModule } from "./features/todos/todos.module"; import { SessionService } from "./core/session/session-service/session.service"; import { waitForChangeTo } from "./core/session/session-states/session-utils"; import { LoginState } from "./core/session/session-states/login-state.enum"; -import { EntityConfigService } from "./core/entity/entity-config.service"; -import { ConfigService } from "./core/config/config.service"; -import { LoggingService } from "./core/logging/logging.service"; -import { RouterService } from "./core/view/dynamic-routing/router.service"; +import { appInitializers } from "./app-initializers"; /** * Main entry point of the application. @@ -165,64 +155,7 @@ import { RouterService } from "./core/view/dynamic-routing/router.service"; }), deps: [SessionService], }, - { - provide: APP_INITIALIZER, - useFactory: - ( - injector: Injector, - configService: ConfigService, - routerService: RouterService, - entityConfigService: EntityConfigService, - router: Router, - sessionService: SessionService, - analyticsService: AnalyticsService, - activatedRoute: ActivatedRoute - ) => - async () => { - // Re-trigger services that depend on the config when something changes - configService.configUpdates.subscribe(() => { - routerService.initRouting(); - entityConfigService.setupEntitiesFromConfig(); - router.navigate([], { - relativeTo: activatedRoute, - queryParamsHandling: "preserve", - }); - }); - - // update the user context for remote error logging and tracking and load config initially - sessionService.loginState.subscribe((newState) => { - if (newState === LoginState.LOGGED_IN) { - const username = sessionService.getCurrentUser().name; - LoggingService.setLoggingContextUser(username); - analyticsService.setUser(username); - } else { - LoggingService.setLoggingContextUser(undefined); - analyticsService.setUser(undefined); - } - }); - - if (environment.production) { - analyticsService.init(); - } - if (environment.demo_mode) { - const m = await import("./core/demo-data/demo-data.module"); - await createInjector(m.DemoDataModule, injector) - .get(m.DemoDataModule) - .publishDemoData(); - } - }, - deps: [ - Injector, - ConfigService, - RouterService, - EntityConfigService, - Router, - SessionService, - AnalyticsService, - ActivatedRoute, - ], - multi: true, - }, + appInitializers, ], bootstrap: [AppComponent], }) From 3728722905851ceeb4e121a6c282af654dbf7996 Mon Sep 17 00:00:00 2001 From: Simon Date: Wed, 31 May 2023 09:16:22 +0200 Subject: [PATCH 4/7] fixed route handling for demo mode --- src/app/app-initializers.ts | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/src/app/app-initializers.ts b/src/app/app-initializers.ts index 1c99e39de5..f5b6cb8ede 100644 --- a/src/app/app-initializers.ts +++ b/src/app/app-initializers.ts @@ -6,7 +6,7 @@ import { import { ConfigService } from "./core/config/config.service"; import { RouterService } from "./core/view/dynamic-routing/router.service"; import { EntityConfigService } from "./core/entity/entity-config.service"; -import { ActivatedRoute, Router } from "@angular/router"; +import { Router } from "@angular/router"; import { SessionService } from "./core/session/session-service/session.service"; import { AnalyticsService } from "./core/analytics/analytics.service"; import { LoginState } from "./core/session/session-states/login-state.enum"; @@ -23,18 +23,15 @@ export const appInitializers = { entityConfigService: EntityConfigService, router: Router, sessionService: SessionService, - analyticsService: AnalyticsService, - activatedRoute: ActivatedRoute + analyticsService: AnalyticsService ) => async () => { // Re-trigger services that depend on the config when something changes configService.configUpdates.subscribe(() => { routerService.initRouting(); entityConfigService.setupEntitiesFromConfig(); - router.navigate([], { - relativeTo: activatedRoute, - queryParamsHandling: "preserve", - }); + const url = location.href.replace(location.origin, ""); + router.navigateByUrl(url, { skipLocationChange: true }); }); // update the user context for remote error logging and tracking and load config initially @@ -67,7 +64,6 @@ export const appInitializers = { Router, SessionService, AnalyticsService, - ActivatedRoute, ], multi: true, }; From c3d29fe751b136744b62155b46e956638af74c93 Mon Sep 17 00:00:00 2001 From: Simon Date: Wed, 31 May 2023 10:16:25 +0200 Subject: [PATCH 5/7] fixed tests --- angular.json | 6 ++ src/app/app.component.spec.ts | 63 +++---------------- .../core/demo-data/demo-data.module.spec.ts | 1 + src/app/core/demo-data/demo-data.module.ts | 4 +- src/app/core/export/query.service.spec.ts | 11 +--- .../navigation/navigation.component.spec.ts | 3 +- .../session/login/login.component.spec.ts | 5 +- .../progress-dashboard.component.spec.ts | 7 ++- src/app/utils/mocked-testing.module.ts | 6 +- src/environments/environment.spec.ts | 30 +++++++++ 10 files changed, 67 insertions(+), 69 deletions(-) create mode 100644 src/environments/environment.spec.ts diff --git a/angular.json b/angular.json index dada2fbe23..792424196c 100644 --- a/angular.json +++ b/angular.json @@ -116,6 +116,12 @@ "src/assets", "src/favicon.ico", "src/manifest.webmanifest" + ], + "fileReplacements": [ + { + "replace": "src/environments/environment.ts", + "with": "src/environments/environment.spec.ts" + } ] } }, diff --git a/src/app/app.component.spec.ts b/src/app/app.component.spec.ts index 0bda7e47a3..f696818c9d 100644 --- a/src/app/app.component.spec.ts +++ b/src/app/app.component.spec.ts @@ -25,79 +25,36 @@ import { } from "@angular/core/testing"; import { AppComponent } from "./app.component"; import { AppModule } from "./app.module"; -import { Config } from "./core/config/config"; -import { USAGE_ANALYTICS_CONFIG_ID } from "./core/analytics/usage-analytics-config"; import { environment } from "../environments/environment"; -import { EntityRegistry } from "./core/entity/database-entity.decorator"; -import { Subject } from "rxjs"; import { Database } from "./core/database/database"; -import { UpdatedEntity } from "./core/entity/model/entity-update"; -import { EntityMapperService } from "./core/entity/entity-mapper.service"; -import { mockEntityMapper } from "./core/entity/mock-entity-mapper-service"; -import { SessionType } from "./core/session/session-type"; import { HttpClientTestingModule } from "@angular/common/http/testing"; -import { Angulartics2Matomo } from "angulartics2"; -import { componentRegistry } from "./dynamic-components"; describe("AppComponent", () => { let component: AppComponent; let fixture: ComponentFixture; - let entityUpdates: Subject>; + const intervalBefore = jasmine.DEFAULT_TIMEOUT_INTERVAL; - beforeAll(() => { - componentRegistry.allowDuplicates(); - }); beforeEach(waitForAsync(() => { - environment.session_type = SessionType.mock; - environment.production = false; - environment.demo_mode = false; - const entityMapper = mockEntityMapper(); - entityUpdates = new Subject(); - spyOn(entityMapper, "receiveUpdates").and.returnValue(entityUpdates); - + jasmine.DEFAULT_TIMEOUT_INTERVAL = 10000; + environment.demo_mode = true; TestBed.configureTestingModule({ imports: [AppModule, HttpClientTestingModule], - providers: [{ provide: EntityMapperService, useValue: entityMapper }], }).compileComponents(); - - spyOn(TestBed.inject(EntityRegistry), "add"); // Prevent error with duplicate registration })); - function createComponent() { + beforeEach(waitForAsync(() => { fixture = TestBed.createComponent(AppComponent); component = fixture.componentInstance; fixture.detectChanges(); - } + })); - afterEach(() => TestBed.inject(Database).destroy()); + afterEach(() => { + environment.demo_mode = false; + jasmine.DEFAULT_TIMEOUT_INTERVAL = intervalBefore; + return TestBed.inject(Database).destroy(); + }); it("should be created", () => { - createComponent(); expect(component).toBeTruthy(); }); - - it("should start tracking with config from db", fakeAsync(() => { - environment.production = true; // tracking is only active in production mode - const testConfig = new Config(Config.CONFIG_KEY, { - [USAGE_ANALYTICS_CONFIG_ID]: { - url: "matomo-test-endpoint", - site_id: "101", - }, - }); - entityUpdates.next({ entity: testConfig, type: "new" }); - const angulartics = TestBed.inject(Angulartics2Matomo); - const startTrackingSpy = spyOn(angulartics, "startTracking"); - window["_paq"] = []; - - createComponent(); - flush(); - - expect(startTrackingSpy).toHaveBeenCalledTimes(1); - expect(window["_paq"]).toContain([ - "setSiteId", - testConfig.data[USAGE_ANALYTICS_CONFIG_ID].site_id, - ]); - - discardPeriodicTasks(); - })); }); diff --git a/src/app/core/demo-data/demo-data.module.spec.ts b/src/app/core/demo-data/demo-data.module.spec.ts index b7e936785c..dcf043027e 100644 --- a/src/app/core/demo-data/demo-data.module.spec.ts +++ b/src/app/core/demo-data/demo-data.module.spec.ts @@ -22,6 +22,7 @@ describe("DemoDataModule", () => { }); it("should generate the demo data once the module is loaded", fakeAsync(() => { + TestBed.inject(DemoDataModule).publishDemoData(); expect(mockEntityMapper.saveAll).not.toHaveBeenCalled(); TestBed.inject(DemoDataModule); diff --git a/src/app/core/demo-data/demo-data.module.ts b/src/app/core/demo-data/demo-data.module.ts index cce2d1d069..4c0f9d083a 100644 --- a/src/app/core/demo-data/demo-data.module.ts +++ b/src/app/core/demo-data/demo-data.module.ts @@ -108,8 +108,6 @@ export class DemoDataModule { constructor(private demoDataInitializer: DemoDataInitializerService) {} publishDemoData() { - return this.demoDataInitializer - .run() - .then(() => console.log("demo data initialised")); + return this.demoDataInitializer.run(); } } diff --git a/src/app/core/export/query.service.spec.ts b/src/app/core/export/query.service.spec.ts index 537a56bafb..ce18844bed 100644 --- a/src/app/core/export/query.service.spec.ts +++ b/src/app/core/export/query.service.spec.ts @@ -18,13 +18,12 @@ import { expectEntitiesToMatch } from "../../utils/expect-entity-data.spec"; import { Database } from "../database/database"; import { Note } from "../../child-dev-project/notes/model/note"; import { genders } from "../../child-dev-project/children/model/genders"; -import { EntityConfigService } from "app/core/entity/entity-config.service"; -import { ConfigService } from "app/core/config/config.service"; import { EventAttendance } from "../../child-dev-project/attendance/model/event-attendance"; import { AttendanceStatusType } from "../../child-dev-project/attendance/model/attendance-status"; import { DatabaseTestingModule } from "../../utils/database-testing.module"; import { ChildrenService } from "../../child-dev-project/children/children.service"; import { AttendanceService } from "../../child-dev-project/attendance/attendance.service"; +import { environment } from "environments/environment"; describe("QueryService", () => { let service: QueryService; @@ -44,17 +43,13 @@ describe("QueryService", () => { (i) => i.id === "COACHING_CLASS" ); - beforeEach(waitForAsync(async () => { + beforeEach(waitForAsync(() => { + environment.demo_mode = false; TestBed.configureTestingModule({ imports: [DatabaseTestingModule], }); service = TestBed.inject(QueryService); - const configService = TestBed.inject(ConfigService); - const entityConfigService = TestBed.inject(EntityConfigService); entityMapper = TestBed.inject(EntityMapperService); - await configService.loadConfig(); - entityConfigService.addConfigAttributes(School); - entityConfigService.addConfigAttributes(Child); })); afterEach(() => TestBed.inject(Database).destroy()); diff --git a/src/app/core/navigation/navigation/navigation.component.spec.ts b/src/app/core/navigation/navigation/navigation.component.spec.ts index 5ff35ece67..e8d9edd4b0 100644 --- a/src/app/core/navigation/navigation/navigation.component.spec.ts +++ b/src/app/core/navigation/navigation/navigation.component.spec.ts @@ -36,10 +36,11 @@ describe("NavigationComponent", () => { beforeEach(waitForAsync(() => { mockConfigUpdated = new BehaviorSubject(null); - mockConfigService = jasmine.createSpyObj(["getConfig"], { + mockConfigService = jasmine.createSpyObj(["getConfig", "getAllConfigs"], { configUpdates: mockConfigUpdated, }); mockConfigService.getConfig.and.returnValue({ items: [] }); + mockConfigService.getAllConfigs.and.returnValue([]); mockUserRoleGuard = jasmine.createSpyObj(["checkRoutePermissions"]); mockUserRoleGuard.checkRoutePermissions.and.returnValue(true); diff --git a/src/app/core/session/login/login.component.spec.ts b/src/app/core/session/login/login.component.spec.ts index 2af9ccf772..42a964424a 100644 --- a/src/app/core/session/login/login.component.spec.ts +++ b/src/app/core/session/login/login.component.spec.ts @@ -43,7 +43,10 @@ describe("LoginComponent", () => { let loader: HarnessLoader; beforeEach(waitForAsync(() => { - mockSessionService = jasmine.createSpyObj(["login"], { loginState }); + mockSessionService = jasmine.createSpyObj(["login", "getCurrentUser"], { + loginState, + }); + mockSessionService.getCurrentUser.and.returnValue({ name: "", roles: [] }); TestBed.configureTestingModule({ imports: [LoginComponent, MockedTestingModule], providers: [ diff --git a/src/app/features/progress-dashboard-widget/progress-dashboard/progress-dashboard.component.spec.ts b/src/app/features/progress-dashboard-widget/progress-dashboard/progress-dashboard.component.spec.ts index 10ee3e8173..da754978cd 100644 --- a/src/app/features/progress-dashboard-widget/progress-dashboard/progress-dashboard.component.spec.ts +++ b/src/app/features/progress-dashboard-widget/progress-dashboard/progress-dashboard.component.spec.ts @@ -11,7 +11,7 @@ import { EntityMapperService } from "../../../core/entity/entity-mapper.service" import { AlertService } from "../../../core/alerts/alert.service"; import { ProgressDashboardConfig } from "./progress-dashboard-config"; import { MatDialog } from "@angular/material/dialog"; -import { BehaviorSubject, Subject } from "rxjs"; +import { BehaviorSubject, NEVER, Subject } from "rxjs"; import { take } from "rxjs/operators"; import { SessionService } from "../../../core/session/session-service/session.service"; import { SyncState } from "../../../core/session/session-states/sync-state.enum"; @@ -27,7 +27,10 @@ describe("ProgressDashboardComponent", () => { beforeEach(waitForAsync(() => { mockSync = new BehaviorSubject(SyncState.UNSYNCED); - mockSession = jasmine.createSpyObj([], { syncState: mockSync }); + mockSession = jasmine.createSpyObj([], { + syncState: mockSync, + loginState: NEVER, + }); TestBed.configureTestingModule({ imports: [ProgressDashboardComponent, MockedTestingModule.withState()], diff --git a/src/app/utils/mocked-testing.module.ts b/src/app/utils/mocked-testing.module.ts index 399bbca04a..bfa0f44cc0 100644 --- a/src/app/utils/mocked-testing.module.ts +++ b/src/app/utils/mocked-testing.module.ts @@ -52,7 +52,11 @@ export const TEST_PASSWORD = "pass"; { provide: SwRegistrationOptions, useValue: { enabled: false } }, { provide: AnalyticsService, - useValue: { eventTrack: () => undefined }, + useValue: { + eventTrack: () => undefined, + setUser: () => undefined, + init: () => undefined, + }, }, { provide: DatabaseIndexingService, diff --git a/src/environments/environment.spec.ts b/src/environments/environment.spec.ts new file mode 100644 index 0000000000..007112c8c1 --- /dev/null +++ b/src/environments/environment.spec.ts @@ -0,0 +1,30 @@ +/* + * This file is part of ndb-core. + * + * ndb-core 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, either version 3 of the License, or + * (at your option) any later version. + * + * ndb-core 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 ndb-core. If not, see . + */ + +import { SessionType } from "../app/core/session/session-type"; +import { AuthProvider } from "../app/core/session/auth/auth-provider"; + +export const environment = { + production: false, + appVersion: "test", + repositoryId: "Aam-Digital/ndb-core", + demo_mode: false, + session_type: SessionType.mock, + authenticator: AuthProvider.CouchDB, + account_url: "https://accounts.aam-digital.net", + email: undefined, +}; From 87512477fed673f6221979ffca89133f5dc47bb9 Mon Sep 17 00:00:00 2001 From: Simon Date: Wed, 31 May 2023 10:21:46 +0200 Subject: [PATCH 6/7] cleaned up code --- src/app/app.component.spec.ts | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/src/app/app.component.spec.ts b/src/app/app.component.spec.ts index f696818c9d..950c3255ea 100644 --- a/src/app/app.component.spec.ts +++ b/src/app/app.component.spec.ts @@ -15,14 +15,7 @@ * along with ndb-core. If not, see . */ -import { - ComponentFixture, - discardPeriodicTasks, - fakeAsync, - flush, - TestBed, - waitForAsync, -} from "@angular/core/testing"; +import { ComponentFixture, TestBed, waitForAsync } from "@angular/core/testing"; import { AppComponent } from "./app.component"; import { AppModule } from "./app.module"; import { environment } from "../environments/environment"; From 138575e6413f939cd7ad84a037118936df065355 Mon Sep 17 00:00:00 2001 From: Simon Date: Wed, 31 May 2023 10:26:40 +0200 Subject: [PATCH 7/7] removed unnecessary env --- src/app/core/export/query.service.spec.ts | 2 -- src/environments/environment.spec.ts | 17 ----------------- 2 files changed, 19 deletions(-) diff --git a/src/app/core/export/query.service.spec.ts b/src/app/core/export/query.service.spec.ts index ce18844bed..76803e72d6 100644 --- a/src/app/core/export/query.service.spec.ts +++ b/src/app/core/export/query.service.spec.ts @@ -23,7 +23,6 @@ import { AttendanceStatusType } from "../../child-dev-project/attendance/model/a import { DatabaseTestingModule } from "../../utils/database-testing.module"; import { ChildrenService } from "../../child-dev-project/children/children.service"; import { AttendanceService } from "../../child-dev-project/attendance/attendance.service"; -import { environment } from "environments/environment"; describe("QueryService", () => { let service: QueryService; @@ -44,7 +43,6 @@ describe("QueryService", () => { ); beforeEach(waitForAsync(() => { - environment.demo_mode = false; TestBed.configureTestingModule({ imports: [DatabaseTestingModule], }); diff --git a/src/environments/environment.spec.ts b/src/environments/environment.spec.ts index 007112c8c1..272a2d5770 100644 --- a/src/environments/environment.spec.ts +++ b/src/environments/environment.spec.ts @@ -1,20 +1,3 @@ -/* - * This file is part of ndb-core. - * - * ndb-core 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, either version 3 of the License, or - * (at your option) any later version. - * - * ndb-core 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 ndb-core. If not, see . - */ - import { SessionType } from "../app/core/session/session-type"; import { AuthProvider } from "../app/core/session/auth/auth-provider";