Skip to content

Commit 6d361be

Browse files
authored
Merge pull request DSpace#1815 from atmire/w2p-94322_fix-theme-matching-using-handles
94322: Fix theme matching using handles
2 parents 916d7fc + 06e3435 commit 6d361be

7 files changed

Lines changed: 55 additions & 15 deletions

File tree

src/app/core/shared/collection.model.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,11 @@ import { RESOURCE_POLICY } from '../resource-policy/models/resource-policy.resou
1515
import { COMMUNITY } from './community.resource-type';
1616
import { Community } from './community.model';
1717
import { ChildHALResource } from './child-hal-resource.model';
18+
import { HandleObject } from './handle-object.model';
1819

1920
@typedObject
2021
@inheritSerialization(DSpaceObject)
21-
export class Collection extends DSpaceObject implements ChildHALResource {
22+
export class Collection extends DSpaceObject implements ChildHALResource, HandleObject {
2223
static type = COLLECTION;
2324

2425
/**

src/app/core/shared/community.model.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,11 @@ import { COMMUNITY } from './community.resource-type';
1111
import { DSpaceObject } from './dspace-object.model';
1212
import { HALLink } from './hal-link.model';
1313
import { ChildHALResource } from './child-hal-resource.model';
14+
import { HandleObject } from './handle-object.model';
1415

1516
@typedObject
1617
@inheritSerialization(DSpaceObject)
17-
export class Community extends DSpaceObject implements ChildHALResource {
18+
export class Community extends DSpaceObject implements ChildHALResource, HandleObject {
1819
static type = COMMUNITY;
1920

2021
/**
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
/**
2+
* Interface representing an object in DSpace that contains a handle
3+
*/
4+
export interface HandleObject {
5+
6+
handle: string;
7+
8+
}

src/app/core/shared/item.model.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,13 +23,14 @@ import { BITSTREAM } from './bitstream.resource-type';
2323
import { Bitstream } from './bitstream.model';
2424
import { ACCESS_STATUS } from 'src/app/shared/object-list/access-status-badge/access-status.resource-type';
2525
import { AccessStatusObject } from 'src/app/shared/object-list/access-status-badge/access-status.model';
26+
import { HandleObject } from './handle-object.model';
2627

2728
/**
2829
* Class representing a DSpace Item
2930
*/
3031
@typedObject
3132
@inheritSerialization(DSpaceObject)
32-
export class Item extends DSpaceObject implements ChildHALResource {
33+
export class Item extends DSpaceObject implements ChildHALResource, HandleObject {
3334
static type = ITEM;
3435

3536
/**

src/app/shared/theme-support/theme.service.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import { Inject, Injectable } from '@angular/core';
2-
import { createFeatureSelector, createSelector, select, Store } from '@ngrx/store';
1+
import { Injectable, Inject, Injector } from '@angular/core';
2+
import { Store, createFeatureSelector, createSelector, select } from '@ngrx/store';
33
import { BehaviorSubject, EMPTY, Observable, of as observableOf } from 'rxjs';
44
import { ThemeState } from './theme.reducer';
55
import { SetThemeAction, ThemeActionTypes } from './theme.actions';
@@ -53,12 +53,13 @@ export class ThemeService {
5353
private store: Store<ThemeState>,
5454
private linkService: LinkService,
5555
private dSpaceObjectDataService: DSpaceObjectDataService,
56+
protected injector: Injector,
5657
@Inject(GET_THEME_CONFIG_FOR_FACTORY) private gtcf: (str) => ThemeConfig,
5758
private router: Router,
5859
@Inject(DOCUMENT) private document: any,
5960
) {
6061
// Create objects from the theme configs in the environment file
61-
this.themes = environment.themes.map((themeConfig: ThemeConfig) => themeFactory(themeConfig));
62+
this.themes = environment.themes.map((themeConfig: ThemeConfig) => themeFactory(themeConfig, injector));
6263
this.hasDynamicTheme = environment.themes.some((themeConfig: any) =>
6364
hasValue(themeConfig.regex) ||
6465
hasValue(themeConfig.handle) ||

src/config/theme.model.spec.ts

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import { Collection } from '../app/core/shared/collection.model';
88
import { Item } from '../app/core/shared/item.model';
99
import { ITEM } from '../app/core/shared/item.resource-type';
1010
import { getItemModuleRoute } from '../app/item-page/item-page-routing-paths';
11+
import { HandleService } from '../app/shared/handle.service';
1112

1213
describe('Theme Models', () => {
1314
let theme: Theme;
@@ -67,24 +68,40 @@ describe('Theme Models', () => {
6768
});
6869

6970
describe('HandleTheme', () => {
71+
let handleService;
72+
beforeEach(() => {
73+
handleService = new HandleService();
74+
});
7075
it('should return true when the DSO\'s handle matches the theme\'s handle', () => {
7176
theme = new HandleTheme({
7277
name: 'matching-handle',
7378
handle: '1234/5678',
74-
});
75-
const dso = Object.assign(new Item(), {
79+
}, handleService);
80+
const matchingDso = Object.assign(new Item(), {
7681
type: ITEM.value,
7782
uuid: 'item-uuid',
7883
handle: '1234/5678',
84+
}, handleService);
85+
expect(theme.matches('', matchingDso)).toEqual(true);
86+
});
87+
it('should return false when the DSO\'s handle contains the theme\'s handle as a subpart', () => {
88+
theme = new HandleTheme({
89+
name: 'matching-handle',
90+
handle: '1234/5678',
91+
}, handleService);
92+
const dso = Object.assign(new Item(), {
93+
type: ITEM.value,
94+
uuid: 'item-uuid',
95+
handle: '1234/567891011',
7996
});
80-
expect(theme.matches('', dso)).toEqual(true);
97+
expect(theme.matches('', dso)).toEqual(false);
8198
});
8299

83100
it('should return false when the handles don\'t match', () => {
84101
theme = new HandleTheme({
85102
name: 'no-matching-handle',
86103
handle: '1234/5678',
87-
});
104+
}, handleService);
88105
const dso = Object.assign(new Item(), {
89106
type: ITEM.value,
90107
uuid: 'item-uuid',

src/config/theme.model.ts

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@ import { Config } from './config.interface';
33
import { hasValue, hasNoValue, isNotEmpty } from '../app/shared/empty.util';
44
import { DSpaceObject } from '../app/core/shared/dspace-object.model';
55
import { getDSORoute } from '../app/app-routing-paths';
6+
import { HandleObject } from '../app/core/shared/handle-object.model';
7+
import { Injector } from '@angular/core';
8+
import { HandleService } from '../app/shared/handle.service';
69

710
export interface NamedThemeConfig extends Config {
811
name: string;
@@ -82,12 +85,20 @@ export class RegExTheme extends Theme {
8285
}
8386

8487
export class HandleTheme extends Theme {
85-
constructor(public config: HandleThemeConfig) {
88+
89+
private normalizedHandle;
90+
91+
constructor(public config: HandleThemeConfig,
92+
protected handleService: HandleService
93+
) {
8694
super(config);
95+
this.normalizedHandle = this.handleService.normalizeHandle(this.config.handle);
96+
8797
}
8898

89-
matches(url: string, dso: any): boolean {
90-
return hasValue(dso) && hasValue(dso.handle) && dso.handle.includes(this.config.handle);
99+
matches<T extends DSpaceObject & HandleObject>(url: string, dso: T): boolean {
100+
return hasValue(dso) && hasValue(dso.handle)
101+
&& this.handleService.normalizeHandle(dso.handle) === this.normalizedHandle;
91102
}
92103
}
93104

@@ -101,11 +112,11 @@ export class UUIDTheme extends Theme {
101112
}
102113
}
103114

104-
export const themeFactory = (config: ThemeConfig): Theme => {
115+
export const themeFactory = (config: ThemeConfig, injector: Injector): Theme => {
105116
if (hasValue((config as RegExThemeConfig).regex)) {
106117
return new RegExTheme(config as RegExThemeConfig);
107118
} else if (hasValue((config as HandleThemeConfig).handle)) {
108-
return new HandleTheme(config as HandleThemeConfig);
119+
return new HandleTheme(config as HandleThemeConfig, injector.get(HandleService));
109120
} else if (hasValue((config as UUIDThemeConfig).uuid)) {
110121
return new UUIDTheme(config as UUIDThemeConfig);
111122
} else {

0 commit comments

Comments
 (0)