+
+
+
{{subCategory.title}}
-
-
-
-
{{subCategory.title}}
-
-
+
diff --git a/aio/src/app/custom-elements/resource/resource-list.component.spec.ts b/aio/src/app/custom-elements/resource/resource-list.component.spec.ts
index c42ae7d01a..60a9374252 100644
--- a/aio/src/app/custom-elements/resource/resource-list.component.spec.ts
+++ b/aio/src/app/custom-elements/resource/resource-list.component.spec.ts
@@ -1,78 +1,115 @@
import { ReflectiveInjector } from '@angular/core';
-import { PlatformLocation } from '@angular/common';
import { of } from 'rxjs';
import { ResourceListComponent } from './resource-list.component';
import { ResourceService } from './resource.service';
-
+import { LocationService } from 'app/shared/location.service';
import { Category } from './resource.model';
// Testing the component class behaviors, independent of its template
// Let e2e tests verify how it displays.
describe('ResourceListComponent', () => {
+ let component: ResourceListComponent;
let injector: ReflectiveInjector;
- let location: TestPlatformLocation;
+ let resourceService: TestResourceService;
+ let locationService: TestLocationService;
+ let categories: Category[];
beforeEach(() => {
injector = ReflectiveInjector.resolveAndCreate([
ResourceListComponent,
- {provide: PlatformLocation, useClass: TestPlatformLocation },
- {provide: ResourceService, useClass: TestResourceService }
+ {provide: ResourceService, useClass: TestResourceService },
+ {provide: LocationService, useClass: TestLocationService }
]);
- location = injector.get(PlatformLocation);
+ locationService = injector.get(LocationService);
+ resourceService = injector.get(ResourceService);
+ categories = resourceService.testCategories;
});
- it('should set the location w/o leading slashes', () => {
- location.pathname = '////resources';
- const component = getComponent();
- expect(component.location).toBe('resources');
+ it('should select the first category when no query string', () => {
+ component = getComponent();
+ expect(component.selectedCategory).toBe(categories[0]);
});
- it('href(id) should return the expected href', () => {
- location.pathname = '////resources';
- const component = getComponent();
- expect(component.href({id: 'foo'})).toBe('resources#foo');
+ it('should select the first category when query string w/o "category" property', () => {
+ locationService.searchResult = { foo: 'development' };
+ component = getComponent();
+ expect(component.selectedCategory).toBe(categories[0]);
});
- it('should set scroll position to zero when no target element', () => {
- const component = getComponent();
- component.onScroll(undefined);
- expect(component.scrollPos).toBe(0);
+ it('should select the first category when query category not found', () => {
+ locationService.searchResult = { category: 'foo' };
+ component = getComponent();
+ expect(component.selectedCategory).toBe(categories[0]);
});
- it('should set scroll position to element.scrollTop when that is defined', () => {
- const component = getComponent();
- component.onScroll({scrollTop: 42});
- expect(component.scrollPos).toBe(42);
+ it('should select the education category when query category is "education"', () => {
+ locationService.searchResult = { category: 'education' };
+ component = getComponent();
+ expect(component.selectedCategory).toBe(categories[1]);
});
- it('should set scroll position to element.body.scrollTop when that is defined', () => {
- const component = getComponent();
- component.onScroll({body: {scrollTop: 42}});
- expect(component.scrollPos).toBe(42);
+ it('should select the education category when query category is "EDUCATION" (case insensitive)', () => {
+ locationService.searchResult = { category: 'EDUCATION' };
+ component = getComponent();
+ expect(component.selectedCategory).toBe(categories[1]);
});
- it('should set scroll position to 0 when no target.body.scrollTop defined', () => {
- const component = getComponent();
- component.onScroll({body: {}});
- expect(component.scrollPos).toBe(0);
+ it('should set the query to the "education" category when user selects "education"', () => {
+ component = getComponent();
+ component.selectCategory('education');
+ expect(locationService.searchResult['category']).toBe('education');
+ });
+
+ it('should set the query to the first category when user selects unknown name', () => {
+ component = getComponent();
+ component.selectCategory('education'); // a legit group that isn't the first
+
+ component.selectCategory('foo'); // not a legit group name
+ expect(locationService.searchResult['category']).toBe('development');
});
//// Test Helpers ////
- function getComponent(): ResourceListComponent { return injector.get(ResourceListComponent); }
-
- class TestPlatformLocation {
- pathname = 'resources';
+ function getComponent(): ResourceListComponent {
+ const comp = injector.get(ResourceListComponent);
+ comp.ngOnInit();
+ return comp;
}
class TestResourceService {
- categories = of(getTestData);
+ testCategories = getTestData();
+ categories = of(this.testCategories);
+ }
+
+ 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;
+ });
}
function getTestData(): Category[] {
- return []; // Not interested in the data in these tests
+ return [
+ // Not interested in the sub-categories data in these tests
+ {
+ id: 'development',
+ title: 'Development',
+ order: 0,
+ subCategories: []
+ },
+ {
+ id: 'education',
+ title: 'Education',
+ order: 1,
+ subCategories: []
+ },
+ ];
}
});
diff --git a/aio/src/app/custom-elements/resource/resource-list.component.ts b/aio/src/app/custom-elements/resource/resource-list.component.ts
index 6d9e4671a3..6b48195fa8 100644
--- a/aio/src/app/custom-elements/resource/resource-list.component.ts
+++ b/aio/src/app/custom-elements/resource/resource-list.component.ts
@@ -2,6 +2,7 @@ import { Component, OnInit } from '@angular/core';
import { Category } from './resource.model';
import { ResourceService } from './resource.service';
+import { LocationService } from 'app/shared/location.service';
/* tslint:disable:template-accessibility-elements-content */
@Component({
@@ -11,16 +12,27 @@ import { ResourceService } from './resource.service';
export class ResourceListComponent implements OnInit {
categories: Category[];
- location: string;
+ selectedCategory: Category;
constructor(
- private resourceService: ResourceService) {
- this.location = location.pathname.replace(/^\/+/, '');
+ private resourceService: ResourceService,
+ private locationService: LocationService) {
}
ngOnInit() {
+ const category = this.locationService.search()['category'] || '';
// Not using async pipe because cats appear twice in template
// No need to unsubscribe because categories observable completes.
- this.resourceService.categories.subscribe(cats => this.categories = cats);
+ this.resourceService.categories.subscribe(cats => {
+ this.categories = cats;
+ this.selectCategory(category);
+ });
+ }
+
+ selectCategory(id: string) {
+ id = id.toLowerCase();
+ this.selectedCategory =
+ this.categories.find(category => category.id.toLowerCase() === id) || this.categories[0];
+ this.locationService.setSearch('', {category: this.selectedCategory.id});
}
}
diff --git a/aio/src/styles/2-modules/_resources.scss b/aio/src/styles/2-modules/_resources.scss
index 386eac2829..890f051e96 100644
--- a/aio/src/styles/2-modules/_resources.scss
+++ b/aio/src/styles/2-modules/_resources.scss
@@ -169,6 +169,10 @@ aio-resource-list {
flex-direction: column;
}
+ .align-items-center{
+ align-items: center;
+ }
+
.c-resource-header {
margin-bottom: 16px;
}