From 5e24ed1fb613a220925284151d7bb40337b3f6b1 Mon Sep 17 00:00:00 2001 From: Nona Luypaert Date: Fri, 6 Sep 2024 16:55:25 +0200 Subject: [PATCH 1/2] 117648: Add tests for basic MenuProviders --- .../providers/access-control.menu.spec.ts | 95 +++++++++++++++++ .../menu/providers/admin-search.menu.spec.ts | 57 ++++++++++ .../shared/menu/providers/browse.menu.spec.ts | 87 +++++++++++++++ .../providers/community-list.menu.spec.ts | 48 +++++++++ .../menu/providers/curation.menu.spec.ts | 57 ++++++++++ .../shared/menu/providers/edit.menu.spec.ts | 92 ++++++++++++++++ .../shared/menu/providers/export.menu.spec.ts | 85 +++++++++++++++ .../shared/menu/providers/health.menu.spec.ts | 57 ++++++++++ .../shared/menu/providers/import.menu.spec.ts | 83 +++++++++++++++ .../shared/menu/providers/new.menu.spec.ts | 100 ++++++++++++++++++ src/app/shared/menu/providers/new.menu.ts | 4 +- .../menu/providers/processes.menu.spec.ts | 57 ++++++++++ .../menu/providers/registries.menu.spec.ts | 82 ++++++++++++++ .../providers/system-wide-alert.menu.spec.ts | 57 ++++++++++ .../menu/providers/workflow.menu.spec.ts | 57 ++++++++++ src/app/shared/testing/browse-service.stub.ts | 22 ++++ src/app/shared/testing/script-service.stub.ts | 18 ++++ 17 files changed, 1056 insertions(+), 2 deletions(-) create mode 100644 src/app/shared/menu/providers/access-control.menu.spec.ts create mode 100644 src/app/shared/menu/providers/admin-search.menu.spec.ts create mode 100644 src/app/shared/menu/providers/browse.menu.spec.ts create mode 100644 src/app/shared/menu/providers/community-list.menu.spec.ts create mode 100644 src/app/shared/menu/providers/curation.menu.spec.ts create mode 100644 src/app/shared/menu/providers/edit.menu.spec.ts create mode 100644 src/app/shared/menu/providers/export.menu.spec.ts create mode 100644 src/app/shared/menu/providers/health.menu.spec.ts create mode 100644 src/app/shared/menu/providers/import.menu.spec.ts create mode 100644 src/app/shared/menu/providers/new.menu.spec.ts create mode 100644 src/app/shared/menu/providers/processes.menu.spec.ts create mode 100644 src/app/shared/menu/providers/registries.menu.spec.ts create mode 100644 src/app/shared/menu/providers/system-wide-alert.menu.spec.ts create mode 100644 src/app/shared/menu/providers/workflow.menu.spec.ts create mode 100644 src/app/shared/testing/browse-service.stub.ts create mode 100644 src/app/shared/testing/script-service.stub.ts diff --git a/src/app/shared/menu/providers/access-control.menu.spec.ts b/src/app/shared/menu/providers/access-control.menu.spec.ts new file mode 100644 index 0000000000..d9284a75c4 --- /dev/null +++ b/src/app/shared/menu/providers/access-control.menu.spec.ts @@ -0,0 +1,95 @@ +/** + * The contents of this file are subject to the license and copyright + * detailed in the LICENSE and NOTICE files at the root of the source + * tree and available online at + * + * http://www.dspace.org/license/ + */ + +import { TestBed } from '@angular/core/testing'; +import { MenuItemType } from '../menu-item-type.model'; +import { MenuSubSection, MenuTopSection } from './expandable-menu-provider'; +import { AuthorizationDataServiceStub } from '../../testing/authorization-service.stub'; +import { of as observableOf } from 'rxjs'; +import { AuthorizationDataService } from '../../../core/data/feature-authorization/authorization-data.service'; +import { FeatureID } from '../../../core/data/feature-authorization/feature-id'; +import { AccessControlMenuProvider } from './access-control.menu'; +import { ScriptDataService } from '../../../core/data/processes/script-data.service'; +import { ScriptServiceStub } from '../../testing/script-service.stub'; + +const expectedTopSection: MenuTopSection = { + model: { + type: MenuItemType.TEXT, + text: 'menu.section.access_control', + }, + icon: 'key' +}; + +const expectedSubSections: MenuSubSection[] = [ + { + visible: true, + model: { + type: MenuItemType.LINK, + text: 'menu.section.access_control_people', + link: '/access-control/epeople', + }, + }, + { + visible: false, + model: { + type: MenuItemType.LINK, + text: 'menu.section.access_control_groups', + link: '/access-control/groups', + }, + }, + { + visible: true, + model: { + type: MenuItemType.LINK, + text: 'menu.section.access_control_bulk', + link: '/access-control/bulk-access', + }, + }, +]; + +describe('AccessControlMenuProvider', () => { + let provider: AccessControlMenuProvider; + let authorizationServiceStub = new AuthorizationDataServiceStub(); + + beforeEach(() => { + spyOn(authorizationServiceStub, 'isAuthorized').and.callFake((id: FeatureID) => { + if (id === FeatureID.CanManageGroups) { + return observableOf(false); + } else { + return observableOf(true); + } + }); + + TestBed.configureTestingModule({ + providers: [ + AccessControlMenuProvider, + { provide: AuthorizationDataService, useValue: authorizationServiceStub }, + { provide: ScriptDataService, useClass: ScriptServiceStub }, + ], + }); + provider = TestBed.inject(AccessControlMenuProvider); + }); + + it('should be created', () => { + expect(provider).toBeTruthy(); + }); + + it('getTopSection should return expected menu section', (done) => { + provider.getTopSection().subscribe((section) => { + expect(section).toEqual(expectedTopSection); + done(); + }); + }); + + it('getSubSections should return expected menu sections', (done) => { + provider.getSubSections().subscribe((sections) => { + expect(sections).toEqual(expectedSubSections); + done(); + }); + }); +}); diff --git a/src/app/shared/menu/providers/admin-search.menu.spec.ts b/src/app/shared/menu/providers/admin-search.menu.spec.ts new file mode 100644 index 0000000000..0471215578 --- /dev/null +++ b/src/app/shared/menu/providers/admin-search.menu.spec.ts @@ -0,0 +1,57 @@ +/** + * The contents of this file are subject to the license and copyright + * detailed in the LICENSE and NOTICE files at the root of the source + * tree and available online at + * + * http://www.dspace.org/license/ + */ + +import { TestBed } from '@angular/core/testing'; +import { PartialMenuSection } from '../menu-provider'; +import { MenuItemType } from '../menu-item-type.model'; +import { AdminSearchMenuProvider } from './admin-search.menu'; +import { AuthorizationDataServiceStub } from '../../testing/authorization-service.stub'; +import { of as observableOf } from 'rxjs'; +import { AuthorizationDataService } from '../../../core/data/feature-authorization/authorization-data.service'; + +const expectedSections: PartialMenuSection[] = [ + { + visible: true, + model: { + type: MenuItemType.LINK, + text: 'menu.section.admin_search', + link: '/admin/search', + }, + icon: 'search', + }, +]; + +describe('AdminSearchMenuProvider', () => { + let provider: AdminSearchMenuProvider; + let authorizationServiceStub = new AuthorizationDataServiceStub(); + + beforeEach(() => { + spyOn(authorizationServiceStub, 'isAuthorized').and.returnValue( + observableOf(true) + ); + + TestBed.configureTestingModule({ + providers: [ + AdminSearchMenuProvider, + { provide: AuthorizationDataService, useValue: authorizationServiceStub }, + ], + }); + provider = TestBed.inject(AdminSearchMenuProvider); + }); + + it('should be created', () => { + expect(provider).toBeTruthy(); + }); + + it('getSections should return expected menu sections', (done) => { + provider.getSections().subscribe((sections) => { + expect(sections).toEqual(expectedSections); + done(); + }); + }); +}); diff --git a/src/app/shared/menu/providers/browse.menu.spec.ts b/src/app/shared/menu/providers/browse.menu.spec.ts new file mode 100644 index 0000000000..20ac0f92be --- /dev/null +++ b/src/app/shared/menu/providers/browse.menu.spec.ts @@ -0,0 +1,87 @@ +/** + * The contents of this file are subject to the license and copyright + * detailed in the LICENSE and NOTICE files at the root of the source + * tree and available online at + * + * http://www.dspace.org/license/ + */ + +import { TestBed } from '@angular/core/testing'; +import { BrowseMenuProvider } from './browse.menu'; +import { MenuItemType } from '../menu-item-type.model'; +import { MenuSubSection, MenuTopSection } from './expandable-menu-provider'; +import { BrowseService } from '../../../core/browse/browse.service'; +import { BrowseServiceStub } from '../../testing/browse-service.stub'; +import { ObjectCacheService } from '../../../core/cache/object-cache.service'; +import { getMockObjectCacheService } from '../../mocks/object-cache.service.mock'; +import { BrowseDefinition } from '../../../core/shared/browse-definition.model'; +import { createSuccessfulRemoteDataObject$ } from '../../remote-data.utils'; +import { createPaginatedList } from '../../testing/utils.test'; + +const expectedTopSection: MenuTopSection = { + model: { + type: MenuItemType.TEXT, + text: 'menu.section.browse_global', + }, + icon: 'globe', + }; + +const expectedSubSections: MenuSubSection[] = [ + { + visible: true, + model: { + type: MenuItemType.LINK, + text: 'menu.section.browse_global_by_author', + link: '/browse/author', + }, + }, + { + visible: true, + model: { + type: MenuItemType.LINK, + text: 'menu.section.browse_global_by_subject', + link: '/browse/subject', + }, + }, +]; + +describe('BrowseMenuProvider', () => { + let provider: BrowseMenuProvider; + let browseServiceStub = new BrowseServiceStub(); + + beforeEach(() => { + spyOn(browseServiceStub, 'getBrowseDefinitions').and.returnValue( + createSuccessfulRemoteDataObject$(createPaginatedList([ + { id: 'author' } as BrowseDefinition, + { id: 'subject' } as BrowseDefinition, + ])) + ); + + TestBed.configureTestingModule({ + providers: [ + BrowseMenuProvider, + { provide: BrowseService, useValue: browseServiceStub }, + { provide: ObjectCacheService, useValue: getMockObjectCacheService() }, + ], + }); + provider = TestBed.inject(BrowseMenuProvider); + }); + + it('should be created', () => { + expect(provider).toBeTruthy(); + }); + + it('getTopSection should return expected menu section', (done) => { + provider.getTopSection().subscribe((section) => { + expect(section).toEqual(expectedTopSection); + done(); + }); + }); + + it('getSubSections should return expected menu sections', (done) => { + provider.getSubSections().subscribe((sections) => { + expect(sections).toEqual(expectedSubSections); + done(); + }); + }); +}); diff --git a/src/app/shared/menu/providers/community-list.menu.spec.ts b/src/app/shared/menu/providers/community-list.menu.spec.ts new file mode 100644 index 0000000000..b0e037d228 --- /dev/null +++ b/src/app/shared/menu/providers/community-list.menu.spec.ts @@ -0,0 +1,48 @@ +/** + * The contents of this file are subject to the license and copyright + * detailed in the LICENSE and NOTICE files at the root of the source + * tree and available online at + * + * http://www.dspace.org/license/ + */ + +import { TestBed } from '@angular/core/testing'; +import { CommunityListMenuProvider } from './community-list.menu'; +import { PartialMenuSection } from '../menu-provider'; +import { MenuItemType } from '../menu-item-type.model'; + +const expectedSections: PartialMenuSection[] = [ + { + visible: true, + model: { + type: MenuItemType.LINK, + text: `menu.section.browse_global_communities_and_collections`, + link: `/community-list`, + }, + icon: 'diagram-project' + }, +]; + +describe('CommunityListMenuProvider', () => { + let provider: CommunityListMenuProvider; + + beforeEach(() => { + TestBed.configureTestingModule({ + providers: [ + CommunityListMenuProvider, + ], + }); + provider = TestBed.inject(CommunityListMenuProvider); + }); + + it('should be created', () => { + expect(provider).toBeTruthy(); + }); + + it('getSections should return expected menu sections', (done) => { + provider.getSections().subscribe((sections) => { + expect(sections).toEqual(expectedSections); + done(); + }); + }); +}); diff --git a/src/app/shared/menu/providers/curation.menu.spec.ts b/src/app/shared/menu/providers/curation.menu.spec.ts new file mode 100644 index 0000000000..5225091f75 --- /dev/null +++ b/src/app/shared/menu/providers/curation.menu.spec.ts @@ -0,0 +1,57 @@ +/** + * The contents of this file are subject to the license and copyright + * detailed in the LICENSE and NOTICE files at the root of the source + * tree and available online at + * + * http://www.dspace.org/license/ + */ + +import { TestBed } from '@angular/core/testing'; +import { PartialMenuSection } from '../menu-provider'; +import { MenuItemType } from '../menu-item-type.model'; +import { AuthorizationDataServiceStub } from '../../testing/authorization-service.stub'; +import { of as observableOf } from 'rxjs'; +import { AuthorizationDataService } from '../../../core/data/feature-authorization/authorization-data.service'; +import { CurationMenuProvider } from './curation.menu'; + +const expectedSections: PartialMenuSection[] = [ + { + visible: true, + model: { + type: MenuItemType.LINK, + text: 'menu.section.curation_task', + link: 'admin/curation-tasks', + }, + icon: 'filter', + }, +]; + +describe('CurationMenuProvider', () => { + let provider: CurationMenuProvider; + let authorizationServiceStub = new AuthorizationDataServiceStub(); + + beforeEach(() => { + spyOn(authorizationServiceStub, 'isAuthorized').and.returnValue( + observableOf(true) + ); + + TestBed.configureTestingModule({ + providers: [ + CurationMenuProvider, + { provide: AuthorizationDataService, useValue: authorizationServiceStub }, + ], + }); + provider = TestBed.inject(CurationMenuProvider); + }); + + it('should be created', () => { + expect(provider).toBeTruthy(); + }); + + it('getSections should return expected menu sections', (done) => { + provider.getSections().subscribe((sections) => { + expect(sections).toEqual(expectedSections); + done(); + }); + }); +}); diff --git a/src/app/shared/menu/providers/edit.menu.spec.ts b/src/app/shared/menu/providers/edit.menu.spec.ts new file mode 100644 index 0000000000..b3204cc818 --- /dev/null +++ b/src/app/shared/menu/providers/edit.menu.spec.ts @@ -0,0 +1,92 @@ +/** + * The contents of this file are subject to the license and copyright + * detailed in the LICENSE and NOTICE files at the root of the source + * tree and available online at + * + * http://www.dspace.org/license/ + */ + +import { TestBed } from '@angular/core/testing'; +import { MenuItemType } from '../menu-item-type.model'; +import { MenuSubSection, MenuTopSection } from './expandable-menu-provider'; +import { AuthorizationDataServiceStub } from '../../testing/authorization-service.stub'; +import { of as observableOf } from 'rxjs'; +import { AuthorizationDataService } from '../../../core/data/feature-authorization/authorization-data.service'; +import { FeatureID } from '../../../core/data/feature-authorization/feature-id'; +import { EditMenuProvider } from './edit.menu'; + +const expectedTopSection: MenuTopSection = { + model: { + type: MenuItemType.TEXT, + text: 'menu.section.edit' + }, + icon: 'pencil', +}; + +const expectedSubSections: MenuSubSection[] = [ + { + visible: true, + model: { + type: MenuItemType.ONCLICK, + text: 'menu.section.edit_community', + function: jasmine.any(Function) as any, + }, + }, + { + visible: false, + model: { + type: MenuItemType.ONCLICK, + text: 'menu.section.edit_collection', + function: jasmine.any(Function) as any, + }, + }, + { + visible: true, + model: { + type: MenuItemType.ONCLICK, + text: 'menu.section.edit_item', + function: jasmine.any(Function) as any, + }, + }, +]; + +describe('EditMenuProvider', () => { + let provider: EditMenuProvider; + let authorizationServiceStub = new AuthorizationDataServiceStub(); + + beforeEach(() => { + spyOn(authorizationServiceStub, 'isAuthorized').and.callFake((id: FeatureID) => { + if (id === FeatureID.IsCollectionAdmin) { + return observableOf(false); + } else { + return observableOf(true); + } + }); + + TestBed.configureTestingModule({ + providers: [ + EditMenuProvider, + { provide: AuthorizationDataService, useValue: authorizationServiceStub }, + ], + }); + provider = TestBed.inject(EditMenuProvider); + }); + + it('should be created', () => { + expect(provider).toBeTruthy(); + }); + + it('getTopSection should return expected menu section', (done) => { + provider.getTopSection().subscribe((section) => { + expect(section).toEqual(expectedTopSection); + done(); + }); + }); + + it('getSubSections should return expected menu sections', (done) => { + provider.getSubSections().subscribe((sections) => { + expect(sections).toEqual(expectedSubSections); + done(); + }); + }); +}); diff --git a/src/app/shared/menu/providers/export.menu.spec.ts b/src/app/shared/menu/providers/export.menu.spec.ts new file mode 100644 index 0000000000..662622b594 --- /dev/null +++ b/src/app/shared/menu/providers/export.menu.spec.ts @@ -0,0 +1,85 @@ +/** + * The contents of this file are subject to the license and copyright + * detailed in the LICENSE and NOTICE files at the root of the source + * tree and available online at + * + * http://www.dspace.org/license/ + */ + +import { TestBed } from '@angular/core/testing'; +import { MenuItemType } from '../menu-item-type.model'; +import { MenuSubSection, MenuTopSection } from './expandable-menu-provider'; +import { AuthorizationDataServiceStub } from '../../testing/authorization-service.stub'; +import { of as observableOf } from 'rxjs'; +import { AuthorizationDataService } from '../../../core/data/feature-authorization/authorization-data.service'; +import { ScriptDataService } from '../../../core/data/processes/script-data.service'; +import { ScriptServiceStub } from '../../testing/script-service.stub'; +import { ExportMenuProvider } from './export.menu'; + +const expectedTopSection: MenuTopSection = { + model: { + type: MenuItemType.TEXT, + text: 'menu.section.export', + }, + icon: 'file-export', + shouldPersistOnRouteChange: true, +}; + +const expectedSubSections: MenuSubSection[] = [ + { + visible: true, + model: { + type: MenuItemType.ONCLICK, + text: 'menu.section.export_metadata', + function: jasmine.any(Function) as any, + }, + shouldPersistOnRouteChange: true, + }, + { + visible: true, + model: { + type: MenuItemType.ONCLICK, + text: 'menu.section.export_batch', + function: jasmine.any(Function) as any, + }, + shouldPersistOnRouteChange: true, + } +]; + +describe('ExportMenuProvider', () => { + let provider: ExportMenuProvider; + let authorizationServiceStub = new AuthorizationDataServiceStub(); + + beforeEach(() => { + spyOn(authorizationServiceStub, 'isAuthorized').and.returnValue( + observableOf(true) + ); + + TestBed.configureTestingModule({ + providers: [ + ExportMenuProvider, + { provide: AuthorizationDataService, useValue: authorizationServiceStub }, + { provide: ScriptDataService, useClass: ScriptServiceStub }, + ], + }); + provider = TestBed.inject(ExportMenuProvider); + }); + + it('should be created', () => { + expect(provider).toBeTruthy(); + }); + + it('getTopSection should return expected menu section', (done) => { + provider.getTopSection().subscribe((section) => { + expect(section).toEqual(expectedTopSection); + done(); + }); + }); + + it('getSubSections should return expected menu sections', (done) => { + provider.getSubSections().subscribe((sections) => { + expect(sections).toEqual(expectedSubSections); + done(); + }); + }); +}); diff --git a/src/app/shared/menu/providers/health.menu.spec.ts b/src/app/shared/menu/providers/health.menu.spec.ts new file mode 100644 index 0000000000..6e10e3cc5f --- /dev/null +++ b/src/app/shared/menu/providers/health.menu.spec.ts @@ -0,0 +1,57 @@ +/** + * The contents of this file are subject to the license and copyright + * detailed in the LICENSE and NOTICE files at the root of the source + * tree and available online at + * + * http://www.dspace.org/license/ + */ + +import { TestBed } from '@angular/core/testing'; +import { PartialMenuSection } from '../menu-provider'; +import { MenuItemType } from '../menu-item-type.model'; +import { AuthorizationDataServiceStub } from '../../testing/authorization-service.stub'; +import { of as observableOf } from 'rxjs'; +import { AuthorizationDataService } from '../../../core/data/feature-authorization/authorization-data.service'; +import { HealthMenuProvider } from './health.menu'; + +const expectedSections: PartialMenuSection[] = [ + { + visible: true, + model: { + type: MenuItemType.LINK, + text: 'menu.section.health', + link: '/health', + }, + icon: 'heartbeat', + }, +]; + +describe('HealthMenuProvider', () => { + let provider: HealthMenuProvider; + let authorizationServiceStub = new AuthorizationDataServiceStub(); + + beforeEach(() => { + spyOn(authorizationServiceStub, 'isAuthorized').and.returnValue( + observableOf(true) + ); + + TestBed.configureTestingModule({ + providers: [ + HealthMenuProvider, + { provide: AuthorizationDataService, useValue: authorizationServiceStub }, + ], + }); + provider = TestBed.inject(HealthMenuProvider); + }); + + it('should be created', () => { + expect(provider).toBeTruthy(); + }); + + it('getSections should return expected menu sections', (done) => { + provider.getSections().subscribe((sections) => { + expect(sections).toEqual(expectedSections); + done(); + }); + }); +}); diff --git a/src/app/shared/menu/providers/import.menu.spec.ts b/src/app/shared/menu/providers/import.menu.spec.ts new file mode 100644 index 0000000000..08223f31d7 --- /dev/null +++ b/src/app/shared/menu/providers/import.menu.spec.ts @@ -0,0 +1,83 @@ +/** + * The contents of this file are subject to the license and copyright + * detailed in the LICENSE and NOTICE files at the root of the source + * tree and available online at + * + * http://www.dspace.org/license/ + */ + +import { TestBed } from '@angular/core/testing'; +import { MenuItemType } from '../menu-item-type.model'; +import { MenuSubSection, MenuTopSection } from './expandable-menu-provider'; +import { AuthorizationDataServiceStub } from '../../testing/authorization-service.stub'; +import { of as observableOf } from 'rxjs'; +import { AuthorizationDataService } from '../../../core/data/feature-authorization/authorization-data.service'; +import { ImportMenuProvider } from './import.menu'; +import { ScriptDataService } from '../../../core/data/processes/script-data.service'; +import { ScriptServiceStub } from '../../testing/script-service.stub'; + +const expectedTopSection: MenuTopSection = { + model: { + type: MenuItemType.TEXT, + text: 'menu.section.import', + }, + icon: 'file-import', + shouldPersistOnRouteChange: true, +}; + +const expectedSubSections: MenuSubSection[] = [ + { + visible: true, + model: { + type: MenuItemType.LINK, + text: 'menu.section.import_metadata', + link: '/admin/metadata-import', + }, + }, + { + visible: true, + model: { + type: MenuItemType.LINK, + text: 'menu.section.import_batch', + link: '/admin/batch-import', + }, + }, +]; + +describe('ImportMenuProvider', () => { + let provider: ImportMenuProvider; + let authorizationServiceStub = new AuthorizationDataServiceStub(); + + beforeEach(() => { + spyOn(authorizationServiceStub, 'isAuthorized').and.returnValue( + observableOf(true) + ); + + TestBed.configureTestingModule({ + providers: [ + ImportMenuProvider, + { provide: AuthorizationDataService, useValue: authorizationServiceStub }, + { provide: ScriptDataService, useClass: ScriptServiceStub }, + ], + }); + provider = TestBed.inject(ImportMenuProvider); + }); + + it('should be created', () => { + expect(provider).toBeTruthy(); + }); + + it('getTopSection should return expected menu section', (done) => { + provider.getTopSection().subscribe((section) => { + expect(section).toEqual(expectedTopSection); + done(); + }); + }); + + it('getSubSections should return expected menu sections', (done) => { + provider.getSubSections().subscribe((sections) => { + expect(sections).toEqual(expectedSubSections); + done(); + }); + }); +}); diff --git a/src/app/shared/menu/providers/new.menu.spec.ts b/src/app/shared/menu/providers/new.menu.spec.ts new file mode 100644 index 0000000000..6376b5e2d3 --- /dev/null +++ b/src/app/shared/menu/providers/new.menu.spec.ts @@ -0,0 +1,100 @@ +/** + * The contents of this file are subject to the license and copyright + * detailed in the LICENSE and NOTICE files at the root of the source + * tree and available online at + * + * http://www.dspace.org/license/ + */ + +import { TestBed } from '@angular/core/testing'; +import { MenuItemType } from '../menu-item-type.model'; +import { MenuSubSection, MenuTopSection } from './expandable-menu-provider'; +import { NewMenuProvider } from './new.menu'; +import { AuthorizationDataServiceStub } from '../../testing/authorization-service.stub'; +import { of as observableOf } from 'rxjs'; +import { AuthorizationDataService } from '../../../core/data/feature-authorization/authorization-data.service'; +import { FeatureID } from '../../../core/data/feature-authorization/feature-id'; + +const expectedTopSection: MenuTopSection = { + model: { + type: MenuItemType.TEXT, + text: 'menu.section.new' + }, + icon: 'plus', + }; + +const expectedSubSections: MenuSubSection[] = [ + { + visible: true, + model: { + type: MenuItemType.ONCLICK, + text: 'menu.section.new_community', + function: jasmine.any(Function) as any, + }, + }, + { + visible: false, + model: { + type: MenuItemType.ONCLICK, + text: 'menu.section.new_collection', + function: jasmine.any(Function) as any, + }, + }, + { + visible: true, + model: { + type: MenuItemType.ONCLICK, + text: 'menu.section.new_item', + function: jasmine.any(Function) as any, + }, + }, + { + visible: true, + model: { + type: MenuItemType.LINK, + text: 'menu.section.new_process', + link: '/processes/new' + }, + }, +]; + +describe('NewMenuProvider', () => { + let provider: NewMenuProvider; + let authorizationServiceStub = new AuthorizationDataServiceStub(); + + beforeEach(() => { + spyOn(authorizationServiceStub, 'isAuthorized').and.callFake((id: FeatureID) => { + if (id === FeatureID.IsCollectionAdmin) { + return observableOf(false); + } else { + return observableOf(true); + } + }); + + TestBed.configureTestingModule({ + providers: [ + NewMenuProvider, + { provide: AuthorizationDataService, useValue: authorizationServiceStub }, + ], + }); + provider = TestBed.inject(NewMenuProvider); + }); + + it('should be created', () => { + expect(provider).toBeTruthy(); + }); + + it('getTopSection should return expected menu section', (done) => { + provider.getTopSection().subscribe((section) => { + expect(section).toEqual(expectedTopSection); + done(); + }); + }); + + it('getSubSections should return expected menu sections', (done) => { + provider.getSubSections().subscribe((sections) => { + expect(sections).toEqual(expectedSubSections); + done(); + }); + }); +}); diff --git a/src/app/shared/menu/providers/new.menu.ts b/src/app/shared/menu/providers/new.menu.ts index 93786b7d02..db270d9d18 100644 --- a/src/app/shared/menu/providers/new.menu.ts +++ b/src/app/shared/menu/providers/new.menu.ts @@ -57,7 +57,7 @@ export class NewMenuProvider extends AbstractExpandableMenuProvider { ]).pipe(map(([isCollectionAdmin, isCommunityAdmin, isSiteAdmin, canSubmit]) => { return [ { - visible: isCollectionAdmin, + visible: isCommunityAdmin, model: { type: MenuItemType.ONCLICK, text: 'menu.section.new_community', @@ -67,7 +67,7 @@ export class NewMenuProvider extends AbstractExpandableMenuProvider { }, }, { - visible: isCommunityAdmin, + visible: isCollectionAdmin, model: { type: MenuItemType.ONCLICK, text: 'menu.section.new_collection', diff --git a/src/app/shared/menu/providers/processes.menu.spec.ts b/src/app/shared/menu/providers/processes.menu.spec.ts new file mode 100644 index 0000000000..78ff544a58 --- /dev/null +++ b/src/app/shared/menu/providers/processes.menu.spec.ts @@ -0,0 +1,57 @@ +/** + * The contents of this file are subject to the license and copyright + * detailed in the LICENSE and NOTICE files at the root of the source + * tree and available online at + * + * http://www.dspace.org/license/ + */ + +import { TestBed } from '@angular/core/testing'; +import { PartialMenuSection } from '../menu-provider'; +import { MenuItemType } from '../menu-item-type.model'; +import { AuthorizationDataServiceStub } from '../../testing/authorization-service.stub'; +import { of as observableOf } from 'rxjs'; +import { AuthorizationDataService } from '../../../core/data/feature-authorization/authorization-data.service'; +import { ProcessesMenuProvider } from './processes.menu'; + +const expectedSections: PartialMenuSection[] = [ + { + visible: true, + model: { + type: MenuItemType.LINK, + text: 'menu.section.processes', + link: '/processes', + }, + icon: 'terminal', + }, +]; + +describe('ProcessesMenuProvider', () => { + let provider: ProcessesMenuProvider; + let authorizationServiceStub = new AuthorizationDataServiceStub(); + + beforeEach(() => { + spyOn(authorizationServiceStub, 'isAuthorized').and.returnValue( + observableOf(true) + ); + + TestBed.configureTestingModule({ + providers: [ + ProcessesMenuProvider, + { provide: AuthorizationDataService, useValue: authorizationServiceStub }, + ], + }); + provider = TestBed.inject(ProcessesMenuProvider); + }); + + it('should be created', () => { + expect(provider).toBeTruthy(); + }); + + it('getSections should return expected menu sections', (done) => { + provider.getSections().subscribe((sections) => { + expect(sections).toEqual(expectedSections); + done(); + }); + }); +}); diff --git a/src/app/shared/menu/providers/registries.menu.spec.ts b/src/app/shared/menu/providers/registries.menu.spec.ts new file mode 100644 index 0000000000..b1aa981f7f --- /dev/null +++ b/src/app/shared/menu/providers/registries.menu.spec.ts @@ -0,0 +1,82 @@ +/** + * The contents of this file are subject to the license and copyright + * detailed in the LICENSE and NOTICE files at the root of the source + * tree and available online at + * + * http://www.dspace.org/license/ + */ + +import { TestBed } from '@angular/core/testing'; +import { MenuItemType } from '../menu-item-type.model'; +import { MenuSubSection, MenuTopSection } from './expandable-menu-provider'; +import { AuthorizationDataServiceStub } from '../../testing/authorization-service.stub'; +import { of as observableOf } from 'rxjs'; +import { AuthorizationDataService } from '../../../core/data/feature-authorization/authorization-data.service'; +import { ScriptDataService } from '../../../core/data/processes/script-data.service'; +import { ScriptServiceStub } from '../../testing/script-service.stub'; +import { RegistriesMenuProvider } from './registries.menu'; + +const expectedTopSection: MenuTopSection = { + model: { + type: MenuItemType.TEXT, + text: 'menu.section.registries', + }, + icon: 'list', +}; + +const expectedSubSections: MenuSubSection[] = [ + { + visible: true, + model: { + type: MenuItemType.LINK, + text: 'menu.section.registries_metadata', + link: 'admin/registries/metadata', + }, + }, + { + visible: true, + model: { + type: MenuItemType.LINK, + text: 'menu.section.registries_format', + link: 'admin/registries/bitstream-formats', + }, + }, +]; + +describe('RegistriesMenuProvider', () => { + let provider: RegistriesMenuProvider; + let authorizationServiceStub = new AuthorizationDataServiceStub(); + + beforeEach(() => { + spyOn(authorizationServiceStub, 'isAuthorized').and.returnValue( + observableOf(true) + ); + + TestBed.configureTestingModule({ + providers: [ + RegistriesMenuProvider, + { provide: AuthorizationDataService, useValue: authorizationServiceStub }, + { provide: ScriptDataService, useClass: ScriptServiceStub }, + ], + }); + provider = TestBed.inject(RegistriesMenuProvider); + }); + + it('should be created', () => { + expect(provider).toBeTruthy(); + }); + + it('getTopSection should return expected menu section', (done) => { + provider.getTopSection().subscribe((section) => { + expect(section).toEqual(expectedTopSection); + done(); + }); + }); + + it('getSubSections should return expected menu sections', (done) => { + provider.getSubSections().subscribe((sections) => { + expect(sections).toEqual(expectedSubSections); + done(); + }); + }); +}); diff --git a/src/app/shared/menu/providers/system-wide-alert.menu.spec.ts b/src/app/shared/menu/providers/system-wide-alert.menu.spec.ts new file mode 100644 index 0000000000..df5e126814 --- /dev/null +++ b/src/app/shared/menu/providers/system-wide-alert.menu.spec.ts @@ -0,0 +1,57 @@ +/** + * The contents of this file are subject to the license and copyright + * detailed in the LICENSE and NOTICE files at the root of the source + * tree and available online at + * + * http://www.dspace.org/license/ + */ + +import { TestBed } from '@angular/core/testing'; +import { PartialMenuSection } from '../menu-provider'; +import { MenuItemType } from '../menu-item-type.model'; +import { AuthorizationDataServiceStub } from '../../testing/authorization-service.stub'; +import { of as observableOf } from 'rxjs'; +import { AuthorizationDataService } from '../../../core/data/feature-authorization/authorization-data.service'; +import { SystemWideAlertMenuProvider } from './system-wide-alert.menu'; + +const expectedSections: PartialMenuSection[] = [ + { + visible: true, + model: { + type: MenuItemType.LINK, + text: 'menu.section.system-wide-alert', + link: '/admin/system-wide-alert', + }, + icon: 'exclamation-circle', + }, +]; + +describe('SystemWideAlertMenuProvider', () => { + let provider: SystemWideAlertMenuProvider; + let authorizationServiceStub = new AuthorizationDataServiceStub(); + + beforeEach(() => { + spyOn(authorizationServiceStub, 'isAuthorized').and.returnValue( + observableOf(true) + ); + + TestBed.configureTestingModule({ + providers: [ + SystemWideAlertMenuProvider, + { provide: AuthorizationDataService, useValue: authorizationServiceStub }, + ], + }); + provider = TestBed.inject(SystemWideAlertMenuProvider); + }); + + it('should be created', () => { + expect(provider).toBeTruthy(); + }); + + it('getSections should return expected menu sections', (done) => { + provider.getSections().subscribe((sections) => { + expect(sections).toEqual(expectedSections); + done(); + }); + }); +}); diff --git a/src/app/shared/menu/providers/workflow.menu.spec.ts b/src/app/shared/menu/providers/workflow.menu.spec.ts new file mode 100644 index 0000000000..2886d0dbf3 --- /dev/null +++ b/src/app/shared/menu/providers/workflow.menu.spec.ts @@ -0,0 +1,57 @@ +/** + * The contents of this file are subject to the license and copyright + * detailed in the LICENSE and NOTICE files at the root of the source + * tree and available online at + * + * http://www.dspace.org/license/ + */ + +import { TestBed } from '@angular/core/testing'; +import { PartialMenuSection } from '../menu-provider'; +import { MenuItemType } from '../menu-item-type.model'; +import { AuthorizationDataServiceStub } from '../../testing/authorization-service.stub'; +import { of as observableOf } from 'rxjs'; +import { AuthorizationDataService } from '../../../core/data/feature-authorization/authorization-data.service'; +import { WorkflowMenuProvider } from './workflow.menu'; + +const expectedSections: PartialMenuSection[] = [ + { + visible: true, + model: { + type: MenuItemType.LINK, + text: 'menu.section.workflow', + link: '/admin/workflow', + }, + icon: 'user-check', + }, +]; + +describe('WorkflowMenuProvider', () => { + let provider: WorkflowMenuProvider; + let authorizationServiceStub = new AuthorizationDataServiceStub(); + + beforeEach(() => { + spyOn(authorizationServiceStub, 'isAuthorized').and.returnValue( + observableOf(true) + ); + + TestBed.configureTestingModule({ + providers: [ + WorkflowMenuProvider, + { provide: AuthorizationDataService, useValue: authorizationServiceStub }, + ], + }); + provider = TestBed.inject(WorkflowMenuProvider); + }); + + it('should be created', () => { + expect(provider).toBeTruthy(); + }); + + it('getSections should return expected menu sections', (done) => { + provider.getSections().subscribe((sections) => { + expect(sections).toEqual(expectedSections); + done(); + }); + }); +}); diff --git a/src/app/shared/testing/browse-service.stub.ts b/src/app/shared/testing/browse-service.stub.ts new file mode 100644 index 0000000000..a60ddb679d --- /dev/null +++ b/src/app/shared/testing/browse-service.stub.ts @@ -0,0 +1,22 @@ +/** + * The contents of this file are subject to the license and copyright + * detailed in the LICENSE and NOTICE files at the root of the source + * tree and available online at + * + * http://www.dspace.org/license/ + */ +import { createSuccessfulRemoteDataObject$ } from '../remote-data.utils'; +import { createPaginatedList } from './utils.test'; +import { Observable } from 'rxjs'; +import { RemoteData } from '../../core/data/remote-data'; +import { PaginatedList } from '../../core/data/paginated-list.model'; +import { BrowseDefinition } from '../../core/shared/browse-definition.model'; + +/** + * Stub class of {@link BrowseService}. + */ +export class BrowseServiceStub { + getBrowseDefinitions(): Observable>> { + return createSuccessfulRemoteDataObject$(createPaginatedList([])); + } +} diff --git a/src/app/shared/testing/script-service.stub.ts b/src/app/shared/testing/script-service.stub.ts new file mode 100644 index 0000000000..133f7185f4 --- /dev/null +++ b/src/app/shared/testing/script-service.stub.ts @@ -0,0 +1,18 @@ +/** + * The contents of this file are subject to the license and copyright + * detailed in the LICENSE and NOTICE files at the root of the source + * tree and available online at + * + * http://www.dspace.org/license/ + */ + +import { Observable, of as observableOf } from 'rxjs'; + +/** + * Stub class of {@link ScriptDataService}. + */ +export class ScriptServiceStub { + scriptWithNameExistsAndCanExecute(scriptName: string): Observable { + return observableOf(true); + } +} From 83dc0696734d7250051f22837eb8ddd52343d11c Mon Sep 17 00:00:00 2001 From: Yana De Pauw Date: Wed, 11 Sep 2024 11:38:02 +0200 Subject: [PATCH 2/2] Make tests compile --- src/app/app-routing.module.ts | 2 -- src/app/community-page/community-page-routing.module.ts | 1 - src/app/home-page/home-page-routing.module.ts | 3 --- .../dso-edit-menu-section.component.spec.ts | 8 ++++---- .../dso-edit-menu/dso-edit-menu.component.spec.ts | 5 +++-- .../menu/menu-section/menu-section.component.spec.ts | 1 - src/app/shared/menu/menu.component.spec.ts | 3 +-- 7 files changed, 8 insertions(+), 15 deletions(-) diff --git a/src/app/app-routing.module.ts b/src/app/app-routing.module.ts index 568cfb0244..f14ba3aed6 100644 --- a/src/app/app-routing.module.ts +++ b/src/app/app-routing.module.ts @@ -32,12 +32,10 @@ import { ReloadGuard } from './core/reload/reload.guard'; import { ServerCheckGuard } from './core/server-check/server-check.guard'; import { ThemedForbiddenComponent } from './forbidden/themed-forbidden.component'; import { ITEM_MODULE_PATH } from './item-page/item-page-routing-paths'; -import { MenuResolver } from './menu.resolver'; import { ThemedPageErrorComponent } from './page-error/themed-page-error.component'; import { ThemedPageInternalServerErrorComponent } from './page-internal-server-error/themed-page-internal-server-error.component'; import { ThemedPageNotFoundComponent } from './pagenotfound/themed-pagenotfound.component'; import { PROCESS_MODULE_PATH } from './process-page/process-page-routing.paths'; -import { MenuProviderService } from './shared/menu/menu-provider.service'; import { resolveStaticMenus } from './shared/menu/menu.resolver'; @NgModule({ diff --git a/src/app/community-page/community-page-routing.module.ts b/src/app/community-page/community-page-routing.module.ts index 493908ce0c..6b71940e2f 100644 --- a/src/app/community-page/community-page-routing.module.ts +++ b/src/app/community-page/community-page-routing.module.ts @@ -4,7 +4,6 @@ import { AuthenticatedGuard } from '../core/auth/authenticated.guard'; import { CommunityBreadcrumbResolver } from '../core/breadcrumbs/community-breadcrumb.resolver'; import { DSOBreadcrumbsService } from '../core/breadcrumbs/dso-breadcrumbs.service'; import { LinkService } from '../core/cache/builders/link.service'; -import { DSOEditMenuResolver } from '../shared/dso-page/dso-edit-menu.resolver'; import { resolveRouteMenus } from '../shared/menu/menu.resolver'; import { SubscribeMenuProvider } from '../shared/menu/providers/comcol-subscribe.menu'; import { DSpaceObjectEditMenuProvider } from '../shared/menu/providers/dso-edit.menu'; diff --git a/src/app/home-page/home-page-routing.module.ts b/src/app/home-page/home-page-routing.module.ts index 92aa86b3da..27721a18f9 100644 --- a/src/app/home-page/home-page-routing.module.ts +++ b/src/app/home-page/home-page-routing.module.ts @@ -1,13 +1,10 @@ import { NgModule } from '@angular/core'; import { RouterModule } from '@angular/router'; -import { MenuProviderService } from '../shared/menu/menu-provider.service'; import { resolveRouteMenus } from '../shared/menu/menu.resolver'; import { StatisticsMenuProvider } from '../shared/menu/providers/statistics.menu'; import { HomePageResolver } from './home-page.resolver'; -import { LinkMenuItemModel } from '../shared/menu/menu-item/models/link.model'; import { ThemedHomePageComponent } from './themed-home-page.component'; -import { MenuItemType } from '../shared/menu/menu-item-type.model'; @NgModule({ imports: [ 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 f0815c5415..bfd881aea2 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 @@ -127,17 +127,17 @@ describe('DsoEditMenuSectionComponent', () => { stopPropagation: jasmine.createSpy('stopPropagation'), }); it('should call the item model function when not disabled', () => { - spyOn(component.section.model as OnClickMenuItemModel, 'function'); + spyOn((component as any).section.model as OnClickMenuItemModel, 'function'); component.activate(mockEvent); - expect((component.section.model as OnClickMenuItemModel).function).toHaveBeenCalled(); + expect(((component as any).section.model as OnClickMenuItemModel).function).toHaveBeenCalled(); }); it('should call not the item model function when disabled', () => { - spyOn(component.section.model as OnClickMenuItemModel, 'function'); + spyOn((component as any).section.model as OnClickMenuItemModel, 'function'); component.itemModel.disabled = true; component.activate(mockEvent); - expect((component.section.model as OnClickMenuItemModel).function).not.toHaveBeenCalled(); + expect(((component as any).section.model as OnClickMenuItemModel).function).not.toHaveBeenCalled(); component.itemModel.disabled = false; }); }); diff --git a/src/app/shared/dso-page/dso-edit-menu/dso-edit-menu.component.spec.ts b/src/app/shared/dso-page/dso-edit-menu/dso-edit-menu.component.spec.ts index 5616e8ea10..2aaf5a6b03 100644 --- a/src/app/shared/dso-page/dso-edit-menu/dso-edit-menu.component.spec.ts +++ b/src/app/shared/dso-page/dso-edit-menu/dso-edit-menu.component.spec.ts @@ -10,12 +10,12 @@ import { AuthorizationDataService } from '../../../core/data/feature-authorizati import { AuthService } from '../../../core/auth/auth.service'; import { AuthServiceStub } from '../../testing/auth-service.stub'; import { MenuService } from '../../menu/menu.service'; -import { MenuItemModel } from '../../menu/menu-item/models/menu-item.model'; import { ThemeService } from '../../theme-support/theme.service'; import { getMockThemeService } from '../../mocks/theme-service.mock'; import { DsoPageModule } from '../dso-page.module'; +import { TextMenuItemModel } from '../../menu/menu-item/models/text.model'; describe('DsoEditMenuComponent', () => { let comp: DsoEditMenuComponent; @@ -34,7 +34,8 @@ describe('DsoEditMenuComponent', () => { model: { type: null, disabled: false, - } as MenuItemModel, + text: 'dummy-text' + } as TextMenuItemModel, icon: 'pencil-alt', index: 1 }; diff --git a/src/app/shared/menu/menu-section/menu-section.component.spec.ts b/src/app/shared/menu/menu-section/menu-section.component.spec.ts index 8949c6c1b0..9f2deae0e9 100644 --- a/src/app/shared/menu/menu-section/menu-section.component.spec.ts +++ b/src/app/shared/menu/menu-section/menu-section.component.spec.ts @@ -1,6 +1,5 @@ import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; import { NoopAnimationsModule } from '@angular/platform-browser/animations'; -import { Router } from '@angular/router'; import { TranslateModule } from '@ngx-translate/core'; import { ChangeDetectionStrategy, diff --git a/src/app/shared/menu/menu.component.spec.ts b/src/app/shared/menu/menu.component.spec.ts index f0660fab4a..f7cf0c9528 100644 --- a/src/app/shared/menu/menu.component.spec.ts +++ b/src/app/shared/menu/menu.component.spec.ts @@ -8,7 +8,6 @@ import { MenuServiceStub } from '../testing/menu-service.stub'; import { of as observableOf } from 'rxjs'; import { Router, ActivatedRoute } from '@angular/router'; import { RouterTestingModule } from '@angular/router/testing'; -import { MenuSection } from './menu-section.model'; import { MenuID } from './menu-id.model'; import { Item } from '../../core/shared/item.model'; import { AuthorizationDataService } from '../../core/data/feature-authorization/authorization-data.service'; @@ -76,7 +75,7 @@ describe('MenuComponent', () => { comp.menuID = mockMenuID; menuService = (comp as any).menuService; router = TestBed.inject(Router); - spyOn(comp as any, 'getSectionDataInjector').and.returnValue(MenuSection); + // spyOn(comp as any, 'getSectionDataInjector').and.returnValue(MenuSection); spyOn(comp as any, 'getSectionComponent').and.returnValue(observableOf({})); fixture.detectChanges(); });