;
constructor(private ws: NbWindowService) {}
openWindow() {
return this.ws.open(
this.contentTemplate,
{ title: 'Window content from template', context: { text: 'hello world' } },
);
}
}
@Component({
selector: 'nb-test-window-with-component',
template: `window content {{ componentInput }}
`,
})
export class TestWindowComponent {}
@NgModule({
declarations: [NbTestWindowComponent, NbTestWindowWithTemplateComponent, TestWindowComponent],
entryComponents: [NbTestWindowComponent, NbTestWindowWithTemplateComponent, TestWindowComponent],
})
class NbTestWindowModule {}
let overlayContainerService: NbOverlayContainerAdapter;
let overlayContainer: HTMLElement;
let document: Document;
const queryBackdrop = () => overlayContainer.querySelector('.cdk-overlay-backdrop');
let windowService: NbWindowService;
class NbViewportRulerAdapterMock {
getViewportSize(): Readonly<{ width: number; height: number; }> {
return { width: 1000, height: 1000 };
}
getViewportScrollPosition(): { left: number; top: number } {
return { left: 0, top: 0 };
}
}
describe('window-service', () => {
beforeEach(() => {
TestBed.configureTestingModule({
imports: [
NbThemeModule.forRoot(),
NbWindowModule.forRoot(),
NbTestWindowModule,
],
providers: [
{ provide: NbViewportRulerAdapter, useClass: NbViewportRulerAdapterMock },
],
});
windowService = TestBed.inject(NbWindowService);
overlayContainerService = TestBed.inject(NbOverlayContainerAdapter);
document = TestBed.inject(NB_DOCUMENT);
});
beforeEach(() => {
overlayContainer = document.createElement('div');
overlayContainerService.setContainer(overlayContainer);
document.body.appendChild(overlayContainer);
});
afterEach(() => {
overlayContainerService.clearContainer();
document.body.removeChild(overlayContainer);
});
it('should render window', () => {
const windowRef = windowService.open(NbTestWindowComponent);
windowRef.componentRef.changeDetectorRef.detectChanges();
expect(windowRef.componentRef).toBeDefined();
const windowElement: ElementRef = windowRef.componentRef.injector.get(ElementRef);
expect(windowElement.nativeElement.innerText).toContain(WINDOW_CONTENT);
});
it('should set title', () => {
const title = 'Window title';
const windowRef = windowService.open(NbTestWindowComponent, { title });
windowRef.componentRef.changeDetectorRef.detectChanges();
const windowElement: ElementRef = windowRef.componentRef.injector.get(ElementRef);
expect(windowElement.nativeElement.querySelector('.title').innerHTML).toEqual(title);
});
it('should set class if provided', () => {
const windowClass = 'my-window-class';
const windowRef = windowService.open(NbTestWindowComponent, { windowClass });
windowRef.componentRef.changeDetectorRef.detectChanges();
const windowElement: ElementRef = windowRef.componentRef.injector.get(ElementRef);
expect(windowElement.nativeElement.classList).toContain(windowClass);
});
it('should render with backdrop if hasBackdrop is true', () => {
const windowRef = windowService.open(NbTestWindowComponent, { hasBackdrop: true });
windowRef.componentRef.changeDetectorRef.detectChanges();
expect(queryBackdrop()).toBeTruthy();
});
it('should render without backdrop if hasBackdrop is false', () => {
const windowRef = windowService.open(NbTestWindowComponent, { hasBackdrop: false });
windowRef.componentRef.changeDetectorRef.detectChanges();
expect(queryBackdrop().hasAttribute('hidden')).toBeTruthy();
});
it('should close on backdrop click if closeOnBackdropClick is true', () => {
const closeSpy = createSpy('closeSpy');
const windowRef = windowService.open(NbTestWindowComponent, { closeOnBackdropClick: true });
windowRef.componentRef.changeDetectorRef.detectChanges();
windowRef.onClose.subscribe(closeSpy);
queryBackdrop().dispatchEvent(new Event('click'));
expect(closeSpy).toHaveBeenCalled();
});
it('should not close on backdrop click if closeOnBackdropClick is false', () => {
const closeSpy = createSpy('closeSpy');
const windowRef = windowService.open(NbTestWindowComponent, { closeOnBackdropClick: false });
windowRef.componentRef.changeDetectorRef.detectChanges();
windowRef.onClose.subscribe(closeSpy);
queryBackdrop().dispatchEvent(new Event('click'));
expect(closeSpy).not.toHaveBeenCalled();
});
it('should close on escape press if closeOnEsc is true', () => {
const closeSpy = createSpy('closeSpy');
const windowRef = windowService.open(NbTestWindowComponent, { closeOnEsc: true });
windowRef.componentRef.changeDetectorRef.detectChanges();
windowRef.onClose.subscribe(closeSpy);
document.body.dispatchEvent(new KeyboardEvent('keydown', { keyCode: 27 }));
expect(closeSpy).toHaveBeenCalled();
});
it('should not close on escape press if closeOnEsc is false', () => {
const closeSpy = createSpy('closeSpy');
const windowRef = windowService.open(NbTestWindowComponent, { closeOnEsc: false });
windowRef.componentRef.changeDetectorRef.detectChanges();
windowRef.onClose.subscribe(closeSpy);
document.body.dispatchEvent(new KeyboardEvent('keydown', { keyCode: 27 }));
expect(closeSpy).not.toHaveBeenCalled();
});
it('should hide backdrop when window not in a full screen', () => {
const windowRef = windowService.open(NbTestWindowComponent, { closeOnEsc: false });
windowRef.componentRef.changeDetectorRef.detectChanges();
expect(queryBackdrop().hasAttribute('hidden')).toBeFalsy();
windowRef.minimize();
windowRef.componentRef.changeDetectorRef.detectChanges();
expect(queryBackdrop().hasAttribute('hidden')).toBeTruthy();
windowRef.maximize();
windowRef.componentRef.changeDetectorRef.detectChanges();
expect(queryBackdrop().hasAttribute('hidden')).toBeTruthy();
windowRef.fullScreen();
windowRef.componentRef.changeDetectorRef.detectChanges();
expect(queryBackdrop().hasAttribute('hidden')).toBeFalsy();
});
it('should keep backdrop while at least one full screen window is open', () => {
const firstWindow = windowService.open(NbTestWindowComponent);
const secondWindow = windowService.open(NbTestWindowComponent);
firstWindow.componentRef.changeDetectorRef.detectChanges();
secondWindow.componentRef.changeDetectorRef.detectChanges();
expect(queryBackdrop().hasAttribute('hidden')).toBeFalsy();
firstWindow.minimize();
firstWindow.componentRef.changeDetectorRef.detectChanges();
expect(queryBackdrop().hasAttribute('hidden')).toBeFalsy();
secondWindow.minimize();
secondWindow.componentRef.changeDetectorRef.detectChanges();
expect(queryBackdrop().hasAttribute('hidden')).toBeTruthy();
firstWindow.fullScreen();
firstWindow.componentRef.changeDetectorRef.detectChanges();
expect(queryBackdrop().hasAttribute('hidden')).toBeFalsy();
});
it(`shouldn't render window content when minimized`, function() {
const windowRef = windowService.open(NbTestWindowComponent);
windowRef.minimize();
windowRef.componentRef.changeDetectorRef.detectChanges();
const windowElement: HTMLElement = windowRef.componentRef.location.nativeElement;
expect(windowElement.querySelector('nb-card-body')).toBeNull();
});
it(`should render window content when unminimized`, function() {
const windowRef = windowService.open(NbTestWindowComponent);
windowRef.minimize();
windowRef.componentRef.changeDetectorRef.detectChanges();
windowRef.maximize();
windowRef.componentRef.changeDetectorRef.detectChanges();
const windowElement: HTMLElement = windowRef.componentRef.location.nativeElement;
expect(windowElement.querySelector('nb-card-body')).not.toBeNull();
});
it(`should render window content from template with context`, function() {
const fixture = TestBed.createComponent(NbTestWindowWithTemplateComponent);
fixture.detectChanges();
const windowRef = fixture.componentInstance.openWindow();
windowRef.componentRef.changeDetectorRef.detectChanges();
expect(windowRef.componentRef).toBeDefined();
const windowElement: ElementRef = windowRef.componentRef.injector.get(ElementRef);
expect(windowElement.nativeElement.innerText).toContain('Static text: hello world');
});
it(`should render window content from component without context`, function() {
const windowRef = windowService.open(TestWindowComponent);
windowRef.componentRef.changeDetectorRef.detectChanges();
const windowElement: ElementRef = windowRef.componentRef.injector.get(ElementRef);
expect(windowElement.nativeElement.innerText).toEqual('window content');
});
it(`should render window content from component with context`, function() {
const windowRef = windowService.open(TestWindowComponent, { context: { componentInput: 'hello world' }});
windowRef.componentRef.changeDetectorRef.detectChanges();
const windowElement: ElementRef = windowRef.componentRef.injector.get(ElementRef);
expect(windowElement.nativeElement.innerText).toEqual('window content hello world');
});
it('should create new window container when overlay container changed', fakeAsync(() => {
const fixture = TestBed.createComponent(NbTestWindowWithTemplateComponent);
fixture.detectChanges();
// Show window to force windows container creation
const windowRef = fixture.componentInstance.openWindow();
fixture.detectChanges();
flush();
windowRef.close();
fixture.detectChanges();
flush();
// Change overlay container
overlayContainerService.ngOnDestroy();
overlayContainerService.clearContainer();
overlayContainer = document.createElement('div');
overlayContainerService.setContainer(overlayContainer);
document.body.appendChild(overlayContainer);
windowService.open(TestWindowComponent);
fixture.detectChanges();
flush();
const windowContent = document.getElementById('window-content');
expect(document.body.contains(windowContent)).toEqual(true);
}));
});