Skip to content

Commit d8c504b

Browse files
committed
Merge branch 'main-cris' into ux-plus-cris
# Conflicts: # src/app/item-page/cris-item-page-tab.resolver.ts
2 parents 405166d + 6df74ce commit d8c504b

7 files changed

Lines changed: 173 additions & 126 deletions

File tree

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: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,7 @@ 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 {
28-
isEmpty,
29-
isNotEmpty,
30-
} from '../shared/empty.util';
27+
import { isNotEmpty } from '../shared/empty.util';
3128
import { createFailedRemoteDataObject$ } from '../shared/remote-data.utils';
3229
import { getItemPageRoute } from './item-page-routing-paths';
3330

@@ -66,7 +63,12 @@ export const crisItemPageTabResolver: ResolveFn<RemoteData<PaginatedList<CrisLay
6663
const givenTab = tabArguments[1];
6764
const hasViewer: boolean = isNotEmpty(tabArguments[2]) && tabArguments[2] === 'viewer';
6865
const itemPageRoute = getItemPageRoute(itemRD.payload);
69-
const isValidTab = isEmpty(givenTab) || tabsRD.payload.page.some((tab) => givenTab?.includes(tab.shortname));
66+
67+
const isValidTab = !givenTab || tabsRD.payload.page.some((tab) => {
68+
const shortnameSplit = tab.shortname.split('::');
69+
const shortname = shortnameSplit[shortnameSplit.length - 1];
70+
return `/${shortname}` === givenTab;
71+
});
7072

7173
const mainTab = tabsRD.payload.page.length === 1
7274
? tabsRD.payload.page[0]

src/app/shared/notifications/process-notification/process-notification.component.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@
3737
</div>
3838
</div>
3939

40-
<div *ngIf="(finished | async) && (files$ | async)?.length > 0">
40+
<div [attr.data-test]="'files-content'" *ngIf="(finished | async) && (files$ | async)?.length > 0">
4141
<div class="notification-content pl-1">{{ 'process.new.notification.process.files' | translate}}</div>
4242
<ds-file-download-link class="pl-1" *ngFor="let file of (files$ | async); let last=last;" [bitstream]="file">
4343
<span>{{getFileName(file)}}</span>

src/app/shared/notifications/process-notification/process-notification.component.spec.ts

Lines changed: 24 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,13 @@ import {
2121
TranslateModule,
2222
TranslateService,
2323
} from '@ngx-translate/core';
24+
import { BehaviorSubject } from 'rxjs';
2425

2526
import { AppConfig } from '../../../../config/app-config.interface';
2627
import { INotificationBoardOptions } from '../../../../config/notifications-config.interfaces';
2728
import { storeModuleConfig } from '../../../app.reducer';
2829
import { ProcessDataService } from '../../../core/data/processes/process-data.service';
29-
import { ThemedFileDownloadLinkComponent } from '../../file-download-link/themed-file-download-link.component';
30+
import { Bitstream } from '../../../core/shared/bitstream.model';
3031
import { TranslateLoaderMock } from '../../mocks/translate-loader.mock';
3132
import { createSuccessfulRemoteDataObject$ } from '../../remote-data.utils';
3233
import { createPaginatedList } from '../../testing/utils.test';
@@ -38,18 +39,18 @@ import { notificationsReducer } from '../notifications.reducers';
3839
import { NotificationsService } from '../notifications.service';
3940
import { ProcessNotificationComponent } from './process-notification.component';
4041

41-
xdescribe('ProcessNotificationComponent', () => {
42+
describe('ProcessNotificationComponent', () => {
4243

4344
let comp: ProcessNotificationComponent;
4445
let fixture: ComponentFixture<ProcessNotificationComponent>;
4546
let deTitle: DebugElement;
4647
let elTitle: HTMLElement;
4748
let deContent: DebugElement;
4849
let elContent: HTMLElement;
49-
let elType: HTMLElement;
5050

5151
const processService = jasmine.createSpyObj('processService', {
5252
getFiles: createSuccessfulRemoteDataObject$(createPaginatedList([])),
53+
getProcess: createSuccessfulRemoteDataObject$({ processStatus: '' }),
5354
});
5455

5556
beforeEach(waitForAsync(() => {
@@ -88,7 +89,7 @@ xdescribe('ProcessNotificationComponent', () => {
8889
NotificationsService,
8990
TranslateService,
9091
],
91-
}).overrideComponent(ProcessNotificationComponent, { remove: { imports: [ThemedFileDownloadLinkComponent] } }).compileComponents(); // compile template and css
92+
}).compileComponents(); // compile template and css
9293

9394
}));
9495

@@ -109,7 +110,6 @@ xdescribe('ProcessNotificationComponent', () => {
109110
elTitle = deTitle.nativeElement;
110111
deContent = fixture.debugElement.query(By.css('.notification-content'));
111112
elContent = deContent.nativeElement;
112-
elType = fixture.debugElement.query(By.css('.notification-icon')).nativeElement;
113113
});
114114

115115
it('should create component', () => {
@@ -118,37 +118,36 @@ xdescribe('ProcessNotificationComponent', () => {
118118

119119
it('should set Title', () => {
120120
fixture.detectChanges();
121-
expect(elTitle.textContent).toBe(comp.notification.title as string);
121+
expect(elTitle.textContent.trim()).toBe((comp.notification.title as string).trim());
122122
});
123123

124124
it('should set Content', () => {
125125
fixture.detectChanges();
126-
expect(elContent.textContent).toBe(comp.notification.content as string);
126+
expect(elContent.textContent.trim()).toBe('process.new.notification.process.processing');
127127
});
128128

129-
it('should set type', () => {
129+
it('Should display files section when finished is true and files are present', () => {
130+
comp.finished = new BehaviorSubject<boolean>(true);
131+
comp.files$ = new BehaviorSubject([{ name: 'file1', sizeBytes: 1024 }]) as BehaviorSubject<Bitstream[]>;
130132
fixture.detectChanges();
131-
expect(elType).toBeDefined();
133+
const filesSection = fixture.debugElement.query(By.css('.notification-content'));
134+
expect(filesSection).toBeTruthy();
132135
});
133136

134-
it('should have html content', () => {
135-
fixture = TestBed.createComponent(ProcessNotificationComponent);
136-
comp = fixture.componentInstance;
137-
const htmlContent = '<a class="btn btn-link p-0 m-0 pb-1" href="/test"><strong>test</strong></a>';
138-
comp.notification = {
139-
id: '1',
140-
type: NotificationType.Info,
141-
title: 'Notif. title',
142-
content: htmlContent,
143-
options: new NotificationOptions(),
144-
html: true,
145-
} as IProcessNotification;
146-
137+
it('Should not display files section when finished is false', () => {
138+
comp.finished = new BehaviorSubject<boolean>(false);
139+
comp.files$ = new BehaviorSubject([{ name: 'file1', sizeBytes: 1024 }]) as BehaviorSubject<Bitstream[]>;
147140
fixture.detectChanges();
141+
const filesSection = fixture.debugElement.query(By.css('.notification-content[data-test="files-content"]'));
142+
expect(filesSection).toBeFalsy();
143+
});
148144

149-
deContent = fixture.debugElement.query(By.css('.notification-html'));
150-
elContent = deContent.nativeElement;
151-
expect(elContent.innerHTML).toEqual(htmlContent);
145+
it('Should not display files section when no files are present', () => {
146+
comp.finished = new BehaviorSubject<boolean>(true);
147+
comp.files$ = new BehaviorSubject([]);
148+
fixture.detectChanges();
149+
const filesSection = fixture.debugElement.query(By.css('.notification-content[data-test="files-content"]'));
150+
expect(filesSection).toBeFalsy();
152151
});
153152

154153
});

0 commit comments

Comments
 (0)