Created
February 9, 2018 16:15
-
-
Save ratbeard/4dc5bd675b25e0540df74aa49ec44c4b to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import { SearchInputModule } from './../search-input/search-input.module'; | |
| import { GetRecordsServiceMock } from './../get-records.service.mock'; | |
| import { AppConfigServiceMock } from './../app-config-service/app-config-service.mock'; | |
| import { AppConfigService } from './../app-config-service/app-config.service'; | |
| import { MaterialModule } from '@angular/material'; | |
| import { SorterComponent } from './../sorter/sorter.component'; | |
| import { ScormDisclaimerComponent } from './../scorm-disclaimer/scorm-disclaimer.component'; | |
| import { GetRecordsService } from './../get-records.service'; | |
| import { FilterBySystemComponent } from './../filter-by-system/filter-by-system.component'; | |
| import { LearningContentTableComponent } from './../learning-content-table/learning-content-table.component'; | |
| import { TitleBarComponent } from './../title-bar/title-bar.component'; | |
| import { PaginatorComponent } from './../paginator/paginator.component'; | |
| import { MainNavigationComponent } from './../main-navigation/main-navigation.component'; | |
| /* tslint:disable:no-unused-variable */ | |
| import { async, ComponentFixture, TestBed } from '@angular/core/testing'; | |
| import { By } from '@angular/platform-browser'; | |
| import { DebugElement } from '@angular/core'; | |
| import { LocalforageService } from './../local-forage/local-forage.service'; | |
| import { LearningPlanComponent } from './learning-plan.component'; | |
| describe('LearningPlanComponent', () => { | |
| let component: LearningPlanComponent; | |
| let fixture: ComponentFixture<LearningPlanComponent>; | |
| beforeEach(async(() => { | |
| TestBed.configureTestingModule({ | |
| imports: [ MaterialModule, SearchInputModule ], | |
| declarations: [ | |
| LearningPlanComponent, | |
| MainNavigationComponent, | |
| PaginatorComponent, | |
| TitleBarComponent, | |
| LearningContentTableComponent, | |
| FilterBySystemComponent, | |
| ScormDisclaimerComponent, | |
| SorterComponent], | |
| providers: [ | |
| { provide: AppConfigService, useClass: AppConfigServiceMock }, | |
| { provide: GetRecordsService, useClass: GetRecordsServiceMock }, | |
| { provide: LocalforageService, useClass: LocalforageService }, | |
| ] | |
| }) | |
| .compileComponents(); | |
| })); | |
| beforeEach(() => { | |
| fixture = TestBed.createComponent(LearningPlanComponent); | |
| component = fixture.componentInstance; | |
| fixture.detectChanges(); | |
| }); | |
| it('should create', () => { | |
| expect(component).toBeTruthy(); | |
| }); | |
| }); |
Here's one of ours for comparison:
import { BrowserModule, By } from '@angular/platform-browser';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { FlexLayoutModule } from '@angular/flex-layout';
import { HttpClientModule } from '@angular/common/http';
import { NgModule, CUSTOM_ELEMENTS_SCHEMA, NO_ERRORS_SCHEMA, DebugElement } from '@angular/core';
import { TestBed, async, ComponentFixture, ComponentFixtureAutoDetect, tick } from '@angular/core/testing';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/observable/of';
import { AppComponent } from './app.component';
import { MaterialModule } from './material.module';
import { AnalyticsService, ListService, TrackingService, WindowRef } from './services';
import { IItem, IResponse, Client } from './models';
import * as URI from 'urijs';
import { } from 'jasmine';
import 'jest-preset-angular';
const AUTH = require('../assets/data/auth.json');
const TRACKERS = require('../assets/data/trackers.json');
const EMPTY_TRACKERS = require('../assets/data/empty_trackers.json');
const ANALYTICS = require('../assets/data/analytics.json');
const RESPONSE = require('../assets/data/response.json');
const URL = 'http://manage.myalerts.com/acme/fakeauthkey/somepath/?utm_campaign=test&utm_medium=email&utm_source=price_drop';
describe('AppComponent', () => {
let fixture: ComponentFixture<AppComponent>;
let de: DebugElement;
let comp: AppComponent;
let el: HTMLElement;
let trackingService: TrackingService;
let authSpy: any;
let getTrackersSpy: any;
let analyticsService: AnalyticsService;
let recordEventSpy: any;
// Asynchronous, so external component templates load
beforeEach(async(() => {
// Create an Angular testing module
TestBed.configureTestingModule({
declarations: [
AppComponent // declare the test component
],
imports: [
BrowserModule,
MaterialModule,
FlexLayoutModule,
BrowserAnimationsModule,
HttpClientModule
],
providers: [
AnalyticsService,
ListService,
TrackingService,
WindowRef,
{ provide: ComponentFixtureAutoDetect, useValue: true }
]
}).compileComponents(); // compile template and css
}));
// Synchronous. Waits for async to complete first.
beforeEach(() => {
fixture = TestBed.createComponent(AppComponent); // Gain access to Testbed features
de = fixture.debugElement; // test helper
comp = de.componentInstance; // access properties and methods
el = de.nativeElement; // access DOM
// Get injected services for spies
trackingService = de.injector.get(TrackingService);
analyticsService = de.injector.get(AnalyticsService);
// Setup spies
authSpy = jest.spyOn(trackingService, 'auth');
getTrackersSpy = jest.spyOn(trackingService, 'getTrackers');
recordEventSpy = jest.spyOn(analyticsService, 'recordEvent');
// Mock response data for every test
authSpy.mockReturnValue(Observable.of(AUTH));
recordEventSpy.mockReturnValue(Observable.of(ANALYTICS));
// Mock url
comp.uri = new URI(URL);
});
afterEach(() => {
jest.resetAllMocks();
jest.restoreAllMocks();
});
function init() {
comp.ngOnInit();
fixture.detectChanges();
}
it(`should create the app`, () => {
expect(comp).toBeTruthy();
});
describe('Static', () => {
it(`should render page title`, () => {
expect(comp.title).toEqual('Manage Alerts');
});
it(`should render subtitle `, () => {
expect(el.querySelector('header .subtitle').textContent).toBe('Manage Alerts');
});
it(`should render copyright in footer`, () => {
expect(el.querySelector('mat-toolbar p').textContent).toBe('© 2017 MyAlerts LLC. All rights reserved.');
});
});
describe('Theme', () => {
it(`should set correct theme if theme not set in url`, () => {
getTrackersSpy.mockReturnValue(Observable.of(TRACKERS));
init();
expect(comp.theme).toBe('theme-light');
});
it(`should set correct theme if theme set incorrectly`, () => {
getTrackersSpy.mockReturnValue(Observable.of(TRACKERS));
comp.uri = new URI('http://manage.myalerts.com/?theme=random');
init();
expect(comp.theme).toBe('theme-light');
});
it(`should set correct theme if 'theme=light'`, () => {
getTrackersSpy.mockReturnValue(Observable.of(TRACKERS));
comp.uri = new URI('http://manage.myalerts.com/?theme=light');
init();
expect(comp.theme).toBe('theme-light');
});
it(`should correct theme if 'theme=dark'`, () => {
getTrackersSpy.mockReturnValue(Observable.of(TRACKERS));
comp.uri = new URI('http://manage.myalerts.com/?theme=dark');
init();
expect(comp.theme).toBe('theme-dark');
});
});
describe('Auth', () => {
it(`should read an auth key from the 2nd url path segment`, () => {
getTrackersSpy.mockReturnValue(Observable.of(TRACKERS));
init();
expect(comp.authKey).toBe('fakeauthkey');
});
it(`should not read an auth key from the 1st url path segment`, () => {
comp.uri = new URI('http://manage.myalerts.com/fakeauthkey/');
init();
expect(comp.authKey).not.toBe('fakeauthkey');
});
it(`should set the client name from auth data`, () => {
getTrackersSpy.mockReturnValue(Observable.of(TRACKERS));
init();
expect(el.querySelector('h1.title').textContent).toBe('Acme');
});
it(`should set logo src from auth data`, () => {
getTrackersSpy.mockReturnValue(Observable.of(TRACKERS));
init();
expect(el.querySelector('.logo img').attributes.getNamedItem('src').value).toBe('https://logo.clearbit.com/myalerts.com');
});
it(`should not display logo if client domain missing from auth data`, () => {
AUTH.data.client_website_url = null;
authSpy.mockReturnValue(Observable.of(AUTH));
getTrackersSpy.mockReturnValue(Observable.of(TRACKERS));
init();
expect(el.querySelector('.logo')).toBe(null);
});
});
describe('Message', () => {
it(`should render default message`, () => {
expect(el.querySelector('article.message h2').textContent).toBe('Sorry, there was an error processing your request.');
});
it(`should show message if user has no trackers`, () => {
getTrackersSpy.mockReturnValue(Observable.of(EMPTY_TRACKERS));
init();
expect(el.querySelector('article.message h2').textContent).toBe('You currently have no alerts to manage.');
});
it(`should not show message if user has trackers`, () => {
getTrackersSpy.mockReturnValue(Observable.of(TRACKERS));
init();
expect(el.querySelector('article.message h2')).toBeNull();
});
});
describe('Cards', () => {
it(`should not show cards if user has no trackers`, () => {
getTrackersSpy.mockReturnValue(Observable.of(EMPTY_TRACKERS));
init();
expect(el.querySelector('mat-card')).toBeNull();
});
it(`should show cards if user has trackers`, () => {
getTrackersSpy.mockReturnValue(Observable.of(TRACKERS));
init();
expect(el.querySelectorAll('mat-card')).not.toBeNull();
});
it(`should show the same number of cards as trackers`, () => {
getTrackersSpy.mockReturnValue(Observable.of(TRACKERS));
init();
expect(el.querySelectorAll('mat-card').length).toBe(TRACKERS.trackers.length);
});
it(`should display correct titles on cards`, () => {
getTrackersSpy.mockReturnValue(Observable.of(TRACKERS));
init();
de.queryAll(By.css('mat-card-title')).forEach((item, i) => {
expect(item.nativeElement.textContent.trim()).toBe(TRACKERS.trackers[i].item.current_record.title);
});
});
});
describe('Card Actions', () => {
it(`should go to url if card image clicked`, () => {
const spy = jest.spyOn(comp, 'goTo');
getTrackersSpy.mockReturnValue(Observable.of(TRACKERS));
init();
de.queryAll(By.css('mat-card-content img')).forEach((element) => {
element.triggerEventHandler('click', null);
});
fixture.detectChanges();
expect(spy).toHaveBeenCalledTimes(TRACKERS.trackers.length);
});
it(`should go to url if jump icon clicked`, () => {
const spy = jest.spyOn(comp, 'goTo');
getTrackersSpy.mockReturnValue(Observable.of(TRACKERS));
init();
de.queryAll(By.css('.mat-icon-button')).forEach((element) => {
element.triggerEventHandler('click', null);
});
fixture.detectChanges();
expect(spy).toHaveBeenCalledTimes(TRACKERS.trackers.length);
});
it(`should unsubscribe if toggled OFF`, () => {
const spy = jest.spyOn(trackingService, 'removeItem').mockReturnValue(Observable.of(RESPONSE));
getTrackersSpy.mockReturnValue(Observable.of(TRACKERS));
init();
de.queryAll(By.css('.mat-slide-toggle')).forEach((element, i) => {
const item = de.injector.get(ListService).marshalItem(TRACKERS.trackers[i]);
const e = {
checked: false,
item: item
};
element.triggerEventHandler('change', e);
});
fixture.detectChanges();
expect(spy).toHaveBeenCalledTimes(3);
});
it(`should subscribe if toggled ON`, () => {
const spy = jest.spyOn(trackingService, 'createItem').mockReturnValue(Observable.of(RESPONSE));
getTrackersSpy.mockReturnValue(Observable.of(TRACKERS));
init();
de.queryAll(By.css('.mat-slide-toggle')).forEach((element, i) => {
const item = de.injector.get(ListService).marshalItem(TRACKERS.trackers[i]);
const e = {
checked: true,
item: item
};
element.triggerEventHandler('change', e);
});
fixture.detectChanges();
expect(spy).toHaveBeenCalledTimes(3);
});
});
});
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
You could probably pull a ton of that out and just put it in a different module and then reduce it to: