From e6557a5eb1d14ca4164f29e876bebe1a48be6b5c Mon Sep 17 00:00:00 2001 From: amadulhaxxani Date: Wed, 25 Feb 2026 10:25:30 +0100 Subject: [PATCH] add search icon to community and collection add search icon to community and collection, click should navigate to community/collection pre-selected advance search page add tests to confirm the new navigation --- .../collection-page.component.html | 4 +- .../collection-page.component.spec.ts | 99 +++++++++++++++++++ .../community-page.component.html | 4 +- .../community-page.component.spec.ts | 81 +++++++++++++++ .../dso-page/dso-edit-menu.resolver.spec.ts | 23 +++++ .../shared/dso-page/dso-edit-menu.resolver.ts | 17 ++++ .../dso-edit-menu-section.component.html | 3 +- .../dso-edit-menu-section.component.spec.ts | 10 +- 8 files changed, 237 insertions(+), 4 deletions(-) create mode 100644 src/app/collection-page/collection-page.component.spec.ts create mode 100644 src/app/community-page/community-page.component.spec.ts diff --git a/src/app/collection-page/collection-page.component.html b/src/app/collection-page/collection-page.component.html index ec8da3c7e7a..96e17f6b4cf 100644 --- a/src/app/collection-page/collection-page.component.html +++ b/src/app/collection-page/collection-page.component.html @@ -32,7 +32,9 @@ [title]="'collection.page.news'"> - +
+ +
diff --git a/src/app/collection-page/collection-page.component.spec.ts b/src/app/collection-page/collection-page.component.spec.ts new file mode 100644 index 00000000000..7444a9128ed --- /dev/null +++ b/src/app/collection-page/collection-page.component.spec.ts @@ -0,0 +1,99 @@ +import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; +import { By } from '@angular/platform-browser'; +import { NO_ERRORS_SCHEMA } from '@angular/core'; +import { ActivatedRoute, Router } from '@angular/router'; +import { TranslateModule } from '@ngx-translate/core'; +import { of as observableOf } from 'rxjs'; +import { NoopAnimationsModule } from '@angular/platform-browser/animations'; + +import { CollectionPageComponent } from './collection-page.component'; +import { CollectionDataService } from '../core/data/collection-data.service'; +import { SearchService } from '../core/shared/search/search.service'; +import { AuthService } from '../core/auth/auth.service'; +import { PaginationService } from '../core/pagination/pagination.service'; +import { AuthorizationDataService } from '../core/data/feature-authorization/authorization-data.service'; +import { DSONameService } from '../core/breadcrumbs/dso-name.service'; +import { APP_CONFIG } from '../../config/app-config.interface'; +import { VarDirective } from '../shared/utils/var.directive'; + +describe('CollectionPageComponent', () => { + let component: CollectionPageComponent; + let fixture: ComponentFixture; + + const collectionUUID = '22222222-2222-2222-2222-222222222222'; + const collection = { + id: collectionUUID, + uuid: collectionUUID, + type: 'collection', + handle: '123456789/2', + introductoryText: null, + sidebarText: null, + copyrightText: null, + logo: observableOf({ hasSucceeded: true, payload: undefined }) + }; + + const collectionRD = { + hasSucceeded: true, + hasFailed: false, + statusCode: 200, + payload: collection + }; + + beforeEach(waitForAsync(() => { + TestBed.configureTestingModule({ + imports: [TranslateModule.forRoot(), NoopAnimationsModule], + declarations: [CollectionPageComponent, VarDirective], + providers: [ + { provide: ActivatedRoute, useValue: { data: observableOf({ dso: collectionRD }) } }, + { provide: Router, useValue: { navigateByUrl: jasmine.createSpy('navigateByUrl'), url: '/' } }, + { provide: CollectionDataService, useValue: {} }, + { + provide: SearchService, + useValue: { + search: () => observableOf({ hasSucceeded: true, payload: { page: [] } }) + } + }, + { + provide: AuthService, + useValue: { + isAuthenticated: () => observableOf(false), + setRedirectUrl: jasmine.createSpy('setRedirectUrl') + } + }, + { + provide: PaginationService, + useValue: { + getCurrentPagination: () => observableOf({ currentPage: 1, pageSize: 10 }), + getCurrentSort: () => observableOf({ field: 'dc.date.accessioned', direction: 'DESC' }), + clearPagination: jasmine.createSpy('clearPagination') + } + }, + { provide: AuthorizationDataService, useValue: { isAuthorized: () => observableOf(false) } }, + { provide: DSONameService, useValue: { getName: () => 'Test Collection' } }, + { provide: APP_CONFIG, useValue: { browseBy: { pageSize: 10 } } } + ], + schemas: [NO_ERRORS_SCHEMA] + }).compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(CollectionPageComponent); + component = fixture.componentInstance; + + spyOn(component, 'ngOnInit').and.callFake(() => { + component.collectionRD$ = observableOf(collectionRD as any); + component.logoRD$ = observableOf({ hasSucceeded: true, payload: undefined } as any); + component.itemRD$ = observableOf({ hasSucceeded: true, payload: { page: [] } } as any); + }); + + fixture.detectChanges(); + }); + + it('should render the dso edit menu in the header action area', () => { + expect(component).toBeTruthy(); + + const editMenu = fixture.debugElement.query(By.css('ds-dso-edit-menu')); + + expect(editMenu).toBeTruthy(); + }); +}); diff --git a/src/app/community-page/community-page.component.html b/src/app/community-page/community-page.component.html index f5885104550..d4535878518 100644 --- a/src/app/community-page/community-page.component.html +++ b/src/app/community-page/community-page.component.html @@ -19,7 +19,9 @@ [title]="'community.page.news'"> - +
+ +
diff --git a/src/app/community-page/community-page.component.spec.ts b/src/app/community-page/community-page.component.spec.ts new file mode 100644 index 00000000000..69e9687e509 --- /dev/null +++ b/src/app/community-page/community-page.component.spec.ts @@ -0,0 +1,81 @@ +import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; +import { By } from '@angular/platform-browser'; +import { NO_ERRORS_SCHEMA } from '@angular/core'; +import { ActivatedRoute, Router } from '@angular/router'; +import { TranslateModule } from '@ngx-translate/core'; +import { of as observableOf } from 'rxjs'; +import { NoopAnimationsModule } from '@angular/platform-browser/animations'; + +import { CommunityPageComponent } from './community-page.component'; +import { CommunityDataService } from '../core/data/community-data.service'; +import { MetadataService } from '../core/metadata/metadata.service'; +import { AuthService } from '../core/auth/auth.service'; +import { AuthorizationDataService } from '../core/data/feature-authorization/authorization-data.service'; +import { DSONameService } from '../core/breadcrumbs/dso-name.service'; +import { VarDirective } from '../shared/utils/var.directive'; + +describe('CommunityPageComponent', () => { + let component: CommunityPageComponent; + let fixture: ComponentFixture; + + const communityUUID = '11111111-1111-1111-1111-111111111111'; + const community = { + id: communityUUID, + uuid: communityUUID, + handle: '123456789/1', + introductoryText: null, + sidebarText: null, + copyrightText: null, + logo: observableOf({ hasSucceeded: true, payload: undefined }) + }; + + const communityRD = { + hasSucceeded: true, + hasFailed: false, + statusCode: 200, + payload: community + }; + + beforeEach(waitForAsync(() => { + TestBed.configureTestingModule({ + imports: [TranslateModule.forRoot(), NoopAnimationsModule], + declarations: [CommunityPageComponent, VarDirective], + providers: [ + { provide: ActivatedRoute, useValue: { data: observableOf({ dso: communityRD }) } }, + { provide: Router, useValue: { navigateByUrl: jasmine.createSpy('navigateByUrl'), url: '/' } }, + { provide: CommunityDataService, useValue: {} }, + { provide: MetadataService, useValue: {} }, + { + provide: AuthService, + useValue: { + isAuthenticated: () => observableOf(false), + setRedirectUrl: jasmine.createSpy('setRedirectUrl') + } + }, + { provide: AuthorizationDataService, useValue: { isAuthorized: () => observableOf(false) } }, + { provide: DSONameService, useValue: { getName: () => 'Test Community' } } + ], + schemas: [NO_ERRORS_SCHEMA] + }).compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(CommunityPageComponent); + component = fixture.componentInstance; + + spyOn(component, 'ngOnInit').and.callFake(() => { + component.communityRD$ = observableOf(communityRD as any); + component.logoRD$ = observableOf({ hasSucceeded: true, payload: undefined } as any); + }); + + fixture.detectChanges(); + }); + + it('should render the dso edit menu in the header action area', () => { + expect(component).toBeTruthy(); + + const editMenu = fixture.debugElement.query(By.css('ds-dso-edit-menu')); + + expect(editMenu).toBeTruthy(); + }); +}); diff --git a/src/app/shared/dso-page/dso-edit-menu.resolver.spec.ts b/src/app/shared/dso-page/dso-edit-menu.resolver.spec.ts index e28a416f230..224f1c89655 100644 --- a/src/app/shared/dso-page/dso-edit-menu.resolver.spec.ts +++ b/src/app/shared/dso-page/dso-edit-menu.resolver.spec.ts @@ -267,6 +267,16 @@ describe('DSOEditMenuResolver', () => { it('should return Community/Collection-specific entries', (done) => { const result = resolver.getDsoMenus(testObject, route, state); combineLatest(result).pipe(map(flatten)).subscribe((menu) => { + const searchEntry = menu.find(entry => entry.id === 'search-dso'); + expect(searchEntry).toBeTruthy(); + expect(searchEntry.active).toBeFalse(); + expect(searchEntry.visible).toBeTrue(); + expect(searchEntry.model.type).toEqual(MenuItemType.LINK); + expect((searchEntry.model as LinkMenuItemModel).text).toEqual('search.title'); + expect((searchEntry.model as LinkMenuItemModel).link).toEqual('/search'); + expect((searchEntry.model as LinkMenuItemModel).queryParams['spc.page']).toEqual('1'); + expect((searchEntry.model as LinkMenuItemModel).queryParams.scope).toEqual('test-community-uuid'); + const subscribeEntry = menu.find(entry => entry.id === 'subscribe'); expect(subscribeEntry).toBeTruthy(); expect(subscribeEntry.active).toBeFalse(); @@ -318,6 +328,16 @@ describe('DSOEditMenuResolver', () => { it('should return Community/Collection-specific entries', (done) => { const result = resolver.getDsoMenus(testObject, route, state); combineLatest(result).pipe(map(flatten)).subscribe((menu) => { + const searchEntry = menu.find(entry => entry.id === 'search-dso'); + expect(searchEntry).toBeTruthy(); + expect(searchEntry.active).toBeFalse(); + expect(searchEntry.visible).toBeTrue(); + expect(searchEntry.model.type).toEqual(MenuItemType.LINK); + expect((searchEntry.model as LinkMenuItemModel).text).toEqual('search.title'); + expect((searchEntry.model as LinkMenuItemModel).link).toEqual('/search'); + expect((searchEntry.model as LinkMenuItemModel).queryParams['spc.page']).toEqual('1'); + expect((searchEntry.model as LinkMenuItemModel).queryParams.scope).toEqual('test-collection-uuid'); + const subscribeEntry = menu.find(entry => entry.id === 'subscribe'); expect(subscribeEntry).toBeTruthy(); expect(subscribeEntry.active).toBeFalse(); @@ -378,6 +398,9 @@ describe('DSOEditMenuResolver', () => { it('should not return Community/Collection-specific entries', (done) => { const result = resolver.getDsoMenus(testObject, route, state); combineLatest(result).pipe(map(flatten)).subscribe((menu) => { + const searchEntry = menu.find(entry => entry.id === 'search-dso'); + expect(searchEntry).toBeFalsy(); + const subscribeEntry = menu.find(entry => entry.id === 'subscribe'); expect(subscribeEntry).toBeFalsy(); done(); diff --git a/src/app/shared/dso-page/dso-edit-menu.resolver.ts b/src/app/shared/dso-page/dso-edit-menu.resolver.ts index 1ade4578405..22f533f073f 100644 --- a/src/app/shared/dso-page/dso-edit-menu.resolver.ts +++ b/src/app/shared/dso-page/dso-edit-menu.resolver.ts @@ -192,6 +192,23 @@ export class DSOEditMenuResolver implements Resolve<{ [key: string]: MenuSection ]).pipe( map(([canSubscribe]) => { return [ + { + id: 'search-dso', + active: false, + visible: true, + model: { + type: MenuItemType.LINK, + disabled: false, + text: 'search.title', + link: '/search', + queryParams: { + 'spc.page': '1', + scope: dso.uuid + } + } as LinkMenuItemModel, + icon: 'search', + index: 3 + }, { id: 'subscribe', active: false, diff --git a/src/app/shared/dso-page/dso-edit-menu/dso-edit-menu-section/dso-edit-menu-section.component.html b/src/app/shared/dso-page/dso-edit-menu/dso-edit-menu-section/dso-edit-menu-section.component.html index 0738e2f28ab..e4fd66481e6 100644 --- a/src/app/shared/dso-page/dso-edit-menu/dso-edit-menu-section/dso-edit-menu-section.component.html +++ b/src/app/shared/dso-page/dso-edit-menu/dso-edit-menu-section/dso-edit-menu-section.component.html @@ -1,7 +1,8 @@
+ [routerLink]="itemModel.link" + [queryParams]="itemModel.queryParams"> {{itemModel.text | translate}} diff --git a/src/app/shared/dso-page/dso-edit-menu/dso-edit-menu-section/dso-edit-menu-section.component.spec.ts b/src/app/shared/dso-page/dso-edit-menu/dso-edit-menu-section/dso-edit-menu-section.component.spec.ts index bdf121f7995..aa5c62fce1c 100644 --- a/src/app/shared/dso-page/dso-edit-menu/dso-edit-menu-section/dso-edit-menu-section.component.spec.ts +++ b/src/app/shared/dso-page/dso-edit-menu/dso-edit-menu-section/dso-edit-menu-section.component.spec.ts @@ -58,7 +58,10 @@ describe('DsoEditMenuSectionComponent', () => { type: MenuItemType.LINK, disabled: false, text: 'text', - link: 'link' + link: 'link', + queryParams: { + scope: 'test-scope-id' + } }, icon: iconString }; @@ -158,6 +161,11 @@ describe('DsoEditMenuSectionComponent', () => { expect(fixture.debugElement.query(By.css('a'))).not.toBeNull(); }); + it('should bind queryParams on the link element', () => { + const link = fixture.debugElement.query(By.css('a')); + expect(link.properties.queryParams.scope).toEqual('test-scope-id'); + }); + }); });