import { CUSTOM_ELEMENTS_SCHEMA, DebugElement } from '@angular/core'; import { async, ComponentFixture, inject, TestBed } from '@angular/core/testing'; import { By } from '@angular/platform-browser'; import { Store, StoreModule } from '@ngrx/store'; import { authReducer, AuthState } from '../../core/auth/auth.reducer'; import { EPersonMock } from '../testing/eperson-mock'; import { TranslateModule } from '@ngx-translate/core'; import { AppState } from '../../app.reducer'; import { AuthNavMenuComponent } from './auth-nav-menu.component'; import { HostWindowServiceStub } from '../testing/host-window-service-stub'; import { HostWindowService } from '../host-window.service'; import { NoopAnimationsModule } from '@angular/platform-browser/animations'; import { AuthTokenInfo } from '../../core/auth/models/auth-token-info.model'; import { AuthService } from '../../core/auth/auth.service'; describe('AuthNavMenuComponent', () => { let component: AuthNavMenuComponent; let deNavMenu: DebugElement; let deNavMenuItem: DebugElement; let fixture: ComponentFixture<AuthNavMenuComponent>; let notAuthState: AuthState; let authState: AuthState; let routerState = { url: '/home' }; function init() { notAuthState = { authenticated: false, loaded: false, loading: false }; authState = { authenticated: true, loaded: true, loading: false, authToken: new AuthTokenInfo('test_token'), user: EPersonMock }; } describe('when is a not mobile view', () => { beforeEach(async(() => { const window = new HostWindowServiceStub(800); // refine the test module by declaring the test component TestBed.configureTestingModule({ imports: [ NoopAnimationsModule, StoreModule.forRoot(authReducer), TranslateModule.forRoot() ], declarations: [ AuthNavMenuComponent ], providers: [ { provide: HostWindowService, useValue: window }, { provide: AuthService, useValue: { setRedirectUrl: () => { /*empty*/ } } } ], schemas: [ CUSTOM_ELEMENTS_SCHEMA ] }) .compileComponents(); })); beforeEach(() => { init(); }); describe('when route is /login and user is not authenticated', () => { beforeEach(inject([Store], (store: Store<AppState>) => { routerState = { url: '/login' }; store .subscribe((state) => { (state as any).router = Object.create({}); (state as any).router.state = routerState; (state as any).core = Object.create({}); (state as any).core.auth = notAuthState; }); // create component and test fixture fixture = TestBed.createComponent(AuthNavMenuComponent); // get test component from the fixture component = fixture.componentInstance; fixture.detectChanges(); const navMenuSelector = '.navbar-nav'; deNavMenu = fixture.debugElement.query(By.css(navMenuSelector)); const navMenuItemSelector = 'li'; deNavMenuItem = deNavMenu.query(By.css(navMenuItemSelector)); })); afterEach(() => { fixture.destroy(); }); it('should not render', () => { expect(component).toBeTruthy(); expect(deNavMenu.nativeElement).toBeDefined(); expect(deNavMenuItem).toBeNull(); }); }); describe('when route is /logout and user is authenticated', () => { beforeEach(inject([Store], (store: Store<AppState>) => { routerState = { url: '/logout' }; store .subscribe((state) => { (state as any).router = Object.create({}); (state as any).router.state = routerState; (state as any).core = Object.create({}); (state as any).core.auth = authState; }); // create component and test fixture fixture = TestBed.createComponent(AuthNavMenuComponent); // get test component from the fixture component = fixture.componentInstance; fixture.detectChanges(); const navMenuSelector = '.navbar-nav'; deNavMenu = fixture.debugElement.query(By.css(navMenuSelector)); const navMenuItemSelector = 'li'; deNavMenuItem = deNavMenu.query(By.css(navMenuItemSelector)); })); afterEach(() => { fixture.destroy(); }); it('should not render', () => { expect(component).toBeTruthy(); expect(deNavMenu.nativeElement).toBeDefined(); expect(deNavMenuItem).toBeNull(); }); }); describe('when route is not /login neither /logout', () => { describe('when user is not authenticated', () => { beforeEach(inject([Store], (store: Store<AppState>) => { routerState = { url: '/home' }; store .subscribe((state) => { (state as any).router = Object.create({}); (state as any).router.state = routerState; (state as any).core = Object.create({}); (state as any).core.auth = notAuthState; }); // create component and test fixture fixture = TestBed.createComponent(AuthNavMenuComponent); // get test component from the fixture component = fixture.componentInstance; fixture.detectChanges(); const navMenuSelector = '.navbar-nav'; deNavMenu = fixture.debugElement.query(By.css(navMenuSelector)); const navMenuItemSelector = 'li'; deNavMenuItem = deNavMenu.query(By.css(navMenuItemSelector)); })); afterEach(() => { fixture.destroy(); component = null; }); it('should render login dropdown menu', () => { const loginDropdownMenu = deNavMenuItem.query(By.css('div[id=loginDropdownMenu]')); expect(loginDropdownMenu.nativeElement).toBeDefined(); }); }); describe('when user is authenticated', () => { beforeEach(inject([Store], (store: Store<AppState>) => { routerState = { url: '/home' }; store .subscribe((state) => { (state as any).router = Object.create({}); (state as any).router.state = routerState; (state as any).core = Object.create({}); (state as any).core.auth = authState; }); // create component and test fixture fixture = TestBed.createComponent(AuthNavMenuComponent); // get test component from the fixture component = fixture.componentInstance; fixture.detectChanges(); const navMenuSelector = '.navbar-nav'; deNavMenu = fixture.debugElement.query(By.css(navMenuSelector)); const navMenuItemSelector = 'li'; deNavMenuItem = deNavMenu.query(By.css(navMenuItemSelector)); })); afterEach(() => { fixture.destroy(); component = null; }); it('should render logout dropdown menu', () => { const logoutDropdownMenu = deNavMenuItem.query(By.css('ul[id=logoutDropdownMenu]')); expect(logoutDropdownMenu.nativeElement).toBeDefined(); }); }) }) }); describe('when is a mobile view', () => { beforeEach(async(() => { const window = new HostWindowServiceStub(300); // refine the test module by declaring the test component TestBed.configureTestingModule({ imports: [ NoopAnimationsModule, StoreModule.forRoot(authReducer), TranslateModule.forRoot() ], declarations: [ AuthNavMenuComponent ], providers: [ { provide: HostWindowService, useValue: window }, { provide: AuthService, useValue: { setRedirectUrl: () => { /*empty*/ } } } ], schemas: [ CUSTOM_ELEMENTS_SCHEMA ] }) .compileComponents(); })); beforeEach(() => { init(); }); describe('when user is not authenticated', () => { beforeEach(inject([Store], (store: Store<AppState>) => { store .subscribe((state) => { (state as any).router = Object.create({}); (state as any).router.state = routerState; (state as any).core = Object.create({}); (state as any).core.auth = notAuthState; }); // create component and test fixture fixture = TestBed.createComponent(AuthNavMenuComponent); // get test component from the fixture component = fixture.componentInstance; fixture.detectChanges(); const navMenuSelector = '.navbar-nav'; deNavMenu = fixture.debugElement.query(By.css(navMenuSelector)); const navMenuItemSelector = 'li'; deNavMenuItem = deNavMenu.query(By.css(navMenuItemSelector)); })); afterEach(() => { fixture.destroy(); component = null; }); it('should render login link', () => { const loginDropdownMenu = deNavMenuItem.query(By.css('a[id=loginLink]')); expect(loginDropdownMenu.nativeElement).toBeDefined(); }); }); describe('when user is authenticated', () => { beforeEach(inject([Store], (store: Store<AppState>) => { store .subscribe((state) => { (state as any).router = Object.create({}); (state as any).router.state = routerState; (state as any).core = Object.create({}); (state as any).core.auth = authState; }); // create component and test fixture fixture = TestBed.createComponent(AuthNavMenuComponent); // get test component from the fixture component = fixture.componentInstance; fixture.detectChanges(); const navMenuSelector = '.navbar-nav'; deNavMenu = fixture.debugElement.query(By.css(navMenuSelector)); const navMenuItemSelector = 'li'; deNavMenuItem = deNavMenu.query(By.css(navMenuItemSelector)); })); afterEach(() => { fixture.destroy(); component = null; }); it('should render logout link', inject([Store], (store: Store<AppState>) => { const logoutDropdownMenu = deNavMenuItem.query(By.css('a[id=logoutLink]')); expect(logoutDropdownMenu.nativeElement).toBeDefined(); })); }) }) });