import {DirtyGuard, FormComponent, RouterOutletDirtyWatchDirective} from './confirm-navigation-if-dirty.framework'; import {ComponentFixture, fakeAsync, TestBed} from '@angular/core/testing'; import {RouterModule, RouterOutlet} from '@angular/router'; import {Observable, of} from 'rxjs'; import {Component, EventEmitter} from '@angular/core'; import {NgForm} from '@angular/forms'; import {environment} from '../environments/environment'; import {DialogService} from './modals/dialog/dialog.service'; @Component({ selector: 'app-dirty-form-test', template: '

test form

' }) class TestDialogComponent extends FormComponent { public formMock = { submitted: false, dirty: false }; public makeDirty(): void { this.formMock.dirty = true; } get form(): NgForm | undefined { return this.formMock as unknown as NgForm; } } describe('Dirty checking frameworks', () => { describe('RouterOutletPlugin', () => { let fixture: ComponentFixture; let component: TestDialogComponent; let directive: RouterOutletDirtyWatchDirective; beforeEach(() => { environment.production = false; fixture = TestBed.createComponent(TestDialogComponent); component = fixture.componentInstance; fixture.detectChanges(); directive = new RouterOutletDirtyWatchDirective({ activateEvents: of(component) as EventEmitter, deactivateEvents: of(undefined) as unknown as EventEmitter } as unknown as RouterOutlet); }); it('should create an instance', () => { expect(directive).toBeTruthy(); }); it('prevents page reloads if component is dirty', fakeAsync(() => { component.makeDirty(); fixture.detectChanges(); expect(component.isDirty()).toBeTrue(); // We're not in production mode, so we don't expect reloads to be blocked expect(directive.canDeactivate(new Event('test'))).toBeTrue(); environment.production = true; expect(directive.canDeactivate(new Event('test'))).toBeFalse(); })); it('allows page reloads if component is not dirty', () => { expect(directive.canDeactivate(new Event('test'))).toBeTrue(); }); }); describe('DirtyGuard', () => { let service: DirtyGuard; let fixture: ComponentFixture; let component: TestDialogComponent; let dialogChoice: boolean; const dialogService = {show(): Observable { return of(dialogChoice); }, testInstance: true}; beforeEach(() => { TestBed.configureTestingModule({ declarations: [TestDialogComponent], imports: [RouterModule], providers: [ {provide: DialogService, useValue: dialogService}, ] }); dialogChoice = false; service = TestBed.inject(DirtyGuard); fixture = TestBed.createComponent(TestDialogComponent); component = fixture.componentInstance; fixture.detectChanges(); }); it('should create an instance', () => { expect(service).toBeTruthy(); }); it('prevents routing if component is dirty', (done) => { const spy = spyOn(dialogService, 'show').and.callThrough(); component.makeDirty(); fixture.detectChanges(); const waitForUserToConfirmNavigation: Observable = service.canDeactivate(component) as Observable; waitForUserToConfirmNavigation.subscribe((result) => { expect(spy).toHaveBeenCalled(); expect(result).toBeFalse(); done(); }); }); it('allows routing if component is not dirty', () => { const spy = spyOn(dialogService, 'show').and.callThrough(); const canNavigate: boolean = service.canDeactivate(component) as boolean; expect(spy).not.toHaveBeenCalled(); expect(canNavigate).toBeTrue(); }); it('allows routing if component does not implement ConfirmIfDirty', () => { const spy = spyOn(dialogService, 'show').and.callThrough(); const canNavigate: boolean = service.canDeactivate({}) as boolean; expect(spy).not.toHaveBeenCalled(); expect(canNavigate).toBeTrue(); }); }); });