94322: Fix theme matching using handles

This commit is contained in:
Yana De Pauw
2022-09-07 15:34:16 +02:00
parent 342a712513
commit 28fff891d2
7 changed files with 54 additions and 14 deletions

View File

@@ -15,10 +15,11 @@ import { RESOURCE_POLICY } from '../resource-policy/models/resource-policy.resou
import { COMMUNITY } from './community.resource-type';
import { Community } from './community.model';
import { ChildHALResource } from './child-hal-resource.model';
import { HandleObject } from './handle-object.model';
@typedObject
@inheritSerialization(DSpaceObject)
export class Collection extends DSpaceObject implements ChildHALResource {
export class Collection extends DSpaceObject implements ChildHALResource, HandleObject {
static type = COLLECTION;
/**

View File

@@ -11,10 +11,11 @@ import { COMMUNITY } from './community.resource-type';
import { DSpaceObject } from './dspace-object.model';
import { HALLink } from './hal-link.model';
import { ChildHALResource } from './child-hal-resource.model';
import { HandleObject } from './handle-object.model';
@typedObject
@inheritSerialization(DSpaceObject)
export class Community extends DSpaceObject implements ChildHALResource {
export class Community extends DSpaceObject implements ChildHALResource, HandleObject {
static type = COMMUNITY;
/**

View File

@@ -0,0 +1,8 @@
/**
* Interface representing an object in DSpace that contains a handle
*/
export interface HandleObject {
handle: string;
}

View File

@@ -23,13 +23,14 @@ import { BITSTREAM } from './bitstream.resource-type';
import { Bitstream } from './bitstream.model';
import { ACCESS_STATUS } from 'src/app/shared/object-list/access-status-badge/access-status.resource-type';
import { AccessStatusObject } from 'src/app/shared/object-list/access-status-badge/access-status.model';
import { HandleObject } from './handle-object.model';
/**
* Class representing a DSpace Item
*/
@typedObject
@inheritSerialization(DSpaceObject)
export class Item extends DSpaceObject implements ChildHALResource {
export class Item extends DSpaceObject implements ChildHALResource, HandleObject {
static type = ITEM;
/**

View File

@@ -1,4 +1,4 @@
import { Injectable, Inject } from '@angular/core';
import { Injectable, Inject, Injector } from '@angular/core';
import { Store, createFeatureSelector, createSelector, select } from '@ngrx/store';
import { EMPTY, Observable, of as observableOf } from 'rxjs';
import { ThemeState } from './theme.reducer';
@@ -46,10 +46,11 @@ export class ThemeService {
private store: Store<ThemeState>,
private linkService: LinkService,
private dSpaceObjectDataService: DSpaceObjectDataService,
protected injector: Injector,
@Inject(GET_THEME_CONFIG_FOR_FACTORY) private gtcf: (str) => ThemeConfig
) {
// Create objects from the theme configs in the environment file
this.themes = environment.themes.map((themeConfig: ThemeConfig) => themeFactory(themeConfig));
this.themes = environment.themes.map((themeConfig: ThemeConfig) => themeFactory(themeConfig, injector));
this.hasDynamicTheme = environment.themes.some((themeConfig: any) =>
hasValue(themeConfig.regex) ||
hasValue(themeConfig.handle) ||

View File

@@ -8,6 +8,7 @@ import { Collection } from '../app/core/shared/collection.model';
import { Item } from '../app/core/shared/item.model';
import { ITEM } from '../app/core/shared/item.resource-type';
import { getItemModuleRoute } from '../app/item-page/item-page-routing-paths';
import { HandleService } from '../app/shared/handle.service';
describe('Theme Models', () => {
let theme: Theme;
@@ -67,24 +68,40 @@ describe('Theme Models', () => {
});
describe('HandleTheme', () => {
let handleService;
beforeEach(() => {
handleService = new HandleService();
});
it('should return true when the DSO\'s handle matches the theme\'s handle', () => {
theme = new HandleTheme({
name: 'matching-handle',
handle: '1234/5678',
});
const dso = Object.assign(new Item(), {
}, handleService);
const matchingDso = Object.assign(new Item(), {
type: ITEM.value,
uuid: 'item-uuid',
handle: '1234/5678',
}, handleService);
expect(theme.matches('', matchingDso)).toEqual(true);
});
it('should return false when the DSO\'s handle contains the theme\'s handle as a subpart', () => {
theme = new HandleTheme({
name: 'matching-handle',
handle: '1234/5678',
}, handleService);
const dso = Object.assign(new Item(), {
type: ITEM.value,
uuid: 'item-uuid',
handle: '1234/567891011',
});
expect(theme.matches('', dso)).toEqual(true);
expect(theme.matches('', dso)).toEqual(false);
});
it('should return false when the handles don\'t match', () => {
theme = new HandleTheme({
name: 'no-matching-handle',
handle: '1234/5678',
});
}, handleService);
const dso = Object.assign(new Item(), {
type: ITEM.value,
uuid: 'item-uuid',

View File

@@ -3,6 +3,9 @@ import { Config } from './config.interface';
import { hasValue, hasNoValue, isNotEmpty } from '../app/shared/empty.util';
import { DSpaceObject } from '../app/core/shared/dspace-object.model';
import { getDSORoute } from '../app/app-routing-paths';
import { HandleObject } from '../app/core/shared/handle-object.model';
import { Injector } from '@angular/core';
import { HandleService } from '../app/shared/handle.service';
export interface NamedThemeConfig extends Config {
name: string;
@@ -82,12 +85,20 @@ export class RegExTheme extends Theme {
}
export class HandleTheme extends Theme {
constructor(public config: HandleThemeConfig) {
private normalizedHandle;
constructor(public config: HandleThemeConfig,
protected handleService: HandleService
) {
super(config);
this.normalizedHandle = this.handleService.normalizeHandle(this.config.handle);
}
matches(url: string, dso: any): boolean {
return hasValue(dso) && hasValue(dso.handle) && dso.handle.includes(this.config.handle);
matches<T extends DSpaceObject & HandleObject>(url: string, dso: T): boolean {
return hasValue(dso) && hasValue(dso.handle)
&& this.handleService.normalizeHandle(dso.handle) === this.normalizedHandle;
}
}
@@ -101,11 +112,11 @@ export class UUIDTheme extends Theme {
}
}
export const themeFactory = (config: ThemeConfig): Theme => {
export const themeFactory = (config: ThemeConfig, injector: Injector): Theme => {
if (hasValue((config as RegExThemeConfig).regex)) {
return new RegExTheme(config as RegExThemeConfig);
} else if (hasValue((config as HandleThemeConfig).handle)) {
return new HandleTheme(config as HandleThemeConfig);
return new HandleTheme(config as HandleThemeConfig, injector.get(HandleService));
} else if (hasValue((config as UUIDThemeConfig).uuid)) {
return new UUIDTheme(config as UUIDThemeConfig);
} else {