Skip to content

Commit f5b0377

Browse files
committed
Merge remote-tracking branch 'bitbucket4science/Jordan-PISCANC/productcreativeworkschematypets-edited-o-1742505524596' into Jordan-PISCANC/productcreativeworkschematypets-edited-o-1742505524596
2 parents 1f4a300 + ba03868 commit f5b0377

29 files changed

Lines changed: 522 additions & 155 deletions

File tree

src/app/core/itemexportformat/item-export-format.service.spec.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ describe('ItemExportFormatService', () => {
122122
const searchOptions = new PaginatedSearchOptions({
123123
query: 'queryX',
124124
filters: [
125-
new SearchFilter('f.name', ['nameX']),
125+
new SearchFilter('f.name', ['nameX', 'nameY']),
126126
new SearchFilter('f.type', ['typeX']),
127127
new SearchFilter('other.name', ['nameY']),
128128
],
@@ -135,7 +135,7 @@ describe('ItemExportFormatService', () => {
135135
Object.assign(new ProcessParameter(), { name: '-f', value: 'publication-xml' }),
136136
Object.assign(new ProcessParameter(), { name: '-t', value: 'Publication' }),
137137
Object.assign(new ProcessParameter(), { name: '-q', value: 'queryX' }),
138-
Object.assign(new ProcessParameter(), { name: '-sf', value: 'name=nameX&type=typeX' }),
138+
Object.assign(new ProcessParameter(), { name: '-sf', value: 'name=nameX&name=nameY&type=typeX' }),
139139
Object.assign(new ProcessParameter(), { name: '-s', value: 'scopeX' }),
140140
Object.assign(new ProcessParameter(), { name: '-c', value: 'configurationX' }),
141141
Object.assign(new ProcessParameter(), { name: '-so', value: 'fieldX,ASC' }),

src/app/core/itemexportformat/item-export-format.service.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -198,7 +198,10 @@ export class ItemExportFormatService extends IdentifiableDataService<ItemExportF
198198
if (searchOptions.filters && searchOptions.filters.length > 0) {
199199
const value = searchOptions.filters
200200
.filter((searchFilter) => searchFilter.key.includes('f.'))
201-
.map((searchFilter) => searchFilter.key.replace('f.', '') + '=' + searchFilter.values[0])
201+
.map((searchFilter) => {
202+
const key = searchFilter.key.replace('f.', '');
203+
return searchFilter.values.map((filterValue) => `${key}=${filterValue}`).join('&');
204+
})
202205
.join('&');
203206
return [...parameterValues, Object.assign(new ProcessParameter(), { name: '-sf', value })];
204207
}

src/app/cris-layout/cris-layout-matrix/cris-layout-box-container/boxes/metadata/rendering-types/identifier/identifier.component.spec.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ import {
1010
TranslateModule,
1111
} from '@ngx-translate/core';
1212

13+
import { APP_CONFIG } from '../../../../../../../../config/app-config.interface';
14+
import { environment } from '../../../../../../../../environments/environment';
1315
import { LayoutField } from '../../../../../../../core/layout/models/box.model';
1416
import { Item } from '../../../../../../../core/shared/item.model';
1517
import { MetadataValue } from '../../../../../../../core/shared/metadata.models';
@@ -91,6 +93,7 @@ describe('IdentifierComponent', () => {
9193
{ provide: 'renderingSubTypeProvider', useValue: '' },
9294
{ provide: 'tabNameProvider', useValue: '' },
9395
{ provide: ResolverStrategyService, useClass: ResolverStrategyService },
96+
{ provide: APP_CONFIG, useValue: environment },
9497
],
9598
})
9699
.compileComponents();
@@ -228,4 +231,18 @@ describe('IdentifierComponent', () => {
228231
});
229232
});
230233

234+
it('should keep white space in metadata value if shouldKeepWhiteSpaces is true', () => {
235+
expect(component.composeLink('keep my white spaces', 'keepMyWhiteSpaces')).toEqual({
236+
href: 'https://keepmywhitespaces.com/keep my white spaces',
237+
text: 'keep my white spaces',
238+
});
239+
});
240+
241+
it('should not keep white space in metadata value if shouldKeepWhiteSpaces is false', () => {
242+
expect(component.composeLink('do not keep my white spaces', 'doi')).toEqual({
243+
href: 'https://doi.org/donotkeepmywhitespaces',
244+
text: 'do not keep my white spaces',
245+
});
246+
});
247+
231248
});

src/app/cris-layout/cris-layout-matrix/cris-layout-box-container/boxes/metadata/rendering-types/identifier/identifier.component.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,9 @@ export class IdentifierComponent extends RenderingTypeValueModelComponent implem
153153
if (metadataValue.startsWith(rep)) {
154154
value = metadataValue.replace(rep, '');
155155
}
156-
const href = this.resolver.getBaseUrl(urn) + value;
156+
const shouldKeepWhiteSpaces = environment.crisLayout
157+
.urn?.find((urnConfig) => urnConfig.name === urn)?.shouldKeepWhiteSpaces;
158+
const href = this.resolver.getBaseUrl(urn) + (shouldKeepWhiteSpaces ? value : value.replace(/\s/g, ''));
157159
return this.createMetadataLinkValue(href, value);
158160
}
159161

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
:host {
2+
word-break: break-word;
3+
}

src/app/cris-layout/cris-layout-matrix/cris-layout-box-container/boxes/metadata/row/metadata-container/metadata-render/metadata-render.component.spec.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,11 @@ describe('MetadataRenderComponent', () => {
160160
component.field = fieldMock;
161161
});
162162

163+
it('Should apply word-break style to host element', () => {
164+
const hostElement = fixture.nativeElement;
165+
expect(getComputedStyle(hostElement).wordBreak).toBe('break-word');
166+
});
167+
163168
describe('When field rendering type is not structured', () => {
164169
beforeEach(() => {
165170
component.metadataValue = metadataValue;

src/app/item-page/cris-item-page-tab.resolver.spec.ts

Lines changed: 121 additions & 94 deletions
Original file line numberDiff line numberDiff line change
@@ -18,130 +18,157 @@ import {
1818
} from '../shared/remote-data.utils';
1919
import {
2020
tabDetailsTest,
21+
tabFundingsTest,
2122
tabPublicationsTest,
2223
} from '../shared/testing/layout-tab.mocks';
2324
import { createPaginatedList } from '../shared/testing/utils.test';
2425
import { crisItemPageTabResolver } from './cris-item-page-tab.resolver';
2526

26-
describe('crisItemPageTabResolver', () => {
27-
let itemService: jasmine.SpyObj<ItemDataService>;
28-
let tabService: jasmine.SpyObj<TabDataService>;
29-
let hardRedirectService: jasmine.SpyObj<HardRedirectService>;
30-
let router: Router;
31-
32-
const uuid = '1234-65487-12354-1235';
33-
const item = Object.assign(new Item(), {
34-
id: uuid,
35-
uuid: uuid,
36-
metadata: {
37-
'dspace.entity.type': [{ value: 'Publication' }],
38-
},
39-
});
40-
41-
const tabsRD = createSuccessfulRemoteDataObject(createPaginatedList([tabPublicationsTest, tabDetailsTest]));
42-
const tabsRD$ = createSuccessfulRemoteDataObject$(createPaginatedList([tabPublicationsTest, tabDetailsTest]));
43-
44-
const noTabsRD = createSuccessfulRemoteDataObject(createPaginatedList([]));
45-
const noTabsRD$ = createSuccessfulRemoteDataObject$(createPaginatedList([]));
46-
27+
describe('CrisItemPageTabResolver', () => {
4728
beforeEach(() => {
48-
itemService = jasmine.createSpyObj('ItemDataService', ['findById']);
49-
tabService = jasmine.createSpyObj('TabDataService', ['findByItem']);
50-
hardRedirectService = jasmine.createSpyObj('HardRedirectService', ['redirect']);
51-
5229
TestBed.configureTestingModule({
53-
imports: [RouterTestingModule.withRoutes([{ path: 'entities/:entity-type/:id/:tab', component: {} as any }])],
54-
providers: [
55-
{ provide: ItemDataService, useValue: itemService },
56-
{ provide: TabDataService, useValue: tabService },
57-
{ provide: HardRedirectService, useValue: hardRedirectService },
58-
{ provide: PLATFORM_ID, useValue: 'browser' },
59-
],
30+
imports: [RouterTestingModule.withRoutes([{
31+
path: 'entities/:entity-type/:id/:tab',
32+
component: {} as any,
33+
}])],
6034
});
61-
62-
router = TestBed.inject(Router);
6335
});
6436

65-
describe('when item exists', () => {
37+
describe('crisItemPageTabResolver', () => {
38+
let itemService: jasmine.SpyObj<ItemDataService>;
39+
let tabService: jasmine.SpyObj<TabDataService>;
40+
let hardRedirectService: jasmine.SpyObj<HardRedirectService>;
41+
let router: Router;
42+
43+
const uuid = '1234-65487-12354-1235';
44+
const item = Object.assign(new Item(), {
45+
id: uuid,
46+
uuid: uuid,
47+
metadata: {
48+
'dspace.entity.type': [{ value: 'Publication' }],
49+
},
50+
});
51+
52+
const tabsRD = createSuccessfulRemoteDataObject(createPaginatedList([tabPublicationsTest, tabDetailsTest, tabFundingsTest]));
53+
const tabsRD$ = createSuccessfulRemoteDataObject$(createPaginatedList([tabPublicationsTest, tabDetailsTest, tabFundingsTest]));
54+
55+
const noTabsRD = createSuccessfulRemoteDataObject(createPaginatedList([]));
56+
const noTabsRD$ = createSuccessfulRemoteDataObject$(createPaginatedList([]));
57+
6658
beforeEach(() => {
67-
itemService.findById.and.returnValue(createSuccessfulRemoteDataObject$(item));
59+
itemService = jasmine.createSpyObj('ItemDataService', ['findById']);
60+
tabService = jasmine.createSpyObj('TabDataService', ['findByItem']);
61+
hardRedirectService = jasmine.createSpyObj('HardRedirectService', ['redirect']);
62+
63+
TestBed.configureTestingModule({
64+
imports: [RouterTestingModule.withRoutes([{ path: 'entities/:entity-type/:id/:tab', component: {} as any }])],
65+
providers: [
66+
{ provide: ItemDataService, useValue: itemService },
67+
{ provide: TabDataService, useValue: tabService },
68+
{ provide: HardRedirectService, useValue: hardRedirectService },
69+
{ provide: PLATFORM_ID, useValue: 'browser' },
70+
],
71+
});
72+
73+
router = TestBed.inject(Router);
6874
});
6975

70-
describe('and there are tabs', () => {
76+
describe('when item exists', () => {
7177
beforeEach(() => {
72-
tabService.findByItem.and.returnValue(tabsRD$);
73-
spyOn(router, 'navigateByUrl');
78+
itemService.findById.and.returnValue(createSuccessfulRemoteDataObject$(item));
7479
});
7580

76-
it('should redirect to root route if given tab is the first one', (done) => {
77-
const obs = TestBed.runInInjectionContext(() => {
78-
return crisItemPageTabResolver({ params: { id: uuid } } as any, { url: '/entities/publication/1234-65487-12354-1235/publications' } as any);
79-
}) as Observable<RemoteData<PaginatedList<CrisLayoutTab>>>;
80-
81-
obs.pipe(take(1)).subscribe((resolved) => {
82-
expect(router.navigateByUrl).toHaveBeenCalledWith('/entities/publication/1234-65487-12354-1235');
83-
expect(hardRedirectService.redirect).not.toHaveBeenCalled();
84-
expect(resolved).toEqual(tabsRD);
85-
done();
81+
describe('and there are tabs', () => {
82+
beforeEach(() => {
83+
tabService.findByItem.and.returnValue(tabsRD$);
84+
spyOn(router, 'navigateByUrl');
8685
});
87-
});
8886

89-
it('should not redirect to root route if tab different than the main one is given', (done) => {
90-
const obs = TestBed.runInInjectionContext(() => {
91-
return crisItemPageTabResolver({ params: { id: uuid } } as any, { url: '/entities/publication/1234-65487-12354-1235/details' } as any);
92-
}) as Observable<RemoteData<PaginatedList<CrisLayoutTab>>>;
87+
it('should redirect to root route if given tab is the first one', (done) => {
88+
const obs = TestBed.runInInjectionContext(() => {
89+
return crisItemPageTabResolver({ params: { id: uuid } } as any, { url: '/entities/publication/1234-65487-12354-1235/publications' } as any);
90+
}) as Observable<RemoteData<PaginatedList<CrisLayoutTab>>>;
91+
92+
obs.pipe(take(1)).subscribe((resolved) => {
93+
expect(router.navigateByUrl).toHaveBeenCalledWith('/entities/publication/1234-65487-12354-1235');
94+
expect(hardRedirectService.redirect).not.toHaveBeenCalled();
95+
expect(resolved).toEqual(tabsRD);
96+
done();
97+
});
98+
});
9399

94-
obs.pipe(take(1)).subscribe((resolved) => {
95-
expect(router.navigateByUrl).not.toHaveBeenCalled();
96-
expect(hardRedirectService.redirect).not.toHaveBeenCalled();
97-
expect(resolved).toEqual(tabsRD);
98-
done();
100+
it('should not redirect to root route if tab different than the main one is given', (done) => {
101+
const obs = TestBed.runInInjectionContext(() => {
102+
return crisItemPageTabResolver({ params: { id: uuid } } as any, { url: '/entities/publication/1234-65487-12354-1235/details' } as any);
103+
}) as Observable<RemoteData<PaginatedList<CrisLayoutTab>>>;
104+
105+
obs.pipe(take(1)).subscribe((resolved) => {
106+
expect(router.navigateByUrl).not.toHaveBeenCalled();
107+
expect(hardRedirectService.redirect).not.toHaveBeenCalled();
108+
expect(resolved).toEqual(tabsRD);
109+
done();
110+
});
99111
});
100-
});
101112

102-
it('should not redirect to root route if no tab is given', (done) => {
103-
const obs = TestBed.runInInjectionContext(() => {
104-
return crisItemPageTabResolver({ params: { id: uuid } } as any, { url: '/entities/publication/1234-65487-12354-1235' } as any);
105-
}) as Observable<RemoteData<PaginatedList<CrisLayoutTab>>>;
113+
it('should not redirect to root route if no tab is given', (done) => {
114+
const obs = TestBed.runInInjectionContext(() => {
115+
return crisItemPageTabResolver({ params: { id: uuid } } as any, { url: '/entities/publication/1234-65487-12354-1235' } as any);
116+
}) as Observable<RemoteData<PaginatedList<CrisLayoutTab>>>;
117+
118+
obs.pipe(take(1)).subscribe((resolved) => {
119+
expect(router.navigateByUrl).not.toHaveBeenCalled();
120+
expect(hardRedirectService.redirect).not.toHaveBeenCalled();
121+
expect(resolved).toEqual(tabsRD);
122+
done();
123+
});
124+
});
106125

107-
obs.pipe(take(1)).subscribe((resolved) => {
108-
expect(router.navigateByUrl).not.toHaveBeenCalled();
109-
expect(hardRedirectService.redirect).not.toHaveBeenCalled();
110-
expect(resolved).toEqual(tabsRD);
111-
done();
126+
it('should navigate to 404 if a wrong tab is given', (done) => {
127+
const obs = TestBed.runInInjectionContext(() => {
128+
return crisItemPageTabResolver({ params: { id: uuid } } as any, { url: '/entities/publication/1234-65487-12354-1235/test' } as any);
129+
}) as Observable<RemoteData<PaginatedList<CrisLayoutTab>>>;
130+
131+
obs.pipe(take(1)).subscribe((resolved) => {
132+
expect(router.navigateByUrl).toHaveBeenCalled();
133+
expect(hardRedirectService.redirect).not.toHaveBeenCalled();
134+
expect(resolved).toEqual(tabsRD);
135+
done();
136+
});
112137
});
113-
});
114138

115-
it('should navigate to 404 if a wrong tab is given', (done) => {
116-
const obs = TestBed.runInInjectionContext(() => {
117-
return crisItemPageTabResolver({ params: { id: uuid } } as any, { url: '/entities/publication/1234-65487-12354-1235/test' } as any);
118-
}) as Observable<RemoteData<PaginatedList<CrisLayoutTab>>>;
139+
it('Should handle tab shortnames with "::" correctly', () => {
140+
const tabRD = createSuccessfulRemoteDataObject(createPaginatedList([{
141+
...tabPublicationsTest,
142+
shortname: 'publication::details',
143+
}]));
144+
tabService.findByItem.and.returnValue(createSuccessfulRemoteDataObject$(tabRD) as any);
145+
146+
TestBed.runInInjectionContext(() => {
147+
return crisItemPageTabResolver({ params: { id: uuid } } as any, { url: '/entities/publication/1234-65487-12354-1235/publication::details' } as any);
148+
});
119149

120-
obs.pipe(take(1)).subscribe((resolved) => {
121-
expect(router.navigateByUrl).toHaveBeenCalled();
150+
expect(router.navigateByUrl).not.toHaveBeenCalled();
122151
expect(hardRedirectService.redirect).not.toHaveBeenCalled();
123-
expect(resolved).toEqual(tabsRD);
124-
done();
125152
});
126153
});
127-
});
128-
129-
describe('and there are no tabs', () => {
130-
beforeEach(() => {
131-
tabService.findByItem.and.returnValue(noTabsRD$);
132-
spyOn(router, 'navigateByUrl');
133-
});
134154

135-
it('should not redirect nor navigate', (done) => {
136-
const obs = TestBed.runInInjectionContext(() => {
137-
return crisItemPageTabResolver({ params: { id: uuid } } as any, { url: '/entities/publication/1234-65487-12354-1235' } as any);
138-
}) as Observable<RemoteData<PaginatedList<CrisLayoutTab>>>;
155+
describe('and there are no tabs', () => {
156+
beforeEach(() => {
157+
tabService.findByItem.and.returnValue(noTabsRD$);
158+
spyOn(router, 'navigateByUrl');
159+
});
139160

140-
obs.pipe(take(1)).subscribe((resolved) => {
141-
expect(router.navigateByUrl).not.toHaveBeenCalled();
142-
expect(hardRedirectService.redirect).not.toHaveBeenCalled();
143-
expect(resolved).toEqual(noTabsRD);
144-
done();
161+
it('should not redirect nor navigate', (done) => {
162+
const obs = TestBed.runInInjectionContext(() => {
163+
return crisItemPageTabResolver({ params: { id: uuid } } as any, { url: '/entities/publication/1234-65487-12354-1235' } as any);
164+
}) as Observable<RemoteData<PaginatedList<CrisLayoutTab>>>;
165+
166+
obs.pipe(take(1)).subscribe((resolved) => {
167+
expect(router.navigateByUrl).not.toHaveBeenCalled();
168+
expect(hardRedirectService.redirect).not.toHaveBeenCalled();
169+
expect(resolved).toEqual(noTabsRD);
170+
done();
171+
});
145172
});
146173
});
147174
});

src/app/item-page/cris-item-page-tab.resolver.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@ import { TabDataService } from '../core/layout/tab-data.service';
2424
import { HardRedirectService } from '../core/services/hard-redirect.service';
2525
import { Item } from '../core/shared/item.model';
2626
import { getFirstCompletedRemoteData } from '../core/shared/operators';
27-
import { isEmpty } from '../shared/empty.util';
2827
import { createFailedRemoteDataObject$ } from '../shared/remote-data.utils';
2928
import { getItemPageRoute } from './item-page-routing-paths';
3029

@@ -61,7 +60,12 @@ export const crisItemPageTabResolver: ResolveFn<RemoteData<PaginatedList<CrisLay
6160
const urlSplit = state.url.split(route.params.id);
6261
const givenTab = urlSplit[1];
6362
const itemPageRoute = getItemPageRoute(itemRD.payload);
64-
const isValidTab = isEmpty(givenTab) || tabsRD.payload.page.some((tab) => `/${tab.shortname}` === givenTab);
63+
64+
const isValidTab = !givenTab || tabsRD.payload.page.some((tab) => {
65+
const shortnameSplit = tab.shortname.split('::');
66+
const shortname = shortnameSplit[shortnameSplit.length - 1];
67+
return `/${shortname}` === givenTab;
68+
});
6569

6670
const mainTab = tabsRD.payload.page.length === 1
6771
? tabsRD.payload.page[0]
Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,18 @@
11
<div>
2-
<div class="modal-header">{{ headerLabel | translate:{ dsoName: name } }}
2+
<div class="modal-header">{{ headerLabel | translate:{ dsoName: dsoNameService.getName(dso) } }}
33
<button type="button" class="close" (click)="close()" aria-label="Close">
44
<span aria-hidden="true">×</span>
55
</button>
66
</div>
77
<div class="modal-body">
8-
<p>{{ infoLabel | translate:{ dsoName: name } }}</p>
8+
<p>{{ infoLabel | translate:{ dsoName: dsoNameService.getName(dso) } }}</p>
99
</div>
1010
<div class="modal-footer">
1111
<button type="button" class="cancel btn btn-outline-secondary" (click)="cancelPressed()" aria-label="Cancel">
12-
<i class="fas fa-times"></i> {{ cancelLabel | translate:{ dsoName: name } }}
12+
<i class="fas fa-times"></i> {{ cancelLabel | translate:{ dsoName: dsoNameService.getName(dso) } }}
1313
</button>
1414
<button type="button" class="confirm btn btn-{{brandColor}}" (click)="confirmPressed()" aria-label="Confirm" ngbAutofocus>
15-
<i *ngIf="confirmIcon" class="{{confirmIcon}}"></i> {{ confirmLabel | translate:{ dsoName: name } }}
15+
<i *ngIf="confirmIcon" class="{{confirmIcon}}"></i> {{ confirmLabel | translate:{ dsoName: dsoNameService.getName(dso) } }}
1616
</button>
1717
</div>
1818
</div>

0 commit comments

Comments
 (0)