| 
									
										
										
										
											2016-09-13 14:39:39 -07:00
										 |  |  | // #docplaster
 | 
					
						
							|  |  |  | import { async, inject, ComponentFixture, TestBed | 
					
						
							|  |  |  | } from '@angular/core/testing'; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-21 20:01:44 -07:00
										 |  |  | import { addMatchers, click } from '../../testing'; | 
					
						
							|  |  |  | import { HeroService }        from '../model'; | 
					
						
							|  |  |  | import { FakeHeroService }    from '../model/testing'; | 
					
						
							| 
									
										
										
										
											2016-09-13 14:39:39 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | import { By }     from '@angular/platform-browser'; | 
					
						
							|  |  |  | import { Router } from '@angular/router'; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import { DashboardComponent } from './dashboard.component'; | 
					
						
							|  |  |  | import { DashboardModule }    from './dashboard.module'; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-17 12:44:34 -07:00
										 |  |  | // #docregion router-stub
 | 
					
						
							|  |  |  | class RouterStub { | 
					
						
							| 
									
										
										
										
											2016-09-19 19:57:59 -07:00
										 |  |  |   navigateByUrl(url: string) { return url; } | 
					
						
							| 
									
										
										
										
											2016-09-13 14:39:39 -07:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2016-09-17 12:44:34 -07:00
										 |  |  | // #enddocregion router-stub
 | 
					
						
							| 
									
										
										
										
											2016-09-13 14:39:39 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | beforeEach ( addMatchers ); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | let comp: DashboardComponent; | 
					
						
							|  |  |  | let fixture: ComponentFixture<DashboardComponent>; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ////////  Deep  ////////////////
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | describe('DashboardComponent (deep)', () => { | 
					
						
							|  |  |  |   beforeEach(() => { | 
					
						
							|  |  |  |     TestBed.configureTestingModule({ | 
					
						
							|  |  |  |       imports: [ DashboardModule ] | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   compileAndCreate(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   tests(clickForDeep); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   function clickForDeep() { | 
					
						
							|  |  |  |     // get first <div class="hero"> DebugElement
 | 
					
						
							|  |  |  |     const heroEl = fixture.debugElement.query(By.css('.hero')); | 
					
						
							| 
									
										
										
										
											2016-09-21 20:01:44 -07:00
										 |  |  |     click(heroEl); | 
					
						
							| 
									
										
										
										
											2016-09-13 14:39:39 -07:00
										 |  |  |   } | 
					
						
							|  |  |  | }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ////////  Shallow ////////////////
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import { NO_ERRORS_SCHEMA } from '@angular/core'; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | describe('DashboardComponent (shallow)', () => { | 
					
						
							|  |  |  |   beforeEach(() => { | 
					
						
							|  |  |  |     TestBed.configureTestingModule({ | 
					
						
							|  |  |  |       declarations: [ DashboardComponent ], | 
					
						
							|  |  |  |       schemas:      [NO_ERRORS_SCHEMA] | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   compileAndCreate(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   tests(clickForShallow); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   function clickForShallow() { | 
					
						
							|  |  |  |     // get first <dashboard-hero> DebugElement
 | 
					
						
							|  |  |  |     const heroEl = fixture.debugElement.query(By.css('dashboard-hero')); | 
					
						
							|  |  |  |     heroEl.triggerEventHandler('selected', comp.heroes[0]); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /** Add TestBed providers, compile, and create DashboardComponent */ | 
					
						
							|  |  |  | function compileAndCreate() { | 
					
						
							|  |  |  |   // #docregion compile-and-create-body
 | 
					
						
							|  |  |  |   beforeEach( async(() => { | 
					
						
							|  |  |  |     TestBed.configureTestingModule({ | 
					
						
							|  |  |  |       providers: [ | 
					
						
							|  |  |  |         { provide: HeroService, useClass: FakeHeroService }, | 
					
						
							| 
									
										
										
										
											2016-09-17 12:44:34 -07:00
										 |  |  |         { provide: Router,      useClass: RouterStub } | 
					
						
							| 
									
										
										
										
											2016-09-13 14:39:39 -07:00
										 |  |  |       ] | 
					
						
							|  |  |  |     }) | 
					
						
							|  |  |  |     .compileComponents().then(() => { | 
					
						
							|  |  |  |       fixture = TestBed.createComponent(DashboardComponent); | 
					
						
							|  |  |  |       comp = fixture.componentInstance; | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  |     // #enddocregion compile-and-create-body
 | 
					
						
							|  |  |  |   })); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /** | 
					
						
							|  |  |  |  * The (almost) same tests for both. | 
					
						
							|  |  |  |  * Only change: the way that the first hero is clicked | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | function tests(heroClick: Function) { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   it('should NOT have heroes before ngOnInit', () => { | 
					
						
							|  |  |  |     expect(comp.heroes.length).toBe(0, | 
					
						
							|  |  |  |       'should not have heroes before ngOnInit'); | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   it('should NOT have heroes immediately after ngOnInit', () => { | 
					
						
							|  |  |  |     fixture.detectChanges(); // runs initial lifecycle hooks
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     expect(comp.heroes.length).toBe(0, | 
					
						
							|  |  |  |       'should not have heroes until service promise resolves'); | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   describe('after get dashboard heroes', () => { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |      // Trigger component so it gets heroes and binds to them
 | 
					
						
							|  |  |  |      beforeEach( async(() => { | 
					
						
							|  |  |  |         fixture.detectChanges(); // runs ngOnInit -> getHeroes
 | 
					
						
							|  |  |  |         fixture.whenStable() // No need for the `lastPromise` hack!
 | 
					
						
							|  |  |  |           .then(() => fixture.detectChanges()); // bind to heroes
 | 
					
						
							|  |  |  |      })); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it('should HAVE heroes', () => { | 
					
						
							|  |  |  |       expect(comp.heroes.length).toBeGreaterThan(0, | 
					
						
							|  |  |  |         'should have heroes after service promise resolves'); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it('should DISPLAY heroes', () => { | 
					
						
							|  |  |  |       // Find and examine the displayed heroes
 | 
					
						
							|  |  |  |       // Look for them in the DOM by css class
 | 
					
						
							|  |  |  |       const heroes = fixture.debugElement.queryAll(By.css('dashboard-hero')); | 
					
						
							|  |  |  |       expect(heroes.length).toBe(4, 'should display 4 heroes'); | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // #docregion navigate-test, inject
 | 
					
						
							|  |  |  |     it('should tell ROUTER to navigate when hero clicked', | 
					
						
							|  |  |  |       inject([Router], (router: Router) => { // ...
 | 
					
						
							|  |  |  |     // #enddocregion inject
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       const spy = spyOn(router, 'navigateByUrl'); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       heroClick(); // trigger click on first inner <div class="hero">
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       // args passed to router.navigateByUrl()
 | 
					
						
							|  |  |  |       const navArgs = spy.calls.first().args[0]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       // expecting to navigate to id of the component's first hero
 | 
					
						
							|  |  |  |       const id = comp.heroes[0].id; | 
					
						
							|  |  |  |       expect(navArgs).toBe('/heroes/' + id, | 
					
						
							|  |  |  |         'should nav to HeroDetail for first hero'); | 
					
						
							|  |  |  |     // #docregion inject
 | 
					
						
							|  |  |  |     })); | 
					
						
							|  |  |  |     // #enddocregion navigate-test, inject
 | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 |