From 51e1ac09e7f0a4ca286cb6e032ec119f318c33a2 Mon Sep 17 00:00:00 2001 From: Bruno Roemers Date: Mon, 15 Mar 2021 11:40:24 +0100 Subject: [PATCH] 77643: BUGFIX: Init BreadcrumbsService before routing --- src/app/app.component.spec.ts | 80 +++++++++++++--------- src/app/app.component.ts | 3 + src/app/breadcrumbs/breadcrumbs.service.ts | 8 ++- 3 files changed, 57 insertions(+), 34 deletions(-) diff --git a/src/app/app.component.spec.ts b/src/app/app.component.spec.ts index c092362c7e..3f2dc45ce7 100644 --- a/src/app/app.component.spec.ts +++ b/src/app/app.component.spec.ts @@ -35,6 +35,7 @@ import { provideMockStore } from '@ngrx/store/testing'; import { GoogleAnalyticsService } from './statistics/google-analytics.service'; import { ThemeService } from './shared/theme-support/theme.service'; import { getMockThemeService } from './shared/mocks/theme-service.mock'; +import { BreadcrumbsService } from './breadcrumbs/breadcrumbs.service'; let comp: AppComponent; let fixture: ComponentFixture; @@ -45,47 +46,54 @@ const initialState = { describe('App component', () => { + let breadcrumbsServiceSpy; + function getMockLocaleService(): LocaleService { return jasmine.createSpyObj('LocaleService', { setCurrentLanguageCode: jasmine.createSpy('setCurrentLanguageCode') }); } - const defaultTestBedConf = { - imports: [ - CommonModule, - StoreModule.forRoot(authReducer, storeModuleConfig), - TranslateModule.forRoot({ - loader: { - provide: TranslateLoader, - useClass: TranslateLoaderMock - } - }), - ], - declarations: [AppComponent], // declare the test component - providers: [ - { provide: NativeWindowService, useValue: new NativeWindowRef() }, - { provide: MetadataService, useValue: new MetadataServiceMock() }, - { provide: Angulartics2GoogleAnalytics, useValue: new AngularticsProviderMock() }, - { provide: Angulartics2DSpace, useValue: new AngularticsProviderMock() }, - { provide: AuthService, useValue: new AuthServiceMock() }, - { provide: Router, useValue: new RouterMock() }, - { provide: ActivatedRoute, useValue: new MockActivatedRoute() }, - { provide: MenuService, useValue: menuService }, - { provide: CSSVariableService, useClass: CSSVariableServiceStub }, - { provide: HostWindowService, useValue: new HostWindowServiceStub(800) }, - { provide: LocaleService, useValue: getMockLocaleService() }, - { provide: ThemeService, useValue: getMockThemeService() }, - provideMockStore({ initialState }), - AppComponent, - RouteService - ], - schemas: [CUSTOM_ELEMENTS_SCHEMA] + const getDefaultTestBedConf = () => { + breadcrumbsServiceSpy = jasmine.createSpyObj(['listenForRouteChanges']); + + return { + imports: [ + CommonModule, + StoreModule.forRoot(authReducer, storeModuleConfig), + TranslateModule.forRoot({ + loader: { + provide: TranslateLoader, + useClass: TranslateLoaderMock + } + }), + ], + declarations: [AppComponent], // declare the test component + providers: [ + { provide: NativeWindowService, useValue: new NativeWindowRef() }, + { provide: MetadataService, useValue: new MetadataServiceMock() }, + { provide: Angulartics2GoogleAnalytics, useValue: new AngularticsProviderMock() }, + { provide: Angulartics2DSpace, useValue: new AngularticsProviderMock() }, + { provide: AuthService, useValue: new AuthServiceMock() }, + { provide: Router, useValue: new RouterMock() }, + { provide: ActivatedRoute, useValue: new MockActivatedRoute() }, + { provide: MenuService, useValue: menuService }, + { provide: CSSVariableService, useClass: CSSVariableServiceStub }, + { provide: HostWindowService, useValue: new HostWindowServiceStub(800) }, + { provide: LocaleService, useValue: getMockLocaleService() }, + { provide: ThemeService, useValue: getMockThemeService() }, + { provide: BreadcrumbsService, useValue: breadcrumbsServiceSpy }, + provideMockStore({ initialState }), + AppComponent, + RouteService + ], + schemas: [CUSTOM_ELEMENTS_SCHEMA] + }; }; // waitForAsync beforeEach beforeEach(waitForAsync(() => { - return TestBed.configureTestingModule(defaultTestBedConf); + return TestBed.configureTestingModule(getDefaultTestBedConf()); })); // synchronous beforeEach @@ -120,13 +128,19 @@ describe('App component', () => { }); + describe('the constructor', () => { + it('should call breadcrumbsService.listenForRouteChanges', () => { + expect(breadcrumbsServiceSpy.listenForRouteChanges).toHaveBeenCalledTimes(1); + }); + }); + describe('when GoogleAnalyticsService is provided', () => { let googleAnalyticsSpy; beforeEach(() => { // NOTE: Cannot override providers once components have been compiled, so TestBed needs to be reset TestBed.resetTestingModule(); - TestBed.configureTestingModule(defaultTestBedConf); + TestBed.configureTestingModule(getDefaultTestBedConf()); googleAnalyticsSpy = jasmine.createSpyObj('googleAnalyticsService', [ 'addTrackingIdToPage', ]); @@ -154,7 +168,7 @@ describe('App component', () => { beforeEach(() => { // NOTE: Cannot override providers once components have been compiled, so TestBed needs to be reset TestBed.resetTestingModule(); - TestBed.configureTestingModule(defaultTestBedConf); + TestBed.configureTestingModule(getDefaultTestBedConf()); TestBed.overrideProvider(ThemeService, {useValue: getMockThemeService('custom')}); document = TestBed.inject(DOCUMENT); headSpy = jasmine.createSpyObj('head', ['appendChild']); diff --git a/src/app/app.component.ts b/src/app/app.component.ts index 8a38d14fe3..a596ba56cd 100644 --- a/src/app/app.component.ts +++ b/src/app/app.component.ts @@ -36,6 +36,7 @@ import { DOCUMENT } from '@angular/common'; import { ThemeService } from './shared/theme-support/theme.service'; import { BASE_THEME_NAME } from './shared/theme-support/theme.constants'; import { DEFAULT_THEME_CONFIG } from './shared/theme-support/theme.effects'; +import { BreadcrumbsService } from './breadcrumbs/breadcrumbs.service'; @Component({ selector: 'ds-app', @@ -73,6 +74,7 @@ export class AppComponent implements OnInit, AfterViewInit { private menuService: MenuService, private windowService: HostWindowService, private localeService: LocaleService, + private breadcrumbsService: BreadcrumbsService, @Optional() private cookiesService: KlaroService, @Optional() private googleAnalyticsService: GoogleAnalyticsService, ) { @@ -106,6 +108,7 @@ export class AppComponent implements OnInit, AfterViewInit { angulartics2DSpace.startTracking(); metadata.listenForRouteChange(); + breadcrumbsService.listenForRouteChanges(); if (environment.debug) { console.info(environment); diff --git a/src/app/breadcrumbs/breadcrumbs.service.ts b/src/app/breadcrumbs/breadcrumbs.service.ts index 23fc806099..a7be030c12 100644 --- a/src/app/breadcrumbs/breadcrumbs.service.ts +++ b/src/app/breadcrumbs/breadcrumbs.service.ts @@ -23,7 +23,13 @@ export class BreadcrumbsService { constructor( private route: ActivatedRoute, private router: Router, - ) { + ) {} + + /** + * Called by {@link AppComponent#constructor} (i.e. before routing) + * such that no routing events are missed. + */ + listenForRouteChanges() { // supply events to this.breadcrumbs$ this.router.events.pipe( filter((e): e is NavigationEnd => e instanceof NavigationEnd),