44988: added tests

This commit is contained in:
Lotte Hofstede
2017-10-31 15:17:42 +01:00
parent 7d5dad94a1
commit 7daf6a2923
11 changed files with 173 additions and 80 deletions

View File

@@ -1,4 +0,0 @@
<div>
<button [disabled]="isList" (click)="setList(true)" class="btn"><i class="fa fa-list" aria-hidden="true"></i></button>
<button [disabled]="!isList" (click)="setList(false)" class="btn"><i class="fa fa-th-large" aria-hidden="true"></i></button>
</div>

View File

@@ -1,15 +0,0 @@
@import '../../../styles/variables.scss';
@import '../../../styles/mixins.scss';
:host {
display: inline-block;
button {
border: none;
background-color: white;
padding: 0;
color: map-get($theme-colors, primary);
i {
font-size: $button-height;
}
}
}

View File

@@ -1,23 +0,0 @@
import { Component, EventEmitter, Input, Output } from '@angular/core';
/**
* This component renders a simple item page.
* The route parameter 'id' is used to request the item it represents.
* All fields of the item that should be displayed, are defined in its template.
*/
@Component({
selector: 'ds-layout-controls',
styleUrls: ['./layout-controls.component.scss'],
templateUrl: './layout-controls.component.html',
})
export class LayoutControlsComponent {
@Input() isList = true;
@Output() toggleList = new EventEmitter<boolean>();
setList(isList: boolean) {
this.isList = isList;
this.toggleList.emit(isList);
}
}

View File

@@ -1,7 +1,6 @@
<div class="search-page"> <div class="search-page">
<ds-search-sidebar dsStick *ngIf="!(isMobileView | async)" class="col-3 sidebar-md-fixed" id="search-sidebar" <ds-search-sidebar dsStick *ngIf="!(isMobileView | async)" class="col-3 sidebar-md-fixed" id="search-sidebar"
resultCount="{{(results.pageInfo | async)?.totalElements}}" resultCount="{{(results.pageInfo | async)?.totalElements}}"></ds-search-sidebar>
(toggleSidebar)="toggle()"></ds-search-sidebar>
<div id="search-header" class="row"> <div id="search-header" class="row">
<ds-search-form id="search-form" class="col-12 col-md-9 ml-md-auto" <ds-search-form id="search-form" class="col-12 col-md-9 ml-md-auto"
[query]="query" [query]="query"
@@ -14,13 +13,13 @@
<div id="search-body" class="row-offcanvas row-offcanvas-left" [@slideInOut]="(isSidebarCollapsed | async) ? 'collapsed' : 'expanded'"> <div id="search-body" class="row-offcanvas row-offcanvas-left" [@slideInOut]="(isSidebarCollapsed | async) ? 'collapsed' : 'expanded'">
<ds-search-sidebar *ngIf="(isMobileView | async)" class="col-12" id="search-sidebar-xs" <ds-search-sidebar *ngIf="(isMobileView | async)" class="col-12" id="search-sidebar-xs"
resultCount="{{(results.pageInfo | async)?.totalElements}}" resultCount="{{(results.pageInfo | async)?.totalElements}}"
(toggleSidebar)="toggle()"></ds-search-sidebar> (toggleSidebar)="closeSidebar()" [ngbCollapse]="(isSidebarCollapsed | async)"></ds-search-sidebar>
<div id="search-content" class="col-12 col-md-9 ml-md-auto"> <div id="search-content" class="col-12 col-md-9 ml-md-auto">
<div class="d-block d-md-none search-controls clearfix"> <div class="d-block d-md-none search-controls clearfix">
<ds-view-mode-switch></ds-view-mode-switch> <ds-view-mode-switch></ds-view-mode-switch>
<button (click)="toggle()" aria-controls="#search-body" <button (click)="openSidebar()" aria-controls="#search-body"
class="btn btn-outline-primary float-right"><i class="btn btn-outline-primary float-right open-sidebar"><i
class="fa fa-sliders"></i> {{"search.sidebar.open" class="fa fa-sliders"></i> {{"search.sidebar.open"
| translate}} | translate}}
</button> </button>

View File

@@ -1,22 +1,36 @@
import { TranslateLoader, TranslateModule } from '@ngx-translate/core'; import { NO_ERRORS_SCHEMA } from '@angular/core';
import { async, ComponentFixture, TestBed } from '@angular/core/testing'; import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { ActivatedRoute, Router } from '@angular/router'; import { RouterTestingModule } from '@angular/router/testing';
import { Store } from '@ngrx/store';
import { TranslateModule } from '@ngx-translate/core';
import { Observable } from 'rxjs/Observable'; import { Observable } from 'rxjs/Observable';
import { SortDirection, SortOptions } from '../core/cache/models/sort-options.model';
import { CommunityDataService } from '../core/data/community-data.service'; import { CommunityDataService } from '../core/data/community-data.service';
import { Community } from '../core/shared/community.model';
import { HostWindowService } from '../shared/host-window.service';
import { PaginationComponentOptions } from '../shared/pagination/pagination-component-options.model';
import { SearchPageComponent } from './search-page.component'; import { SearchPageComponent } from './search-page.component';
import { SearchService } from './search-service/search.service'; import { SearchService } from './search-service/search.service';
import { Community } from '../core/shared/community.model'; import { NoopAnimationsModule } from '@angular/platform-browser/animations';
import { PaginationComponentOptions } from '../shared/pagination/pagination-component-options.model'; import { ActivatedRoute } from '@angular/router';
import { SortDirection, SortOptions } from '../core/cache/models/sort-options.model'; import {
import { NO_ERRORS_SCHEMA } from '@angular/core'; SearchSidebarCollapseAction,
import { SearchPageModule } from './search-page.module'; SearchSidebarExpandAction
import { Store } from '@ngrx/store'; } from './search-sidebar/search-sidebar.actions';
import { By } from '@angular/platform-browser';
import { NgbCollapseModule } from '@ng-bootstrap/ng-bootstrap';
fdescribe('SearchPageComponent', () => { describe('SearchPageComponent', () => {
let comp: SearchPageComponent; let comp: SearchPageComponent;
let fixture: ComponentFixture<SearchPageComponent>; let fixture: ComponentFixture<SearchPageComponent>;
let searchServiceObject: SearchService; let searchServiceObject: SearchService;
const store: Store<SearchPageComponent> = jasmine.createSpyObj('store', {
/* tslint:disable:no-empty */
dispatch: {},
/* tslint:enable:no-empty */
select: Observable.of(true)
});
const mockResults = ['test', 'data']; const mockResults = ['test', 'data'];
const searchServiceStub = { const searchServiceStub = {
search: () => mockResults search: () => mockResults
@@ -43,15 +57,25 @@ fdescribe('SearchPageComponent', () => {
beforeEach(async(() => { beforeEach(async(() => {
TestBed.configureTestingModule({ TestBed.configureTestingModule({
imports: [ SearchPageModule ], imports: [TranslateModule.forRoot(), RouterTestingModule.withRoutes([]), NoopAnimationsModule, NgbCollapseModule.forRoot()],
// declarations: [SearchPageComponent], declarations: [SearchPageComponent],
providers: [ providers: [
{ provide: SearchService, useValue: searchServiceStub }, { provide: SearchService, useValue: searchServiceStub },
{
provide: CommunityDataService,
useValue: jasmine.createSpyObj('communityService', ['findById', 'findAll'])
},
{ provide: ActivatedRoute, useValue: activatedRouteStub }, { provide: ActivatedRoute, useValue: activatedRouteStub },
{ provide: CommunityDataService, useValue: communityDataServiceStub }, {
{ provide: Router, useClass: RouterStub }, provide: Store, useValue: store
{ provide: Store, useClass: {} } },
], {
provide: HostWindowService, useValue: jasmine.createSpyObj('hostWindowService', {
isXs: Observable.of(true),
isSm: Observable.of(false)
})
}
],
schemas: [NO_ERRORS_SCHEMA] schemas: [NO_ERRORS_SCHEMA]
}).compileComponents(); }).compileComponents();
})); }));
@@ -112,4 +136,60 @@ fdescribe('SearchPageComponent', () => {
}); });
}); });
describe('when the closeSidebar event is emitted clicked in mobile view', () => {
beforeEach(() => {
const closeSidebarButton = fixture.debugElement.query(By.css('#search-sidebar-xs'));
closeSidebarButton.triggerEventHandler('toggleSidebar', null);
});
it('should dispatch a SearchSidebarCollapseAction', () => {
expect(store.dispatch).toHaveBeenCalledWith(new SearchSidebarCollapseAction());
});
});
describe('when the open sidebar button is clicked in mobile view', () => {
beforeEach(() => {
const openSidebarButton = fixture.debugElement.query(By.css('.open-sidebar'));
openSidebarButton.triggerEventHandler('click', null);
});
it('should dispatch a SearchSidebarExpandAction', () => {
expect(store.dispatch).toHaveBeenCalledWith(new SearchSidebarExpandAction());
});
});
describe('when sidebarCollapsed in the store is true in mobile view', () => {
let menu: HTMLElement;
beforeEach(() => {
menu = fixture.debugElement.query(By.css('#search-sidebar-xs')).nativeElement;
comp.isSidebarCollapsed = Observable.of(true);
fixture.detectChanges();
});
it('should close the sidebar', () => {
expect(menu.classList).not.toContain('show');
});
});
describe('when sidebarCollapsed in the store is false in mobile view', () => {
let menu: HTMLElement;
beforeEach(() => {
menu = fixture.debugElement.query(By.css('#search-sidebar-xs')).nativeElement;
comp.isSidebarCollapsed = Observable.of(false);
fixture.detectChanges();
});
it('should open the menu', () => {
expect(menu.classList).toContain('show');
});
});
}); });

View File

@@ -14,7 +14,9 @@ import { createSelector, Store } from '@ngrx/store';
import { AppState } from '../app.reducer'; import { AppState } from '../app.reducer';
import { Observable } from 'rxjs/Observable'; import { Observable } from 'rxjs/Observable';
import { SearchSidebarState } from './search-sidebar/search-sidebar.reducer'; import { SearchSidebarState } from './search-sidebar/search-sidebar.reducer';
import { SearchSidebarToggleAction } from './search-sidebar/search-sidebar.actions'; import {
SearchSidebarCollapseAction, SearchSidebarExpandAction,
} from './search-sidebar/search-sidebar.actions';
import { slideInOut } from '../shared/animations/slide'; import { slideInOut } from '../shared/animations/slide';
import { HostWindowService } from '../shared/host-window.service'; import { HostWindowService } from '../shared/host-window.service';
@@ -60,14 +62,22 @@ export class SearchPageComponent implements OnInit, OnDestroy {
pagination.pageSize = 10; pagination.pageSize = 10;
const sort: SortOptions = new SortOptions(); const sort: SortOptions = new SortOptions();
this.searchOptions = { pagination: pagination, sort: sort }; this.searchOptions = { pagination: pagination, sort: sort };
}
ngOnInit(): void {
this.isMobileView = Observable.combineLatest( this.isMobileView = Observable.combineLatest(
this.hostWindowService.isXs(), this.hostWindowService.isXs(),
this.hostWindowService.isSm(), this.hostWindowService.isSm(),
(isXs, isSm) => isXs || isSm); (isXs, isSm) => isXs || isSm);
}
ngOnInit(): void { /*
this.isSidebarCollapsed = this.store.select(sidebarCollapsedSelector); Sidebar should always be 'collapsed' when not in mobile view
*/
this.isSidebarCollapsed = Observable.combineLatest(
this.isMobileView,
this.store.select(sidebarCollapsedSelector),
(mobile, store) => mobile ? store : true);
this.sub = this.route this.sub = this.route
.queryParams .queryParams
.subscribe((params) => { .subscribe((params) => {
@@ -108,7 +118,11 @@ export class SearchPageComponent implements OnInit, OnDestroy {
this.sub.unsubscribe(); this.sub.unsubscribe();
} }
public toggle(): void { public closeSidebar(): void {
this.store.dispatch(new SearchSidebarToggleAction()); this.store.dispatch(new SearchSidebarCollapseAction());
}
public openSidebar(): void {
this.store.dispatch(new SearchSidebarExpandAction());
} }
} }

View File

@@ -1,9 +1,5 @@
import { NgModule } from '@angular/core'; import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common'; import { CommonModule } from '@angular/common';
import { RouterModule } from '@angular/router';
import { TranslateModule } from '@ngx-translate/core';
import { SharedModule } from '../shared/shared.module'; import { SharedModule } from '../shared/shared.module';
import { SearchPageRoutingModule } from './search-page-routing.module'; import { SearchPageRoutingModule } from './search-page-routing.module';
import { SearchPageComponent } from './search-page.component'; import { SearchPageComponent } from './search-page.component';
@@ -13,7 +9,6 @@ import { CollectionSearchResultListElementComponent } from '../object-list/searc
import { CommunitySearchResultListElementComponent } from '../object-list/search-result-list-element/community-search-result/community-search-result-list-element.component'; import { CommunitySearchResultListElementComponent } from '../object-list/search-result-list-element/community-search-result/community-search-result-list-element.component';
import { SearchService } from './search-service/search.service'; import { SearchService } from './search-service/search.service';
import { SearchSidebarComponent } from './search-sidebar/search-sidebar.component'; import { SearchSidebarComponent } from './search-sidebar/search-sidebar.component';
import { LayoutControlsComponent } from './layout-controls/layout-controls.component';
@NgModule({ @NgModule({
imports: [ imports: [
@@ -27,8 +22,7 @@ import { LayoutControlsComponent } from './layout-controls/layout-controls.compo
SearchSidebarComponent, SearchSidebarComponent,
ItemSearchResultListElementComponent, ItemSearchResultListElementComponent,
CollectionSearchResultListElementComponent, CollectionSearchResultListElementComponent,
CommunitySearchResultListElementComponent, CommunitySearchResultListElementComponent
LayoutControlsComponent
], ],
providers: [ providers: [
SearchService SearchService

View File

@@ -1,8 +1,8 @@
<div> <div>
<div id="sidebar-options" class="d-block d-md-none search-controls clearfix"> <div id="sidebar-options" class="d-block d-md-none search-controls clearfix">
<small class="results">{{resultCount}} {{"search.sidebar.results" | translate}}</small> <small class="results">{{resultCount}} {{"search.sidebar.results" | translate}}</small>
<button (click)="toggleSidebar.emit(false)" <button (click)="toggleSidebar.emit()"
aria-controls="#search-body" class="btn btn-outline-primary float-right"><i aria-controls="#search-body" class="btn btn-outline-primary float-right close-sidebar"><i
class="fa fa-arrow-right"></i> {{"search.sidebar.close" | translate}} class="fa fa-arrow-right"></i> {{"search.sidebar.close" | translate}}
</button> </button>
</div> </div>

View File

@@ -0,0 +1,51 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { Store, StoreModule } from '@ngrx/store';
import { TranslateModule } from '@ngx-translate/core';
import { SearchSidebarComponent } from './search-sidebar.component';
import { NgbCollapseModule } from '@ng-bootstrap/ng-bootstrap';
import { SearchSidebarState } from './search-sidebar.reducer';
import { By } from '@angular/platform-browser';
import {
SearchSidebarCollapseAction, SearchSidebarExpandAction,
} from './search-sidebar.actions';
import { Observable } from 'rxjs/Observable';
import { NO_ERRORS_SCHEMA } from '@angular/core';
import { HostWindowService } from '../../shared/host-window.service';
describe('SearchSidebarComponent', () => {
let comp: SearchSidebarComponent;
let fixture: ComponentFixture<SearchSidebarComponent>;
// async beforeEach
beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [TranslateModule.forRoot(), NgbCollapseModule.forRoot()],
declarations: [SearchSidebarComponent],
schemas: [NO_ERRORS_SCHEMA],
})
.compileComponents(); // compile template and css
}));
// synchronous beforeEach
beforeEach(() => {
fixture = TestBed.createComponent(SearchSidebarComponent);
comp = fixture.componentInstance;
});
describe('when the close sidebar button is clicked in mobile view', () => {
beforeEach(() => {
spyOn(comp.toggleSidebar, 'emit');
const closeSidebarButton = fixture.debugElement.query(By.css('button.close-sidebar'));
closeSidebarButton.triggerEventHandler('click', null);
});
it('should emit a toggleSidebar event', () => {
expect(comp.toggleSidebar.emit).toHaveBeenCalled();
});
});
});

View File

@@ -5,8 +5,6 @@ import {
SearchSidebarCollapseAction, SearchSidebarExpandAction, SearchSidebarCollapseAction, SearchSidebarExpandAction,
SearchSidebarToggleAction SearchSidebarToggleAction
} from './search-sidebar.actions'; } from './search-sidebar.actions';
import { async, TestBed } from '@angular/core/testing';
import { TranslateModule } from '@ngx-translate/core';
class NullAction extends SearchSidebarCollapseAction { class NullAction extends SearchSidebarCollapseAction {
type = null; type = null;

View File

@@ -10,7 +10,6 @@ import { HeaderComponent } from './header.component';
import { HeaderState } from './header.reducer'; import { HeaderState } from './header.reducer';
import { HeaderToggleAction } from './header.actions'; import { HeaderToggleAction } from './header.actions';
import Spy = jasmine.Spy;
let comp: HeaderComponent; let comp: HeaderComponent;
let fixture: ComponentFixture<HeaderComponent>; let fixture: ComponentFixture<HeaderComponent>;