Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 49 additions & 8 deletions src/app/browse-by/browse-by-date/browse-by-date.component.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@ import { PaginationService } from '../../core/pagination/pagination.service';
import { BrowseEntry } from '../../core/shared/browse-entry.model';
import { Community } from '../../core/shared/community.model';
import { Item } from '../../core/shared/item.model';
import { SearchService } from '../../core/shared/search/search.service';
import { SearchConfigurationService } from '../../core/shared/search/search-configuration.service';
import { SearchConfig } from '../../core/shared/search/search-filters/search-config.model';
import { ThemedBrowseByComponent } from '../../shared/browse-by/themed-browse-by.component';
import { ThemedComcolPageBrowseByComponent } from '../../shared/comcol/comcol-page-browse-by/themed-comcol-page-browse-by.component';
import { ComcolPageContentComponent } from '../../shared/comcol/comcol-page-content/comcol-page-content.component';
Expand All @@ -40,7 +43,14 @@ import { ComcolPageHeaderComponent } from '../../shared/comcol/comcol-page-heade
import { ComcolPageLogoComponent } from '../../shared/comcol/comcol-page-logo/comcol-page-logo.component';
import { ThemedLoadingComponent } from '../../shared/loading/themed-loading.component';
import { RouterMock } from '../../shared/mocks/router.mock';
import { createSuccessfulRemoteDataObject$ } from '../../shared/remote-data.utils';
import {
createSuccessfulRemoteDataObject,
createSuccessfulRemoteDataObject$,
} from '../../shared/remote-data.utils';
import { FacetValues } from '../../shared/search/models/facet-values.model';
import { FilterType } from '../../shared/search/models/filter-type.model';
import { PaginatedSearchOptions } from '../../shared/search/models/paginated-search-options.model';
import { SearchFilterConfig } from '../../shared/search/models/search-filter-config.model';
import { ActivatedRouteStub } from '../../shared/testing/active-router.stub';
import { PaginationServiceStub } from '../../shared/testing/pagination-service.stub';
import { EnumKeysPipe } from '../../shared/utils/enum-keys-pipe';
Expand Down Expand Up @@ -85,12 +95,41 @@ describe('BrowseByDateComponent', () => {
},
});

const mockFilterConfig: SearchFilterConfig = Object.assign(new SearchFilterConfig(), {
name: 'dateIssued',
filterType: FilterType.range,
hasFacets: false,
isOpenByDefault: false,
pageSize: 1,
});

const mockFacetValue: FacetValues =
Object.assign(new FacetValues(), {
authorityKey: null,
count: 1,
label: '2009 - 2009',
value: '2009 - 2009',
type: 'discover',
});


const filtersConfigRD = createSuccessfulRemoteDataObject([mockFilterConfig]);
const filtersConfigRD$ = observableOf(filtersConfigRD);

const mockBrowseService = {
getBrowseEntriesFor: (options: BrowseEntrySearchOptions) => toRemoteData([]),
getBrowseItemsFor: (value: string, options: BrowseEntrySearchOptions) => toRemoteData([firstItem]),
getFirstItemFor: (definition: string, scope?: string, sortDirection?: SortDirection) => null,
};

const mockSearchConfigService = {
getConfig: () => filtersConfigRD$,
};

const mockSearchService = {
getFacetValuesFor: (filterConfig: SearchFilterConfig, valuePage: number, searchOptions?: PaginatedSearchOptions, filterQuery?: string, useCachedVersionIfAvailable = true) => toRemoteData([mockFacetValue]),
};

const mockDsoService = {
findById: () => createSuccessfulRemoteDataObject$(mockCommunity),
};
Expand Down Expand Up @@ -128,6 +167,8 @@ describe('BrowseByDateComponent', () => {
{ provide: Store, useValue: {} },
{ provide: APP_CONFIG, useValue: environment },
{ provide: PLATFORM_ID, useValue: 'browser' },
{ provide: SearchConfigurationService, useValue: mockSearchConfigService },
{ provide: SearchService, useValue: mockSearchService },
],
schemas: [NO_ERRORS_SCHEMA],
})
Expand All @@ -149,12 +190,8 @@ describe('BrowseByDateComponent', () => {

beforeEach(() => {
fixture = TestBed.createComponent(BrowseByDateComponent);
const browseService = fixture.debugElement.injector.get(BrowseService);
spyOn(browseService, 'getFirstItemFor')
// ok to expect the default browse as first param since we just need the mock items obtained via sort direction.
.withArgs('author', undefined, SortDirection.ASC).and.returnValue(createSuccessfulRemoteDataObject$(firstItem))
.withArgs('author', undefined, SortDirection.DESC).and.returnValue(createSuccessfulRemoteDataObject$(lastItem));
comp = fixture.componentInstance;
comp.browseId = 'dateissued';
route = (comp as any).route;
fixture.detectChanges();
});
Expand All @@ -170,12 +207,12 @@ describe('BrowseByDateComponent', () => {
});

it('should create a list of startsWith options with the earliest year at the end (rounded down by 10)', () => {
expect(comp.startsWithOptions[comp.startsWithOptions.length - 1]).toEqual(1950);
expect(comp.startsWithOptions[comp.startsWithOptions.length - 1]).toEqual(2009);
});

it('should create a list of startsWith options with the current year first', () => {
//expect(comp.startsWithOptions[0]).toEqual(new Date().getUTCFullYear());
expect(comp.startsWithOptions[0]).toEqual(1960);
expect(comp.startsWithOptions[0]).toEqual(2009);
});

describe('when rendered in SSR', () => {
Expand All @@ -198,12 +235,16 @@ describe('BrowseByDateComponent', () => {
beforeEach(() => {
comp.platformId = 'browser';
spyOn((comp as any).browseService, 'getBrowseItemsFor').and.returnValue(createSuccessfulRemoteDataObject$(new BrowseEntry()));
spyOn((comp as any).searchConfigService, 'getConfig').and.returnValue(createSuccessfulRemoteDataObject$([new SearchConfig()]));
spyOn((comp as any).searchService, 'getFacetValuesFor').and.returnValue(createSuccessfulRemoteDataObject$([new FacetValues()]));
});

it('should call getBrowseItemsFor on init', fakeAsync(() => {
comp.ngOnInit();
tick(100);
expect((comp as any).browseService.getBrowseItemsFor).toHaveBeenCalled();
expect((comp as any).searchConfigService.getConfig).toHaveBeenCalled();
expect((comp as any).searchService.getFacetValuesFor).toHaveBeenCalled();
}));
});
});
81 changes: 43 additions & 38 deletions src/app/browse-by/browse-by-date/browse-by-date.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,9 @@ import {
} from 'rxjs';
import {
distinctUntilChanged,
filter,
map,
switchMap,
} from 'rxjs/operators';
import { ThemedBrowseByComponent } from 'src/app/shared/browse-by/themed-browse-by.component';

Expand All @@ -42,6 +44,12 @@ import { DSpaceObjectDataService } from '../../core/data/dspace-object-data.serv
import { RemoteData } from '../../core/data/remote-data';
import { PaginationService } from '../../core/pagination/pagination.service';
import { Item } from '../../core/shared/item.model';
import {
getAllSucceededRemoteDataPayload,
getFirstSucceededRemoteDataPayload,
} from '../../core/shared/operators';
import { SearchService } from '../../core/shared/search/search.service';
import { SearchConfigurationService } from '../../core/shared/search/search-configuration.service';
import { isValidDate } from '../../shared/date.util';
import {
hasValue,
Expand All @@ -55,6 +63,7 @@ import {
browseParamsToOptions,
} from '../browse-by-metadata/browse-by-metadata.component';


@Component({
selector: 'ds-browse-by-date',
styleUrls: ['../browse-by-metadata/browse-by-metadata.component.scss'],
Expand Down Expand Up @@ -90,6 +99,8 @@ export class BrowseByDateComponent extends BrowseByMetadataComponent implements
public dsoNameService: DSONameService,
protected cdRef: ChangeDetectorRef,
@Inject(PLATFORM_ID) public platformId: any,
public searchConfigService: SearchConfigurationService,
public searchService: SearchService,
) {
super(route, browseService, dsoService, paginationService, router, appConfig, dsoNameService, platformId);
}
Expand Down Expand Up @@ -137,50 +148,44 @@ export class BrowseByDateComponent extends BrowseByMetadataComponent implements
* @param scope The scope under which to fetch the earliest item for
*/
updateStartsWithOptions(definition: string, metadataKeys: string[], scope?: string) {
const firstItemRD$: Observable<RemoteData<Item>> = this.browseService.getFirstItemFor(definition, scope, SortDirection.ASC);
const lastItemRD$: Observable<RemoteData<Item>> = this.browseService.getFirstItemFor(definition, scope, SortDirection.DESC);
this.loading$ = observableCombineLatest([
firstItemRD$,
lastItemRD$,
]).pipe(
map(([firstItemRD, lastItemRD]: [RemoteData<Item>, RemoteData<Item>]) => firstItemRD.isLoading || lastItemRD.isLoading),
);
this.subs.push(
observableCombineLatest([
firstItemRD$,
lastItemRD$,
]).subscribe(([firstItemRD, lastItemRD]: [RemoteData<Item>, RemoteData<Item>]) => {
let lowerLimit: number = this.getLimit(firstItemRD, metadataKeys, this.appConfig.browseBy.defaultLowerLimit);
const upperLimit: number = this.getLimit(lastItemRD, metadataKeys, new Date().getUTCFullYear());
const options: number[] = [];
const oneYearBreak: number = Math.floor((upperLimit - this.appConfig.browseBy.oneYearLimit) / 5) * 5;
const fiveYearBreak: number = Math.floor((upperLimit - this.appConfig.browseBy.fiveYearLimit) / 10) * 10;
if (lowerLimit <= fiveYearBreak) {
lowerLimit -= 10;
} else if (lowerLimit <= oneYearBreak) {
lowerLimit -= 5;
} else {
lowerLimit -= 1;
}
let i: number = upperLimit;
while (i > lowerLimit) {
options.push(i);
if (i <= fiveYearBreak) {
i -= 10;
} else if (i <= oneYearBreak) {
i -= 5;
} else {
i--;
}
}
this.searchConfigService.getConfig(null,definition).pipe(
getFirstSucceededRemoteDataPayload(),
filter( configs => configs.length > 0 ),
map( configs => configs.filter( filterConfig => filterConfig.name?.toUpperCase() === definition.toUpperCase() ) ),
map( findConfig => findConfig[0]),
switchMap( config => {
return this.searchService.getFacetValuesFor(config, 10).pipe(
getAllSucceededRemoteDataPayload(),
);
}),
map( facetValue => facetValue.page ),
).subscribe(
values => {
const options = this.generateYearFromFacetValue(values);
if (isNotEmpty(options)) {
this.startsWithOptions = options;
this.cdRef.detectChanges();
}
}),
);
});
}

/**
* Prepare options
* @param data The facets values
*/
generateYearFromFacetValue = (data: any[]) => {
const years: number[] = [];
if (!hasValue(data)) {return [];}
data.forEach(item => {
const [start, end] = item.value.split(' - ').map(Number);
for (let year = start; year <= end; year++) {
years.push(year);
}
});

return years;
};

/**
* Returns the year from the item metadata field or the limit.
* @param itemRD the item remote data
Expand Down
Loading