Skip to content

Commit

Permalink
fix(workbench/messagebox): fix registration of MessageBoxService in r…
Browse files Browse the repository at this point in the history
…oot injector

If the workbench was mounted via a standalone component using the Angular router, application-modal message boxes were not displayed.
  • Loading branch information
danielwiehl authored and mofogasy committed Jan 31, 2023
1 parent f9378e0 commit 47beed6
Show file tree
Hide file tree
Showing 3 changed files with 126 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ import {MessageBoxStackComponent} from './message-box-stack.component';
import {MessageBoxComponent} from './message-box.component';
import {TextMessageComponent} from './text-message.component';
import {MessageBoxCssClassesPipe} from './message-box-css-classes.pipe';
import {MessageBoxService} from './message-box.service';
import {A11yModule} from '@angular/cdk/a11y';
import {PortalModule} from '@angular/cdk/portal';
import {MoveDirective} from './move.directive';
Expand Down Expand Up @@ -43,9 +42,6 @@ import {CoerceObservablePipe} from './coerce-observable.pipe';
exports: [
MessageBoxStackComponent,
],
providers: [
MessageBoxService,
],
})
export class MessageBoxModule {
}
124 changes: 124 additions & 0 deletions projects/scion/workbench/src/lib/message-box/message-box.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
/*
* Copyright (c) 2018-2023 Swiss Federal Railways
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*/

import {ComponentFixture, ComponentFixtureAutoDetect, TestBed} from '@angular/core/testing';
import {Component, DebugElement} from '@angular/core';
import {Router, RouterOutlet} from '@angular/router';
import {RouterTestingModule} from '@angular/router/testing';
import {NoopAnimationsModule} from '@angular/platform-browser/animations';
import {By} from '@angular/platform-browser';
import {ComponentType} from '@angular/cdk/portal';
import {WorkbenchRouter} from '../routing/workbench-router.service';
import {WorkbenchTestingModule} from '../spec/workbench-testing.module';
import {MessageBoxService} from './message-box.service';
import {WorkbenchModule} from '../workbench.module';
import {WorkbenchLauncher} from '../startup/workbench-launcher.service';

describe('MessageBox', () => {

describe('Workbench in a Router Outlet (Angular sets up a separate injector for standalone components loaded via router)', () => {

beforeEach(() => {
TestBed.configureTestingModule({
imports: [
WorkbenchTestingModule.forRoot({startup: {launcher: 'LAZY'}}),
RouterTestingModule.withRoutes([
{path: '', component: WorkbenchTestComponent},
{path: 'view', component: ViewTestComponent},
]),
NoopAnimationsModule,
],
providers: [
{provide: ComponentFixtureAutoDetect, useValue: true},
],
});
TestBed.inject(Router).initialNavigation();
});

it('should display application-modal message box', async () => {
// Create fixture
const fixture = TestBed.createComponent(RootTestComponent);
fixture.debugElement.nativeElement.style.border = '1px solid black';

// Launch workbench
await TestBed.inject(WorkbenchLauncher).launch();

// Open application-modal message box
TestBed.inject(MessageBoxService).open({content: 'message', cssClass: 'testee'}).then();

// Expect message box to show
await fixture.whenStable();
expect(querySelector(fixture, 'wb-message-box.testee')).toBeDefined();
});

it('should display view-local message box', async () => {
// Create fixture
const fixture = TestBed.createComponent(RootTestComponent);
fixture.debugElement.nativeElement.style.border = '1px solid black';

// Launch workbench
await TestBed.inject(WorkbenchLauncher).launch();

// Open view
await TestBed.inject(WorkbenchRouter).navigate(['view']);
await fixture.whenStable();

// Open view-local message box
const viewDebugElement = debugElement(fixture, ViewTestComponent);
viewDebugElement.injector.get(MessageBoxService).open({content: 'Message from View', cssClass: 'testee'}).then();
await fixture.whenStable();

// Expect message box to show
expect(querySelector(fixture, 'wb-message-box.testee')).toBeDefined();
});

/****************************************************************************************************
* Definition of Test Components *
****************************************************************************************************/
@Component({
selector: 'spec-root',
template: '<router-outlet></router-outlet>',
standalone: true,
imports: [
RouterOutlet,
],
})
class RootTestComponent {
}

@Component({
selector: 'spec-workbench',
template: '<wb-workbench></wb-workbench>',
styles: [':host {display: grid; height: 500px;}'],
standalone: true,
imports: [
WorkbenchModule,
],
})
class WorkbenchTestComponent {
}

@Component({
selector: 'spec-view-1',
template: 'View',
standalone: true,
})
class ViewTestComponent {
}
});
});

function querySelector(fixture: ComponentFixture<any>, selector: string): HTMLElement | undefined {
return fixture.debugElement.query(By.css(selector))?.nativeElement ?? undefined;
}

function debugElement(fixture: ComponentFixture<any>, view: ComponentType<any>): DebugElement | undefined {
return fixture.debugElement.query(By.directive(view)) ?? undefined;
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

import {ComponentFixture, ComponentFixtureAutoDetect, TestBed} from '@angular/core/testing';
import {expect, jasmineCustomMatchers} from './util/jasmine-custom-matchers.spec';
import {Component, NgZone} from '@angular/core';
import {Component} from '@angular/core';
import {PartsLayoutComponent} from '../layout/parts-layout.component';
import {Router, UrlSegment} from '@angular/router';
import {RouterTestingModule} from '@angular/router/testing';
Expand Down Expand Up @@ -53,7 +53,7 @@ describe('PartsLayoutComponent', () => {
wbRouter = TestBed.inject(WorkbenchRouter);
viewDragService = TestBed.inject(ViewDragService);

TestBed.inject(NgZone).run(() => TestBed.inject(Router).initialNavigation());
TestBed.inject(Router).initialNavigation();
fixture = TestBed.createComponent(PartsLayoutComponent);
fixture.debugElement.nativeElement.style.height = '500px';
fixture.debugElement.nativeElement.style.background = 'lightgray';
Expand Down

0 comments on commit 47beed6

Please sign in to comment.