From bb804dd3e9f06da1c2edc6ac19bfa07b5ef01865 Mon Sep 17 00:00:00 2001 From: Ward Bell Date: Wed, 21 Jun 2017 11:58:24 -0700 Subject: [PATCH] =?UTF-8?q?feat(aio):=20select=20contributor=20group=20wit?= =?UTF-8?q?h=20URL=20=E2=80=9Cabout=3Fgroup=3Dgde=E2=80=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit closes #17656 also adds test for ContributorListComponent. --- .../contributor-list.component.spec.ts | 105 ++++++++++++++++++ .../contributor/contributor-list.component.ts | 12 +- 2 files changed, 114 insertions(+), 3 deletions(-) create mode 100644 aio/src/app/embedded/contributor/contributor-list.component.spec.ts diff --git a/aio/src/app/embedded/contributor/contributor-list.component.spec.ts b/aio/src/app/embedded/contributor/contributor-list.component.spec.ts new file mode 100644 index 0000000000..6d20348747 --- /dev/null +++ b/aio/src/app/embedded/contributor/contributor-list.component.spec.ts @@ -0,0 +1,105 @@ +import { ReflectiveInjector } from '@angular/core'; + +import { of } from 'rxjs/observable/of'; + +import { ContributorGroup } from './contributors.model'; +import { ContributorListComponent } from './contributor-list.component'; +import { ContributorService } from './contributor.service'; +import { LocationService } from 'app/shared/location.service'; + +// Testing the component class behaviors, independent of its template +// Let e2e tests verify how it displays. +describe('ContributorListComponent', () => { + + let component: ContributorListComponent; + let injector: ReflectiveInjector; + let contributorService: TestContributorService; + let locationService: TestLocationService; + let contributorGroups: ContributorGroup[]; + + beforeEach(() => { + injector = ReflectiveInjector.resolveAndCreate([ + ContributorListComponent, + {provide: ContributorService, useClass: TestContributorService }, + {provide: LocationService, useClass: TestLocationService } + ]); + + locationService = injector.get(LocationService); + contributorService = injector.get(ContributorService); + contributorGroups = contributorService.testContributors; + }); + + it('should select the first group when no query string', () => { + component = getComponent(); + expect(component.selectedGroup).toBe(contributorGroups[0]); + }); + + it('should select the first group when query string w/o "group" property', () => { + locationService.searchResult = { foo: 'GDE' }; + component = getComponent(); + expect(component.selectedGroup).toBe(contributorGroups[0]); + }); + + it('should select the first group when query group not found', () => { + locationService.searchResult = { group: 'foo' }; + component = getComponent(); + expect(component.selectedGroup).toBe(contributorGroups[0]); + }); + + it('should select the GDE group when query group is "GDE"', () => { + locationService.searchResult = { group: 'GDE' }; + component = getComponent(); + expect(component.selectedGroup).toBe(contributorGroups[1]); + }); + + it('should select the GDE group when query group is "gde" (case insensitive)', () => { + locationService.searchResult = { group: 'gde' }; + component = getComponent(); + expect(component.selectedGroup).toBe(contributorGroups[1]); + }); + + it('should set the query to the "GDE" group when user selects "GDE"', () => { + component = getComponent(); + component.selectGroup('GDE'); + expect(locationService.searchResult['group']).toBe('GDE'); + }); + + it('should set the query to the first group when user selects unknown name', () => { + component = getComponent(); + component.selectGroup('GDE'); // a legit group that isn't the first + + component.selectGroup('foo'); // not a legit group name + expect(locationService.searchResult['group']).toBe('Angular'); + }); + + //// Test Helpers //// + function getComponent(): ContributorListComponent { + const comp = injector.get(ContributorListComponent); + comp.ngOnInit(); + return comp; + } + + interface SearchResult { [index: string]: string; }; + + class TestLocationService { + searchResult: SearchResult = {}; + search = jasmine.createSpy('search').and.callFake(() => this.searchResult); + setSearch = jasmine.createSpy('setSearch') + .and.callFake((label: string, result: SearchResult) => { + this.searchResult = result; + }); + } + + class TestContributorService { + testContributors = getTestData(); + contributors = of(this.testContributors); + } + + function getTestData(): ContributorGroup[] { + return [ + // Not interested in the contributors data in these tests + { name: 'Angular', order: 0, contributors: [] }, + { name: 'GDE', order: 1, contributors: [] }, + ]; + } +}); diff --git a/aio/src/app/embedded/contributor/contributor-list.component.ts b/aio/src/app/embedded/contributor/contributor-list.component.ts index c8fbacde24..c61d3454fa 100644 --- a/aio/src/app/embedded/contributor/contributor-list.component.ts +++ b/aio/src/app/embedded/contributor/contributor-list.component.ts @@ -1,6 +1,7 @@ import { Component, OnInit } from '@angular/core'; import { ContributorGroup } from './contributors.model'; import { ContributorService } from './contributor.service'; +import { LocationService } from 'app/shared/location.service'; @Component({ selector: `aio-contributor-list`, @@ -22,19 +23,24 @@ export class ContributorListComponent implements OnInit { groupNames: string[]; selectedGroup: ContributorGroup; - constructor(private contributorService: ContributorService) { } + constructor( + private contributorService: ContributorService, + private locationService: LocationService) { } ngOnInit() { + const groupName = this.locationService.search()['group'] || ''; // no need to unsubscribe because `contributors` completes this.contributorService.contributors .subscribe(grps => { this.groups = grps; this.groupNames = grps.map(g => g.name); - this.selectGroup(grps[0].name); + this.selectGroup(groupName); }); } selectGroup(name) { - this.selectedGroup = this.groups.find(g => g.name === name); + name = name.toLowerCase(); + this.selectedGroup = this.groups.find(g => g.name.toLowerCase() === name) || this.groups[0]; + this.locationService.setSearch('', {group: this.selectedGroup.name}); } }