Files
dspace-angular/src/app/menu.resolver.spec.ts
2022-09-27 20:19:50 +05:30

338 lines
13 KiB
TypeScript

import { TestBed, waitForAsync } from '@angular/core/testing';
import { MenuResolver } from './menu.resolver';
import { of as observableOf } from 'rxjs';
import { FeatureID } from './core/data/feature-authorization/feature-id';
import { TranslateModule } from '@ngx-translate/core';
import { NoopAnimationsModule } from '@angular/platform-browser/animations';
import { RouterTestingModule } from '@angular/router/testing';
import { AdminSidebarComponent } from './admin/admin-sidebar/admin-sidebar.component';
import { NO_ERRORS_SCHEMA } from '@angular/core';
import { MenuService } from './shared/menu/menu.service';
import { AuthorizationDataService } from './core/data/feature-authorization/authorization-data.service';
import { ScriptDataService } from './core/data/processes/script-data.service';
import { NgbModal } from '@ng-bootstrap/ng-bootstrap';
import { MenuServiceStub } from './shared/testing/menu-service.stub';
import { MenuID } from './shared/menu/menu-id.model';
import { BrowseService } from './core/browse/browse.service';
import { cold } from 'jasmine-marbles';
import createSpy = jasmine.createSpy;
import { createSuccessfulRemoteDataObject$ } from './shared/remote-data.utils';
import { createPaginatedList } from './shared/testing/utils.test';
const BOOLEAN = { t: true, f: false };
const MENU_STATE = {
id: 'some menu'
};
const BROWSE_DEFINITIONS = [
{ id: 'definition1' },
{ id: 'definition2' },
{ id: 'definition3' },
];
describe('MenuResolver', () => {
let resolver: MenuResolver;
let menuService;
let browseService;
let authorizationService;
let scriptService;
beforeEach(waitForAsync(() => {
menuService = new MenuServiceStub();
spyOn(menuService, 'getMenu').and.returnValue(observableOf(MENU_STATE));
browseService = jasmine.createSpyObj('browseService', {
getBrowseDefinitions: createSuccessfulRemoteDataObject$(createPaginatedList(BROWSE_DEFINITIONS))
});
authorizationService = jasmine.createSpyObj('authorizationService', {
isAuthorized: observableOf(true)
});
scriptService = jasmine.createSpyObj('scriptService', {
scriptWithNameExistsAndCanExecute: observableOf(true)
});
TestBed.configureTestingModule({
imports: [TranslateModule.forRoot(), NoopAnimationsModule, RouterTestingModule],
declarations: [AdminSidebarComponent],
providers: [
{ provide: MenuService, useValue: menuService },
{ provide: BrowseService, useValue: browseService },
{ provide: AuthorizationDataService, useValue: authorizationService },
{ provide: ScriptDataService, useValue: scriptService },
{
provide: NgbModal, useValue: {
open: () => {/*comment*/
}
}
}
],
schemas: [NO_ERRORS_SCHEMA]
});
resolver = TestBed.inject(MenuResolver);
spyOn(menuService, 'addSection');
}));
it('should be created', () => {
expect(resolver).toBeTruthy();
});
describe('resolve', () => {
it('should create all menus', (done) => {
spyOn(resolver, 'createPublicMenu$').and.returnValue(observableOf(true));
spyOn(resolver, 'createAdminMenu$').and.returnValue(observableOf(true));
resolver.resolve(null, null).subscribe(resolved => {
expect(resolved).toBeTrue();
expect(resolver.createPublicMenu$).toHaveBeenCalled();
expect(resolver.createAdminMenu$).toHaveBeenCalled();
done();
});
});
it('should return an Observable that emits true as soon as all menus are created', () => {
spyOn(resolver, 'createPublicMenu$').and.returnValue(cold('--(t|)', BOOLEAN));
spyOn(resolver, 'createAdminMenu$').and.returnValue(cold('----(t|)', BOOLEAN));
expect(resolver.resolve(null, null)).toBeObservable(cold('----(t|)', BOOLEAN));
});
});
describe('createPublicMenu$', () => {
it('should retrieve the menu by ID return an Observable that emits true as soon as it is created', () => {
(menuService as any).getMenu.and.returnValue(cold('--u--m--', {
u: undefined,
m: MENU_STATE,
}));
expect(resolver.createPublicMenu$()).toBeObservable(cold('-----(t|)', BOOLEAN));
expect(menuService.getMenu).toHaveBeenCalledOnceWith(MenuID.PUBLIC);
});
describe('contents', () => {
beforeEach((done) => {
resolver.createPublicMenu$().subscribe((_) => {
done();
});
});
it('should include community list link', () => {
expect(menuService.addSection).toHaveBeenCalledWith(MenuID.PUBLIC, jasmine.objectContaining({
id: 'browse_global_communities_and_collections', visible: true,
}));
});
it('should include browse dropdown', () => {
expect(menuService.addSection).toHaveBeenCalledWith(MenuID.PUBLIC, jasmine.objectContaining({
id: 'browse_global_by_definition1', parentID: 'browse_global', visible: true,
}));
expect(menuService.addSection).toHaveBeenCalledWith(MenuID.PUBLIC, jasmine.objectContaining({
id: 'browse_global_by_definition2', parentID: 'browse_global', visible: true,
}));
expect(menuService.addSection).toHaveBeenCalledWith(MenuID.PUBLIC, jasmine.objectContaining({
id: 'browse_global_by_definition3', parentID: 'browse_global', visible: true,
}));
expect(menuService.addSection).toHaveBeenCalledWith(MenuID.PUBLIC, jasmine.objectContaining({
id: 'browse_global', visible: true,
}));
});
});
});
describe('createAdminMenu$', () => {
it('should retrieve the menu by ID return an Observable that emits true as soon as it is created', () => {
(menuService as any).getMenu.and.returnValue(cold('--u--m', {
u: undefined,
m: MENU_STATE,
}));
expect(resolver.createAdminMenu$()).toBeObservable(cold('-----(t|)', BOOLEAN));
expect(menuService.getMenu).toHaveBeenCalledOnceWith(MenuID.ADMIN);
});
describe('for regular user', () => {
beforeEach(() => {
authorizationService.isAuthorized = createSpy('isAuthorized').and.callFake(() => {
return observableOf(false);
});
});
beforeEach((done) => {
resolver.createAdminMenu$().subscribe((_) => {
done();
});
});
it('should not show site admin section', () => {
expect(menuService.addSection).toHaveBeenCalledWith(MenuID.ADMIN, jasmine.objectContaining({
id: 'admin_search', visible: false,
}));
expect(menuService.addSection).toHaveBeenCalledWith(MenuID.ADMIN, jasmine.objectContaining({
id: 'registries', visible: false,
}));
expect(menuService.addSection).toHaveBeenCalledWith(MenuID.ADMIN, jasmine.objectContaining({
parentID: 'registries', visible: false,
}));
expect(menuService.addSection).toHaveBeenCalledWith(MenuID.ADMIN, jasmine.objectContaining({
id: 'curation_tasks', visible: false,
}));
expect(menuService.addSection).toHaveBeenCalledWith(MenuID.ADMIN, jasmine.objectContaining({
id: 'workflow', visible: false,
}));
});
it('should not show edit_community', () => {
expect(menuService.addSection).toHaveBeenCalledWith(MenuID.ADMIN, jasmine.objectContaining({
id: 'edit_community', visible: false,
}));
});
it('should not show edit_collection', () => {
expect(menuService.addSection).toHaveBeenCalledWith(MenuID.ADMIN, jasmine.objectContaining({
id: 'edit_collection', visible: false,
}));
});
it('should not show access control section', () => {
expect(menuService.addSection).toHaveBeenCalledWith(MenuID.ADMIN, jasmine.objectContaining({
id: 'access_control', visible: false,
}));
expect(menuService.addSection).toHaveBeenCalledWith(MenuID.ADMIN, jasmine.objectContaining({
parentID: 'access_control', visible: false,
}));
});
// We check that the menu section has not been called with visible set to true
// The reason why we don't check if it has been called with visible set to false
// Is because the function does not get called unless a user is authorised
it('should not show the import section', () => {
expect(menuService.addSection).not.toHaveBeenCalledWith(MenuID.ADMIN, jasmine.objectContaining({
id: 'import', visible: true,
}));
});
// We check that the menu section has not been called with visible set to true
// The reason why we don't check if it has been called with visible set to false
// Is because the function does not get called unless a user is authorised
it('should not show the export section', () => {
expect(menuService.addSection).not.toHaveBeenCalledWith(MenuID.ADMIN, jasmine.objectContaining({
id: 'export', visible: true,
}));
});
});
describe('for site admin', () => {
beforeEach(() => {
authorizationService.isAuthorized = createSpy('isAuthorized').and.callFake((featureID: FeatureID) => {
return observableOf(featureID === FeatureID.AdministratorOf);
});
});
beforeEach((done) => {
resolver.createAdminMenu$().subscribe((_) => {
done();
});
});
it('should contain site admin section', () => {
expect(menuService.addSection).toHaveBeenCalledWith(MenuID.ADMIN, jasmine.objectContaining({
id: 'admin_search', visible: true,
}));
expect(menuService.addSection).toHaveBeenCalledWith(MenuID.ADMIN, jasmine.objectContaining({
id: 'registries', visible: true,
}));
expect(menuService.addSection).toHaveBeenCalledWith(MenuID.ADMIN, jasmine.objectContaining({
parentID: 'registries', visible: true,
}));
expect(menuService.addSection).toHaveBeenCalledWith(MenuID.ADMIN, jasmine.objectContaining({
id: 'curation_tasks', visible: true,
}));
expect(menuService.addSection).toHaveBeenCalledWith(MenuID.ADMIN, jasmine.objectContaining({
id: 'workflow', visible: true,
}));
expect(menuService.addSection).toHaveBeenCalledWith(MenuID.ADMIN, jasmine.objectContaining({
id: 'workflow', visible: true,
}));
expect(menuService.addSection).toHaveBeenCalledWith(MenuID.ADMIN, jasmine.objectContaining({
id: 'import', visible: true,
}));
expect(menuService.addSection).toHaveBeenCalledWith(MenuID.ADMIN, jasmine.objectContaining({
id: 'import_batch', parentID: 'import', visible: true,
}));
expect(menuService.addSection).toHaveBeenCalledWith(MenuID.ADMIN, jasmine.objectContaining({
id: 'export', visible: true,
}));
expect(menuService.addSection).toHaveBeenCalledWith(MenuID.ADMIN, jasmine.objectContaining({
id: 'export_batch', parentID: 'export', visible: true,
}));
});
});
describe('for community admin', () => {
beforeEach(() => {
authorizationService.isAuthorized = createSpy('isAuthorized').and.callFake((featureID: FeatureID) => {
return observableOf(featureID === FeatureID.IsCommunityAdmin);
});
});
beforeEach((done) => {
resolver.createAdminMenu$().subscribe((_) => {
done();
});
});
it('should show edit_community', () => {
expect(menuService.addSection).toHaveBeenCalledWith(MenuID.ADMIN, jasmine.objectContaining({
id: 'edit_community', visible: true,
}));
});
});
describe('for collection admin', () => {
beforeEach(() => {
authorizationService.isAuthorized = createSpy('isAuthorized').and.callFake((featureID: FeatureID) => {
return observableOf(featureID === FeatureID.IsCollectionAdmin);
});
});
beforeEach((done) => {
resolver.createAdminMenu$().subscribe((_) => {
done();
});
});
it('should show edit_collection', () => {
expect(menuService.addSection).toHaveBeenCalledWith(MenuID.ADMIN, jasmine.objectContaining({
id: 'edit_collection', visible: true,
}));
});
});
describe('for group admin', () => {
beforeEach(() => {
authorizationService.isAuthorized = createSpy('isAuthorized').and.callFake((featureID: FeatureID) => {
return observableOf(featureID === FeatureID.CanManageGroups);
});
});
beforeEach((done) => {
resolver.createAdminMenu$().subscribe((_) => {
done();
});
});
it('should show access control section', () => {
expect(menuService.addSection).toHaveBeenCalledWith(MenuID.ADMIN, jasmine.objectContaining({
id: 'access_control', visible: true,
}));
expect(menuService.addSection).toHaveBeenCalledWith(MenuID.ADMIN, jasmine.objectContaining({
parentID: 'access_control', visible: true,
}));
});
});
});
});