mirror of
https://github.com/DSpace/dspace-angular.git
synced 2025-10-13 21:13:07 +00:00
almost finished date widget
This commit is contained in:
@@ -104,9 +104,9 @@
|
||||
"methods": "1.1.2",
|
||||
"moment": "^2.22.1",
|
||||
"morgan": "1.9.0",
|
||||
"ng2-nouislider": "^1.7.7",
|
||||
"ng2-nouislider": "1.7.8",
|
||||
"ngx-pagination": "3.0.3",
|
||||
"nouislider": "^10.0.0",
|
||||
"nouislider": "^11.0.0",
|
||||
"pem": "1.12.3",
|
||||
"reflect-metadata": "0.1.12",
|
||||
"rxjs": "5.5.6",
|
||||
|
@@ -1,8 +1,7 @@
|
||||
import { Component, InjectionToken, Injector, Input, OnInit } from '@angular/core';
|
||||
import { Component, Injector, Input, OnInit } from '@angular/core';
|
||||
import { renderFilterType } from '../search-filter-type-decorator';
|
||||
import { FilterType } from '../../../search-service/filter-type.model';
|
||||
import { SearchFilterConfig } from '../../../search-service/search-filter-config.model';
|
||||
import { GlobalConfig } from '../../../../../config/global-config.interface';
|
||||
import { FILTER_CONFIG, SELECTED_VALUES } from '../search-filter.service';
|
||||
import { Observable } from 'rxjs/Observable';
|
||||
|
||||
|
@@ -2,7 +2,7 @@ import { ChangeDetectionStrategy, NO_ERRORS_SCHEMA } from '@angular/core';
|
||||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
import { NoopAnimationsModule } from '@angular/platform-browser/animations';
|
||||
import { SearchFilterService } from '../search-filter.service';
|
||||
import { FILTER_CONFIG, SearchFilterService, SELECTED_VALUES } from '../search-filter.service';
|
||||
import { SearchFilterConfig } from '../../../search-service/search-filter-config.model';
|
||||
import { FilterType } from '../../../search-service/filter-type.model';
|
||||
import { FacetValue } from '../../../search-service/facet-value.model';
|
||||
@@ -17,7 +17,7 @@ import { RouterStub } from '../../../../shared/testing/router-stub';
|
||||
import { Router } from '@angular/router';
|
||||
import { BehaviorSubject } from 'rxjs/BehaviorSubject';
|
||||
import { PageInfo } from '../../../../core/shared/page-info.model';
|
||||
import { SearchFacetFilterComponent } from '../search-facet-filter/search-facet-filter.component';
|
||||
import { SearchFacetFilterComponent } from './search-facet-filter.component';
|
||||
|
||||
describe('SearchFacetFilterComponent', () => {
|
||||
let comp: SearchFacetFilterComponent;
|
||||
@@ -64,6 +64,8 @@ describe('SearchFacetFilterComponent', () => {
|
||||
providers: [
|
||||
{ provide: SearchService, useValue: new SearchServiceStub(searchLink) },
|
||||
{ provide: Router, useValue: new RouterStub() },
|
||||
{ provide: FILTER_CONFIG, useValue: new SearchFilterConfig()},
|
||||
{ provide: SELECTED_VALUES, useValue: {} },
|
||||
{
|
||||
provide: SearchFilterService, useValue: {
|
||||
isFilterActiveWithValue: (paramName: string, filterValue: string) => true,
|
@@ -1,7 +1,7 @@
|
||||
<div>
|
||||
<div (click)="toggle()" class="filter-name"><h5 class="d-inline-block mb-0">{{'search.filters.filter.' + filter.name + '.head'| translate}}</h5> <span class="filter-toggle fa float-right"
|
||||
[ngClass]="(isCollapsed() | async) ? 'fa-plus' : 'fa-minus'"></span></div>
|
||||
<div [@slide]="(isCollapsed() | async) ? 'collapsed' : 'expanded'" class="search-filter-wrapper">
|
||||
<div [@slide]="(isCollapsed() | async) ? 'collapsed' : 'expanded'" class="search-filter-wrapper" [ngClass]="{'closed' : (isCollapsed() | async)}">
|
||||
<ds-search-facet-filter-wrapper [filterConfig]="filter" [selectedValues]="getSelectedValues()"></ds-search-facet-filter-wrapper>
|
||||
</div>
|
||||
</div>
|
@@ -3,7 +3,7 @@
|
||||
|
||||
:host {
|
||||
border: 1px solid map-get($theme-colors, light);
|
||||
.search-filter-wrapper {
|
||||
.search-filter-wrapper.closed {
|
||||
overflow: hidden;
|
||||
}
|
||||
.filter-toggle {
|
||||
|
@@ -1,241 +0,0 @@
|
||||
import { ChangeDetectionStrategy, NO_ERRORS_SCHEMA } from '@angular/core';
|
||||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
import { NoopAnimationsModule } from '@angular/platform-browser/animations';
|
||||
import { SearchFilterService } from '../search-filter.service';
|
||||
import { SearchFilterConfig } from '../../../search-service/search-filter-config.model';
|
||||
import { FilterType } from '../../../search-service/filter-type.model';
|
||||
import { FacetValue } from '../../../search-service/facet-value.model';
|
||||
import { FormsModule } from '@angular/forms';
|
||||
import { Observable } from 'rxjs/Observable';
|
||||
import { SearchService } from '../../../search-service/search.service';
|
||||
import { SearchServiceStub } from '../../../../shared/testing/search-service-stub';
|
||||
import { RemoteData } from '../../../../core/data/remote-data';
|
||||
import { PaginatedList } from '../../../../core/data/paginated-list';
|
||||
import { SearchOptions } from '../../../search-options.model';
|
||||
import { RouterStub } from '../../../../shared/testing/router-stub';
|
||||
import { Router } from '@angular/router';
|
||||
import { BehaviorSubject } from 'rxjs/BehaviorSubject';
|
||||
import { PageInfo } from '../../../../core/shared/page-info.model';
|
||||
import { SearchFacetFilterComponent } from '../search-facet-filter/search-facet-filter.component';
|
||||
|
||||
describe('SearchFacetFilterComponent', () => {
|
||||
let comp: SearchFacetFilterComponent;
|
||||
let fixture: ComponentFixture<SearchFacetFilterComponent>;
|
||||
const filterName1 = 'test name';
|
||||
const value1 = 'testvalue1';
|
||||
const value2 = 'test2';
|
||||
const value3 = 'another value3';
|
||||
const mockFilterConfig: SearchFilterConfig = Object.assign(new SearchFilterConfig(), {
|
||||
name: filterName1,
|
||||
type: FilterType.text,
|
||||
hasFacets: false,
|
||||
isOpenByDefault: false,
|
||||
pageSize: 2
|
||||
});
|
||||
const values: FacetValue[] = [
|
||||
{
|
||||
value: value1,
|
||||
count: 52,
|
||||
search: ''
|
||||
}, {
|
||||
value: value2,
|
||||
count: 20,
|
||||
search: ''
|
||||
}, {
|
||||
value: value3,
|
||||
count: 5,
|
||||
search: ''
|
||||
}
|
||||
];
|
||||
|
||||
const searchLink = '/search';
|
||||
const selectedValues = [value1, value2];
|
||||
let filterService;
|
||||
let searchService;
|
||||
let router;
|
||||
const page = Observable.of(0);
|
||||
|
||||
const mockValues = Observable.of(new RemoteData(false, false, true, null, new PaginatedList(new PageInfo(), values)));
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
imports: [TranslateModule.forRoot(), NoopAnimationsModule, FormsModule],
|
||||
declarations: [SearchFacetFilterComponent],
|
||||
providers: [
|
||||
{ provide: SearchService, useValue: new SearchServiceStub(searchLink) },
|
||||
{ provide: Router, useValue: new RouterStub() },
|
||||
{
|
||||
provide: SearchFilterService, useValue: {
|
||||
isFilterActiveWithValue: (paramName: string, filterValue: string) => true,
|
||||
getPage: (paramName: string) => page,
|
||||
/* tslint:disable:no-empty */
|
||||
incrementPage: (filterName: string) => {
|
||||
},
|
||||
resetPage: (filterName: string) => {
|
||||
},
|
||||
getSearchOptions: () => Observable.of({}),
|
||||
/* tslint:enable:no-empty */
|
||||
}
|
||||
}
|
||||
],
|
||||
schemas: [NO_ERRORS_SCHEMA]
|
||||
}).overrideComponent(SearchFacetFilterComponent, {
|
||||
set: { changeDetection: ChangeDetectionStrategy.Default }
|
||||
}).compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(SearchFacetFilterComponent);
|
||||
comp = fixture.componentInstance; // SearchPageComponent test instance
|
||||
comp.filterConfig = mockFilterConfig;
|
||||
comp.filterValues = [mockValues];
|
||||
comp.filterValues$ = new BehaviorSubject(comp.filterValues);
|
||||
comp.selectedValues = selectedValues;
|
||||
filterService = (comp as any).filterService;
|
||||
searchService = (comp as any).searchService;
|
||||
spyOn(searchService, 'getFacetValuesFor').and.returnValue(mockValues);
|
||||
router = (comp as any).router;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
describe('when the isChecked method is called with a value', () => {
|
||||
beforeEach(() => {
|
||||
spyOn(filterService, 'isFilterActiveWithValue');
|
||||
comp.isChecked(values[1]);
|
||||
});
|
||||
|
||||
it('should call isFilterActiveWithValue on the filterService with the correct filter parameter name and the passed value', () => {
|
||||
expect(filterService.isFilterActiveWithValue).toHaveBeenCalledWith(mockFilterConfig.paramName, values[1].value)
|
||||
});
|
||||
});
|
||||
|
||||
describe('when the getSearchLink method is triggered', () => {
|
||||
let link: string;
|
||||
beforeEach(() => {
|
||||
link = comp.getSearchLink();
|
||||
});
|
||||
|
||||
it('should return the value of the searchLink variable in the filter service', () => {
|
||||
expect(link).toEqual(searchLink);
|
||||
});
|
||||
});
|
||||
|
||||
describe('when the getAddParams method is called wih a value', () => {
|
||||
it('should return the selectedValue list with the new parameter value', () => {
|
||||
const result = comp.getAddParams(value3);
|
||||
expect(result[mockFilterConfig.paramName]).toEqual([value1, value2, value3]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('when the getRemoveParams method is called wih a value', () => {
|
||||
it('should return the selectedValue list with the parameter value left out', () => {
|
||||
const result = comp.getRemoveParams(value1);
|
||||
expect(result[mockFilterConfig.paramName]).toEqual([value2]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('when the showMore method is called', () => {
|
||||
beforeEach(() => {
|
||||
spyOn(filterService, 'incrementPage');
|
||||
comp.showMore();
|
||||
});
|
||||
|
||||
it('should call incrementPage on the filterService with the correct filter parameter name', () => {
|
||||
expect(filterService.incrementPage).toHaveBeenCalledWith(mockFilterConfig.name)
|
||||
});
|
||||
});
|
||||
|
||||
describe('when the showFirstPageOnly method is called', () => {
|
||||
beforeEach(() => {
|
||||
spyOn(filterService, 'resetPage');
|
||||
comp.showFirstPageOnly();
|
||||
});
|
||||
|
||||
it('should call resetPage on the filterService with the correct filter parameter name', () => {
|
||||
expect(filterService.resetPage).toHaveBeenCalledWith(mockFilterConfig.name);
|
||||
});
|
||||
});
|
||||
|
||||
describe('when the getCurrentPage method is called', () => {
|
||||
beforeEach(() => {
|
||||
spyOn(filterService, 'getPage');
|
||||
comp.getCurrentPage();
|
||||
});
|
||||
|
||||
it('should call getPage on the filterService with the correct filter parameter name', () => {
|
||||
expect(filterService.getPage).toHaveBeenCalledWith(mockFilterConfig.name)
|
||||
});
|
||||
});
|
||||
|
||||
describe('when the getCurrentUrl method is called', () => {
|
||||
const url = 'test.url/test'
|
||||
beforeEach(() => {
|
||||
router.navigateByUrl(url);
|
||||
});
|
||||
|
||||
it('should call getPage on the filterService with the correct filter parameter name', () => {
|
||||
expect(router.url).toEqual(url);
|
||||
});
|
||||
});
|
||||
|
||||
describe('when the onSubmit method is called with data', () => {
|
||||
const searchUrl = '/search/path';
|
||||
const testValue = 'test';
|
||||
const data = { [mockFilterConfig.paramName]: testValue };
|
||||
beforeEach(() => {
|
||||
spyOn(comp, 'getSearchLink').and.returnValue(searchUrl);
|
||||
comp.onSubmit(data);
|
||||
});
|
||||
|
||||
it('should call navigate on the router with the right searchlink and parameters', () => {
|
||||
expect(router.navigate).toHaveBeenCalledWith([searchUrl], {
|
||||
queryParams: { [mockFilterConfig.paramName]: [...selectedValues, testValue] },
|
||||
queryParamsHandling: 'merge'
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('when updateFilterValueList is called', () => {
|
||||
const cPage = 10;
|
||||
const searchOptions = new SearchOptions();
|
||||
beforeEach(() => {
|
||||
// spyOn(searchService, 'getFacetValuesFor'); Already spied upon
|
||||
comp.currentPage = Observable.of(cPage);
|
||||
comp.updateFilterValueList(searchOptions);
|
||||
});
|
||||
|
||||
it('should call getFacetValuesFor on the searchService with the correct parameters', () => {
|
||||
expect(searchService.getFacetValuesFor).toHaveBeenCalledWith(mockFilterConfig, cPage, searchOptions);
|
||||
});
|
||||
});
|
||||
|
||||
describe('when updateFilterValueList is called and pageChange is set to true', () => {
|
||||
const searchOptions = new SearchOptions();
|
||||
beforeEach(() => {
|
||||
comp.pageChange = true;
|
||||
spyOn(comp, 'showFirstPageOnly');
|
||||
comp.updateFilterValueList(searchOptions);
|
||||
});
|
||||
|
||||
it('should not call showFirstPageOnly on the component', () => {
|
||||
expect(comp.showFirstPageOnly).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should set pageChange to false', () => {
|
||||
expect(comp.pageChange).toBeFalsy();
|
||||
});
|
||||
});
|
||||
|
||||
describe('when updateFilterValueList is called and pageChange is set to false', () => {
|
||||
const searchOptions = new SearchOptions();
|
||||
beforeEach(() => {
|
||||
comp.pageChange = false;
|
||||
spyOn(comp, 'showFirstPageOnly');
|
||||
comp.updateFilterValueList(searchOptions);
|
||||
});
|
||||
|
||||
it('should call showFirstPageOnly on the component', () => {
|
||||
expect(comp.showFirstPageOnly).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
});
|
@@ -20,6 +20,4 @@ import { SearchFacetFilterComponent } from '../search-facet-filter/search-facet-
|
||||
@renderFacetFor(FilterType.hierarchy)
|
||||
export class SearchHierarchyFilterComponent extends SearchFacetFilterComponent implements OnInit {
|
||||
currentPage: Observable<number>;
|
||||
|
||||
|
||||
}
|
||||
|
@@ -1,3 +1,4 @@
|
||||
<script src="search-range-filter.component.ts"></script>
|
||||
<div>
|
||||
<div class="filters">
|
||||
<form #form="ngForm" (ngSubmit)="onSubmit(form.value)" class="add-filter row"
|
||||
@@ -17,7 +18,7 @@
|
||||
<input type="submit" class="d-none"/>
|
||||
</form>
|
||||
<nouislider [connect]="true" [min]="min" [max]="max" [step]="1"
|
||||
[(ngModel)]="range" (mouseup)="onSubmit(form.value)"></nouislider>
|
||||
[(ngModel)]="range" (mouseup)="onSubmit(form.value)" ngDefaultControl></nouislider>
|
||||
|
||||
<ng-container *ngFor="let page of (filterValues$ | async)">
|
||||
<ng-container *ngFor="let value of (page | async)?.payload.page">
|
||||
|
@@ -1,8 +1,10 @@
|
||||
@import '../../../../../styles/variables.scss';
|
||||
@import '../../../../../styles/mixins.scss';
|
||||
|
||||
.filters {
|
||||
|
||||
.filters {
|
||||
margin-top: $spacer/2;
|
||||
margin-bottom: $spacer/2;
|
||||
a {
|
||||
color: $link-color;
|
||||
&:hover {
|
||||
@@ -11,4 +13,26 @@
|
||||
|
||||
}
|
||||
}
|
||||
.toggle-more-filters a {
|
||||
color: $link-color;
|
||||
text-decoration: underline;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
|
||||
$slider-handle-width: 18px;
|
||||
::ng-deep
|
||||
{
|
||||
html:not([dir=rtl]) .noUi-horizontal .noUi-handle {
|
||||
right: -$slider-handle-width/2;
|
||||
}
|
||||
.noUi-horizontal .noUi-handle {
|
||||
width: $slider-handle-width;
|
||||
&:before {
|
||||
left: ($slider-handle-width - 2)/2 - 2;
|
||||
}
|
||||
&:after {
|
||||
left: ($slider-handle-width - 2)/2 + 2;
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,139 @@
|
||||
import { ChangeDetectionStrategy, NO_ERRORS_SCHEMA } from '@angular/core';
|
||||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
import { NoopAnimationsModule } from '@angular/platform-browser/animations';
|
||||
import { FILTER_CONFIG, SearchFilterService, SELECTED_VALUES } from '../search-filter.service';
|
||||
import { SearchFilterConfig } from '../../../search-service/search-filter-config.model';
|
||||
import { FilterType } from '../../../search-service/filter-type.model';
|
||||
import { FacetValue } from '../../../search-service/facet-value.model';
|
||||
import { FormsModule } from '@angular/forms';
|
||||
import { Observable } from 'rxjs/Observable';
|
||||
import { SearchService } from '../../../search-service/search.service';
|
||||
import { SearchServiceStub } from '../../../../shared/testing/search-service-stub';
|
||||
import { RemoteData } from '../../../../core/data/remote-data';
|
||||
import { PaginatedList } from '../../../../core/data/paginated-list';
|
||||
import { RouterStub } from '../../../../shared/testing/router-stub';
|
||||
import { ActivatedRoute, Router } from '@angular/router';
|
||||
import { BehaviorSubject } from 'rxjs/BehaviorSubject';
|
||||
import { PageInfo } from '../../../../core/shared/page-info.model';
|
||||
import { SearchRangeFilterComponent } from './search-range-filter.component';
|
||||
import { MockActivatedRoute } from '../../../../shared/mocks/mock-active-router';
|
||||
|
||||
describe('SearchFacetFilterComponent', () => {
|
||||
let comp: SearchRangeFilterComponent;
|
||||
let fixture: ComponentFixture<SearchRangeFilterComponent>;
|
||||
const minSuffix = '.min';
|
||||
const maxSuffix = '.max';
|
||||
const dateFormats = ['YYYY', 'YYYY-MM', 'YYYY-MM-DD'];
|
||||
const filterName1 = 'test name';
|
||||
const value1 = '2000 - 2012';
|
||||
const value2 = '1992 - 2000';
|
||||
const value3 = '1990 - 1992';
|
||||
const mockFilterConfig: SearchFilterConfig = Object.assign(new SearchFilterConfig(), {
|
||||
name: filterName1,
|
||||
type: FilterType.range,
|
||||
hasFacets: false,
|
||||
isOpenByDefault: false,
|
||||
pageSize: 2,
|
||||
minValue: 200,
|
||||
maxValue: 3000,
|
||||
});
|
||||
const values: FacetValue[] = [
|
||||
{
|
||||
value: value1,
|
||||
count: 52,
|
||||
search: ''
|
||||
}, {
|
||||
value: value2,
|
||||
count: 20,
|
||||
search: ''
|
||||
}, {
|
||||
value: value3,
|
||||
count: 5,
|
||||
search: ''
|
||||
}
|
||||
];
|
||||
|
||||
const searchLink = '/search';
|
||||
const selectedValues = [value1];
|
||||
let filterService;
|
||||
let searchService;
|
||||
let router;
|
||||
const page = Observable.of(0);
|
||||
const activatedRouteStub = new MockActivatedRoute();
|
||||
|
||||
const mockValues = Observable.of(new RemoteData(false, false, true, null, new PaginatedList(new PageInfo(), values)));
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
imports: [TranslateModule.forRoot(), NoopAnimationsModule, FormsModule],
|
||||
declarations: [SearchRangeFilterComponent],
|
||||
providers: [
|
||||
{ provide: SearchService, useValue: new SearchServiceStub(searchLink) },
|
||||
{ provide: Router, useValue: new RouterStub() },
|
||||
{ provide: FILTER_CONFIG, useValue: mockFilterConfig},
|
||||
{ provide: SELECTED_VALUES, useValue: selectedValues },
|
||||
{ provide: ActivatedRoute, useValue: activatedRouteStub },
|
||||
{
|
||||
provide: SearchFilterService, useValue: {
|
||||
isFilterActiveWithValue: (paramName: string, filterValue: string) => true,
|
||||
getPage: (paramName: string) => page,
|
||||
/* tslint:disable:no-empty */
|
||||
incrementPage: (filterName: string) => {
|
||||
},
|
||||
resetPage: (filterName: string) => {
|
||||
},
|
||||
getSearchOptions: () => Observable.of({}),
|
||||
/* tslint:enable:no-empty */
|
||||
}
|
||||
}
|
||||
],
|
||||
schemas: [NO_ERRORS_SCHEMA]
|
||||
}).overrideComponent(SearchRangeFilterComponent, {
|
||||
set: { changeDetection: ChangeDetectionStrategy.Default }
|
||||
}).compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(SearchRangeFilterComponent);
|
||||
comp = fixture.componentInstance; // SearchPageComponent test instance
|
||||
comp.filterValues = [mockValues];
|
||||
comp.filterValues$ = new BehaviorSubject(comp.filterValues);
|
||||
filterService = (comp as any).filterService;
|
||||
searchService = (comp as any).searchService;
|
||||
spyOn(searchService, 'getFacetValuesFor').and.returnValue(mockValues);
|
||||
router = (comp as any).router;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
describe('when the getAddParams method is called wih a value', () => {
|
||||
it('should return the selectedValue list with the new parameter value', () => {
|
||||
const result = comp.getAddParams(value3);
|
||||
expect(result[mockFilterConfig.paramName + minSuffix]).toEqual(['1990']);
|
||||
expect(result[mockFilterConfig.paramName + maxSuffix]).toEqual(['1992']);
|
||||
});
|
||||
});
|
||||
|
||||
describe('when the getRemoveParams method is called wih a value', () => {
|
||||
it('should return the selectedValue list with the parameter value left out', () => {
|
||||
const result = comp.getRemoveParams(value1);
|
||||
expect(result[mockFilterConfig.paramName + minSuffix]).toBeNull();
|
||||
expect(result[mockFilterConfig.paramName + maxSuffix]).toBeNull();
|
||||
});
|
||||
});
|
||||
|
||||
describe('when the onSubmit method is called with data', () => {
|
||||
const searchUrl = '/search/path';
|
||||
const data = { [mockFilterConfig.paramName + minSuffix]: '1900', [mockFilterConfig.paramName + maxSuffix]: '1950' };
|
||||
beforeEach(() => {
|
||||
spyOn(comp, 'getSearchLink').and.returnValue(searchUrl);
|
||||
comp.onSubmit(data);
|
||||
});
|
||||
|
||||
it('should call navigate on the router with the right searchlink and parameters', () => {
|
||||
expect(router.navigate).toHaveBeenCalledWith([searchUrl], {
|
||||
queryParams: { [mockFilterConfig.paramName + minSuffix]: ['1900'], [mockFilterConfig.paramName + maxSuffix]: ['1950']},
|
||||
queryParamsHandling: 'merge'
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
@@ -14,6 +14,10 @@ import * as moment from 'moment';
|
||||
* 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.
|
||||
*/
|
||||
const minSuffix = '.min';
|
||||
const maxSuffix = '.max';
|
||||
const dateFormats = ['YYYY', 'YYYY-MM', 'YYYY-MM-DD'];
|
||||
const rangeDelimiter = '-';
|
||||
|
||||
@Component({
|
||||
selector: 'ds-search-range-filter',
|
||||
@@ -23,11 +27,9 @@ import * as moment from 'moment';
|
||||
|
||||
@renderFacetFor(FilterType.range)
|
||||
export class SearchRangeFilterComponent extends SearchFacetFilterComponent implements OnInit {
|
||||
rangeDelimiter = '-';
|
||||
min = 1950;
|
||||
max = 2018;
|
||||
range;
|
||||
dateFormats = ['YYYY', 'YYYY-MM', 'YYYY-MM-DD']
|
||||
|
||||
constructor(protected searchService: SearchService,
|
||||
protected filterService: SearchFilterService,
|
||||
@@ -40,29 +42,29 @@ export class SearchRangeFilterComponent extends SearchFacetFilterComponent imple
|
||||
|
||||
ngOnInit(): void {
|
||||
super.ngOnInit();
|
||||
this.min = moment(this.filterConfig.minValue, this.dateFormats).year() || this.min;
|
||||
this.max = moment(this.filterConfig.maxValue, this.dateFormats).year() || this.max;
|
||||
const iniMin = this.route.snapshot.queryParams[this.filterConfig.paramName + '.min'] || this.min;
|
||||
const iniMax = this.route.snapshot.queryParams[this.filterConfig.paramName + '.max'] || this.max;
|
||||
this.min = moment(this.filterConfig.minValue, dateFormats).year() || this.min;
|
||||
this.max = moment(this.filterConfig.maxValue, dateFormats).year() || this.max;
|
||||
const iniMin = this.route.snapshot.queryParams[this.filterConfig.paramName + minSuffix] || this.min;
|
||||
const iniMax = this.route.snapshot.queryParams[this.filterConfig.paramName + maxSuffix] || this.max;
|
||||
this.range = [iniMin, iniMax];
|
||||
|
||||
}
|
||||
|
||||
getAddParams(value: string) {
|
||||
const parts = value.split(this.rangeDelimiter);
|
||||
const parts = value.split(rangeDelimiter);
|
||||
const min = parts.length > 1 ? parts[0].trim() : value;
|
||||
const max = parts.length > 1 ? parts[1].trim() : value;
|
||||
return {
|
||||
[this.filterConfig.paramName + '.min']: [min],
|
||||
[this.filterConfig.paramName + '.max']: [max],
|
||||
[this.filterConfig.paramName + minSuffix]: [min],
|
||||
[this.filterConfig.paramName + maxSuffix]: [max],
|
||||
page: 1
|
||||
};
|
||||
}
|
||||
|
||||
getRemoveParams(value: string) {
|
||||
return {
|
||||
[this.filterConfig.paramName + '.min']: null,
|
||||
[this.filterConfig.paramName + '.max']: null,
|
||||
[this.filterConfig.paramName + minSuffix]: null,
|
||||
[this.filterConfig.paramName + maxSuffix]: null,
|
||||
page: 1
|
||||
};
|
||||
}
|
||||
@@ -72,8 +74,8 @@ export class SearchRangeFilterComponent extends SearchFacetFilterComponent imple
|
||||
this.router.navigate([this.getSearchLink()], {
|
||||
queryParams:
|
||||
{
|
||||
[this.filterConfig.paramName + '.min']: [data[this.filterConfig.paramName + '.min']],
|
||||
[this.filterConfig.paramName + '.max']: [data[this.filterConfig.paramName + '.max']]
|
||||
[this.filterConfig.paramName + minSuffix]: [data[this.filterConfig.paramName + minSuffix]],
|
||||
[this.filterConfig.paramName + maxSuffix]: [data[this.filterConfig.paramName + maxSuffix]]
|
||||
},
|
||||
queryParamsHandling: 'merge'
|
||||
});
|
||||
|
@@ -1,242 +0,0 @@
|
||||
import { ChangeDetectionStrategy, NO_ERRORS_SCHEMA } from '@angular/core';
|
||||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
import { RouterTestingModule } from '@angular/router/testing';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
import { NoopAnimationsModule } from '@angular/platform-browser/animations';
|
||||
import { SearchFilterService } from '../search-filter.service';
|
||||
import { SearchFilterConfig } from '../../../search-service/search-filter-config.model';
|
||||
import { FilterType } from '../../../search-service/filter-type.model';
|
||||
import { FacetValue } from '../../../search-service/facet-value.model';
|
||||
import { FormsModule } from '@angular/forms';
|
||||
import { Observable } from 'rxjs/Observable';
|
||||
import { SearchService } from '../../../search-service/search.service';
|
||||
import { SearchServiceStub } from '../../../../shared/testing/search-service-stub';
|
||||
import { RemoteData } from '../../../../core/data/remote-data';
|
||||
import { PaginatedList } from '../../../../core/data/paginated-list';
|
||||
import { SearchOptions } from '../../../search-options.model';
|
||||
import { RouterStub } from '../../../../shared/testing/router-stub';
|
||||
import { Router } from '@angular/router';
|
||||
import { BehaviorSubject } from 'rxjs/BehaviorSubject';
|
||||
import { PageInfo } from '../../../../core/shared/page-info.model';
|
||||
import { SearchFacetFilterComponent } from '../search-facet-filter/search-facet-filter.component';
|
||||
|
||||
describe('SearchFacetFilterComponent', () => {
|
||||
let comp: SearchFacetFilterComponent;
|
||||
let fixture: ComponentFixture<SearchFacetFilterComponent>;
|
||||
const filterName1 = 'test name';
|
||||
const value1 = 'testvalue1';
|
||||
const value2 = 'test2';
|
||||
const value3 = 'another value3';
|
||||
const mockFilterConfig: SearchFilterConfig = Object.assign(new SearchFilterConfig(), {
|
||||
name: filterName1,
|
||||
type: FilterType.text,
|
||||
hasFacets: false,
|
||||
isOpenByDefault: false,
|
||||
pageSize: 2
|
||||
});
|
||||
const values: FacetValue[] = [
|
||||
{
|
||||
value: value1,
|
||||
count: 52,
|
||||
search: ''
|
||||
}, {
|
||||
value: value2,
|
||||
count: 20,
|
||||
search: ''
|
||||
}, {
|
||||
value: value3,
|
||||
count: 5,
|
||||
search: ''
|
||||
}
|
||||
];
|
||||
|
||||
const searchLink = '/search';
|
||||
const selectedValues = [value1, value2];
|
||||
let filterService;
|
||||
let searchService;
|
||||
let router;
|
||||
const page = Observable.of(0);
|
||||
|
||||
const mockValues = Observable.of(new RemoteData(false, false, true, null, new PaginatedList(new PageInfo(), values)));
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
imports: [TranslateModule.forRoot(), NoopAnimationsModule, FormsModule],
|
||||
declarations: [SearchFacetFilterComponent],
|
||||
providers: [
|
||||
{ provide: SearchService, useValue: new SearchServiceStub(searchLink) },
|
||||
{ provide: Router, useValue: new RouterStub() },
|
||||
{
|
||||
provide: SearchFilterService, useValue: {
|
||||
isFilterActiveWithValue: (paramName: string, filterValue: string) => true,
|
||||
getPage: (paramName: string) => page,
|
||||
/* tslint:disable:no-empty */
|
||||
incrementPage: (filterName: string) => {
|
||||
},
|
||||
resetPage: (filterName: string) => {
|
||||
},
|
||||
getSearchOptions: () => Observable.of({}),
|
||||
/* tslint:enable:no-empty */
|
||||
}
|
||||
}
|
||||
],
|
||||
schemas: [NO_ERRORS_SCHEMA]
|
||||
}).overrideComponent(SearchFacetFilterComponent, {
|
||||
set: { changeDetection: ChangeDetectionStrategy.Default }
|
||||
}).compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(SearchFacetFilterComponent);
|
||||
comp = fixture.componentInstance; // SearchPageComponent test instance
|
||||
comp.filterConfig = mockFilterConfig;
|
||||
comp.filterValues = [mockValues];
|
||||
comp.filterValues$ = new BehaviorSubject(comp.filterValues);
|
||||
comp.selectedValues = selectedValues;
|
||||
filterService = (comp as any).filterService;
|
||||
searchService = (comp as any).searchService;
|
||||
spyOn(searchService, 'getFacetValuesFor').and.returnValue(mockValues);
|
||||
router = (comp as any).router;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
describe('when the isChecked method is called with a value', () => {
|
||||
beforeEach(() => {
|
||||
spyOn(filterService, 'isFilterActiveWithValue');
|
||||
comp.isChecked(values[1]);
|
||||
});
|
||||
|
||||
it('should call isFilterActiveWithValue on the filterService with the correct filter parameter name and the passed value', () => {
|
||||
expect(filterService.isFilterActiveWithValue).toHaveBeenCalledWith(mockFilterConfig.paramName, values[1].value)
|
||||
});
|
||||
});
|
||||
|
||||
describe('when the getSearchLink method is triggered', () => {
|
||||
let link: string;
|
||||
beforeEach(() => {
|
||||
link = comp.getSearchLink();
|
||||
});
|
||||
|
||||
it('should return the value of the searchLink variable in the filter service', () => {
|
||||
expect(link).toEqual(searchLink);
|
||||
});
|
||||
});
|
||||
|
||||
describe('when the getAddParams method is called wih a value', () => {
|
||||
it('should return the selectedValue list with the new parameter value', () => {
|
||||
const result = comp.getAddParams(value3);
|
||||
expect(result[mockFilterConfig.paramName]).toEqual([value1, value2, value3]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('when the getRemoveParams method is called wih a value', () => {
|
||||
it('should return the selectedValue list with the parameter value left out', () => {
|
||||
const result = comp.getRemoveParams(value1);
|
||||
expect(result[mockFilterConfig.paramName]).toEqual([value2]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('when the showMore method is called', () => {
|
||||
beforeEach(() => {
|
||||
spyOn(filterService, 'incrementPage');
|
||||
comp.showMore();
|
||||
});
|
||||
|
||||
it('should call incrementPage on the filterService with the correct filter parameter name', () => {
|
||||
expect(filterService.incrementPage).toHaveBeenCalledWith(mockFilterConfig.name)
|
||||
});
|
||||
});
|
||||
|
||||
describe('when the showFirstPageOnly method is called', () => {
|
||||
beforeEach(() => {
|
||||
spyOn(filterService, 'resetPage');
|
||||
comp.showFirstPageOnly();
|
||||
});
|
||||
|
||||
it('should call resetPage on the filterService with the correct filter parameter name', () => {
|
||||
expect(filterService.resetPage).toHaveBeenCalledWith(mockFilterConfig.name);
|
||||
});
|
||||
});
|
||||
|
||||
describe('when the getCurrentPage method is called', () => {
|
||||
beforeEach(() => {
|
||||
spyOn(filterService, 'getPage');
|
||||
comp.getCurrentPage();
|
||||
});
|
||||
|
||||
it('should call getPage on the filterService with the correct filter parameter name', () => {
|
||||
expect(filterService.getPage).toHaveBeenCalledWith(mockFilterConfig.name)
|
||||
});
|
||||
});
|
||||
|
||||
describe('when the getCurrentUrl method is called', () => {
|
||||
const url = 'test.url/test'
|
||||
beforeEach(() => {
|
||||
router.navigateByUrl(url);
|
||||
});
|
||||
|
||||
it('should call getPage on the filterService with the correct filter parameter name', () => {
|
||||
expect(router.url).toEqual(url);
|
||||
});
|
||||
});
|
||||
|
||||
describe('when the onSubmit method is called with data', () => {
|
||||
const searchUrl = '/search/path';
|
||||
const testValue = 'test';
|
||||
const data = { [mockFilterConfig.paramName]: testValue };
|
||||
beforeEach(() => {
|
||||
spyOn(comp, 'getSearchLink').and.returnValue(searchUrl);
|
||||
comp.onSubmit(data);
|
||||
});
|
||||
|
||||
it('should call navigate on the router with the right searchlink and parameters', () => {
|
||||
expect(router.navigate).toHaveBeenCalledWith([searchUrl], {
|
||||
queryParams: { [mockFilterConfig.paramName]: [...selectedValues, testValue] },
|
||||
queryParamsHandling: 'merge'
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('when updateFilterValueList is called', () => {
|
||||
const cPage = 10;
|
||||
const searchOptions = new SearchOptions();
|
||||
beforeEach(() => {
|
||||
// spyOn(searchService, 'getFacetValuesFor'); Already spied upon
|
||||
comp.currentPage = Observable.of(cPage);
|
||||
comp.updateFilterValueList(searchOptions);
|
||||
});
|
||||
|
||||
it('should call getFacetValuesFor on the searchService with the correct parameters', () => {
|
||||
expect(searchService.getFacetValuesFor).toHaveBeenCalledWith(mockFilterConfig, cPage, searchOptions);
|
||||
});
|
||||
});
|
||||
|
||||
describe('when updateFilterValueList is called and pageChange is set to true', () => {
|
||||
const searchOptions = new SearchOptions();
|
||||
beforeEach(() => {
|
||||
comp.pageChange = true;
|
||||
spyOn(comp, 'showFirstPageOnly');
|
||||
comp.updateFilterValueList(searchOptions);
|
||||
});
|
||||
|
||||
it('should not call showFirstPageOnly on the component', () => {
|
||||
expect(comp.showFirstPageOnly).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should set pageChange to false', () => {
|
||||
expect(comp.pageChange).toBeFalsy();
|
||||
});
|
||||
});
|
||||
|
||||
describe('when updateFilterValueList is called and pageChange is set to false', () => {
|
||||
const searchOptions = new SearchOptions();
|
||||
beforeEach(() => {
|
||||
comp.pageChange = false;
|
||||
spyOn(comp, 'showFirstPageOnly');
|
||||
comp.updateFilterValueList(searchOptions);
|
||||
});
|
||||
|
||||
it('should call showFirstPageOnly on the component', () => {
|
||||
expect(comp.showFirstPageOnly).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
});
|
@@ -24,7 +24,7 @@ describe('SearchFiltersComponent', () => {
|
||||
/* tslint:enable:no-empty */
|
||||
};
|
||||
const searchFilterServiceStub = jasmine.createSpyObj('SearchFilterService', {
|
||||
getCurrentFilters: Observable.of({})
|
||||
getCurrentFrontendFilters: Observable.of({})
|
||||
});
|
||||
|
||||
beforeEach(async(() => {
|
||||
|
@@ -72,6 +72,7 @@ const effects = [
|
||||
ItemSearchResultGridElementComponent,
|
||||
CollectionSearchResultGridElementComponent,
|
||||
CommunitySearchResultGridElementComponent,
|
||||
SearchFacetFilterComponent,
|
||||
SearchRangeFilterComponent,
|
||||
SearchTextFilterComponent,
|
||||
SearchHierarchyFilterComponent,
|
||||
|
@@ -5,8 +5,7 @@ import { ResponseParsingService } from './parsing.service';
|
||||
import { RestRequest } from './request.models';
|
||||
import { DSpaceRESTV2Response } from '../dspace-rest-v2/dspace-rest-v2-response.model';
|
||||
import { DSpaceRESTv2Serializer } from '../dspace-rest-v2/dspace-rest-v2.serializer';
|
||||
import { PageInfo } from '../shared/page-info.model';
|
||||
import { hasValue, isNotEmpty } from '../../shared/empty.util';
|
||||
import { hasValue } from '../../shared/empty.util';
|
||||
import { SearchQueryResponse } from '../../+search-page/search-service/search-query-response.model';
|
||||
import { Metadatum } from '../shared/metadatum.model';
|
||||
|
||||
@@ -17,7 +16,6 @@ export class SearchResponseParsingService implements ResponseParsingService {
|
||||
|
||||
parse(request: RestRequest, data: DSpaceRESTV2Response): RestResponse {
|
||||
const payload = data.payload;
|
||||
console.log(payload);
|
||||
const hitHighlights = payload._embedded.objects
|
||||
.map((object) => object.hitHighlights)
|
||||
.map((hhObject) => {
|
||||
|
@@ -29,6 +29,6 @@ export class MockActivatedRoute {
|
||||
|
||||
// ActivatedRoute.snapshot.params
|
||||
get snapshot() {
|
||||
return { params: this.testParams };
|
||||
return { params: this.testParams, queryParams: this.testParams };
|
||||
}
|
||||
}
|
||||
|
12
yarn.lock
12
yarn.lock
@@ -5591,9 +5591,9 @@ netmask@~1.0.4:
|
||||
version "1.0.6"
|
||||
resolved "https://registry.yarnpkg.com/netmask/-/netmask-1.0.6.tgz#20297e89d86f6f6400f250d9f4f6b4c1945fcd35"
|
||||
|
||||
ng2-nouislider@^1.7.7:
|
||||
version "1.7.7"
|
||||
resolved "https://registry.yarnpkg.com/ng2-nouislider/-/ng2-nouislider-1.7.7.tgz#b841f4b313c8c9c8a763c80f3a59d5aa4c3a70c8"
|
||||
ng2-nouislider@1.7.8:
|
||||
version "1.7.8"
|
||||
resolved "https://registry.yarnpkg.com/ng2-nouislider/-/ng2-nouislider-1.7.8.tgz#5fd6de120f9ca5b5d9c4b377f884944b74c06855"
|
||||
|
||||
ngrx-store-freeze@^0.2.1:
|
||||
version "0.2.1"
|
||||
@@ -5814,9 +5814,9 @@ normalize-url@^1.4.0:
|
||||
query-string "^4.1.0"
|
||||
sort-keys "^1.0.0"
|
||||
|
||||
nouislider@^10.0.0:
|
||||
version "10.1.0"
|
||||
resolved "https://registry.yarnpkg.com/nouislider/-/nouislider-10.1.0.tgz#7bdd0411fd62d4584bfe88cb92bb8d06e64c6b47"
|
||||
nouislider@^11.0.0:
|
||||
version "11.1.0"
|
||||
resolved "https://registry.yarnpkg.com/nouislider/-/nouislider-11.1.0.tgz#1768eb5b854917325d41b96f2dc4eb3757d73381"
|
||||
|
||||
npm-run-all@4.1.2:
|
||||
version "4.1.2"
|
||||
|
Reference in New Issue
Block a user