mirror of
https://github.com/DSpace/dspace-angular.git
synced 2025-10-14 21:43:04 +00:00
71429: Feature and Authorization tests
This commit is contained in:
@@ -33,6 +33,9 @@ import { NotificationsServiceStub } from '../../../../shared/testing/notificatio
|
||||
import { TranslateLoaderMock } from '../../../../shared/mocks/translate-loader.mock';
|
||||
import { AuthService } from '../../../../core/auth/auth.service';
|
||||
import { AuthServiceStub } from '../../../../shared/testing/auth-service.stub';
|
||||
import { AuthorizationDataService } from '../../../../core/data/feature-authorization/authorization-data.service';
|
||||
import { GroupDataService } from '../../../../core/eperson/group-data.service';
|
||||
import { createPaginatedList } from '../../../../shared/testing/utils.test';
|
||||
|
||||
describe('EPersonFormComponent', () => {
|
||||
let component: EPersonFormComponent;
|
||||
@@ -43,6 +46,8 @@ describe('EPersonFormComponent', () => {
|
||||
let mockEPeople;
|
||||
let ePersonDataServiceStub: any;
|
||||
let authService: AuthServiceStub;
|
||||
let authorizationService: AuthorizationDataService;
|
||||
let groupsDataService: GroupDataService;
|
||||
|
||||
beforeEach(async(() => {
|
||||
mockEPeople = [EPersonMock, EPersonMock2];
|
||||
@@ -108,6 +113,13 @@ describe('EPersonFormComponent', () => {
|
||||
builderService = getMockFormBuilderService();
|
||||
translateService = getMockTranslateService();
|
||||
authService = new AuthServiceStub();
|
||||
authorizationService = jasmine.createSpyObj('authorizationService', {
|
||||
isAuthenticated: observableOf(true)
|
||||
});
|
||||
groupsDataService = jasmine.createSpyObj('groupsDataService', {
|
||||
findAllByHref: createSuccessfulRemoteDataObject$(createPaginatedList([])),
|
||||
getGroupRegistryRouterLink: ''
|
||||
});
|
||||
TestBed.configureTestingModule({
|
||||
imports: [CommonModule, NgbModule, FormsModule, ReactiveFormsModule, BrowserModule,
|
||||
TranslateModule.forRoot({
|
||||
@@ -130,6 +142,8 @@ describe('EPersonFormComponent', () => {
|
||||
{ provide: RemoteDataBuildService, useValue: {} },
|
||||
{ provide: HALEndpointService, useValue: {} },
|
||||
{ provide: AuthService, useValue: authService },
|
||||
{ provide: AuthorizationDataService, useValue: authorizationService },
|
||||
{ provide: GroupDataService, useValue: groupsDataService },
|
||||
EPeopleRegistryComponent
|
||||
],
|
||||
schemas: [NO_ERRORS_SCHEMA]
|
||||
|
@@ -245,7 +245,7 @@ export class EPersonFormComponent implements OnInit, OnDestroy {
|
||||
});
|
||||
}));
|
||||
this.canImpersonate$ = this.epersonService.getActiveEPerson().pipe(
|
||||
switchMap((eperson) => this.authorizationService.isAuthenticated(FeatureType.LoginOnBehalfOf, eperson.self))
|
||||
switchMap((eperson) => this.authorizationService.isAuthenticated(FeatureType.LoginOnBehalfOf, hasValue(eperson) ? eperson.self : undefined))
|
||||
);
|
||||
});
|
||||
}
|
||||
|
@@ -15,13 +15,18 @@ import { By } from '@angular/platform-browser';
|
||||
import { NgbModal } from '@ng-bootstrap/ng-bootstrap';
|
||||
import { RouterTestingModule } from '@angular/router/testing';
|
||||
import { ActivatedRoute } from '@angular/router';
|
||||
import { AuthorizationDataService } from '../../core/data/feature-authorization/authorization-data.service';
|
||||
|
||||
describe('AdminSidebarComponent', () => {
|
||||
let comp: AdminSidebarComponent;
|
||||
let fixture: ComponentFixture<AdminSidebarComponent>;
|
||||
const menuService = new MenuServiceStub();
|
||||
let authorizationService: AuthorizationDataService;
|
||||
|
||||
beforeEach(async(() => {
|
||||
authorizationService = jasmine.createSpyObj('authorizationService', {
|
||||
isAuthenticated: observableOf(true)
|
||||
});
|
||||
TestBed.configureTestingModule({
|
||||
imports: [TranslateModule.forRoot(), NoopAnimationsModule, RouterTestingModule],
|
||||
declarations: [AdminSidebarComponent],
|
||||
@@ -31,6 +36,7 @@ describe('AdminSidebarComponent', () => {
|
||||
{ provide: CSSVariableService, useClass: CSSVariableServiceStub },
|
||||
{ provide: AuthService, useClass: AuthServiceStub },
|
||||
{ provide: ActivatedRoute, useValue: {} },
|
||||
{ provide: AuthorizationDataService, useValue: authorizationService },
|
||||
{
|
||||
provide: NgbModal, useValue: {
|
||||
open: () => {/*comment*/}
|
||||
|
@@ -0,0 +1,162 @@
|
||||
import { AuthorizationDataService } from './authorization-data.service';
|
||||
import { SiteDataService } from '../site-data.service';
|
||||
import { AuthService } from '../../auth/auth.service';
|
||||
import { Site } from '../../shared/site.model';
|
||||
import { EPerson } from '../../eperson/models/eperson.model';
|
||||
import { of as observableOf } from 'rxjs';
|
||||
import { FindListOptions } from '../request.models';
|
||||
import { FeatureType } from './feature-type';
|
||||
import { hasValue } from '../../../shared/empty.util';
|
||||
import { RequestParam } from '../../cache/models/request-param.model';
|
||||
import { Authorization } from '../../shared/authorization.model';
|
||||
import { RemoteData } from '../remote-data';
|
||||
import { createSuccessfulRemoteDataObject$ } from '../../../shared/remote-data.utils';
|
||||
import { createPaginatedList } from '../../../shared/testing/utils.test';
|
||||
|
||||
describe('AuthorizationDataService', () => {
|
||||
let service: AuthorizationDataService;
|
||||
let siteService: SiteDataService;
|
||||
let authService: AuthService;
|
||||
|
||||
let site: Site;
|
||||
let ePerson: EPerson;
|
||||
|
||||
function init() {
|
||||
site = Object.assign(new Site(), {
|
||||
id: 'test-site',
|
||||
_links: {
|
||||
self: { href: 'test-site-href' }
|
||||
}
|
||||
});
|
||||
ePerson = Object.assign(new EPerson(), {
|
||||
id: 'test-eperson',
|
||||
uuid: 'test-eperson'
|
||||
});
|
||||
siteService = jasmine.createSpyObj('siteService', {
|
||||
find: observableOf(site)
|
||||
});
|
||||
authService = {
|
||||
isAuthenticated: () => observableOf(true),
|
||||
getAuthenticatedUserFromStore: () => observableOf(ePerson)
|
||||
} as AuthService;
|
||||
service = new AuthorizationDataService(undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, authService, siteService);
|
||||
}
|
||||
|
||||
beforeEach(() => {
|
||||
init();
|
||||
spyOn(service, 'searchBy').and.returnValue(observableOf(undefined));
|
||||
});
|
||||
|
||||
describe('searchByObject', () => {
|
||||
const objectUrl = 'fake-object-url';
|
||||
const ePersonUuid = 'fake-eperson-uuid';
|
||||
|
||||
function createExpected(objectUrl: string, ePersonUuid?: string, featureId?: FeatureType): FindListOptions {
|
||||
const searchParams = [new RequestParam('uri', objectUrl)];
|
||||
if (hasValue(featureId)) {
|
||||
searchParams.push(new RequestParam('feature', featureId));
|
||||
}
|
||||
if (hasValue(ePersonUuid)) {
|
||||
searchParams.push(new RequestParam('eperson', ePersonUuid));
|
||||
}
|
||||
return Object.assign(new FindListOptions(), { searchParams });
|
||||
}
|
||||
|
||||
describe('when no arguments are provided and a user is authenticated', () => {
|
||||
beforeEach(() => {
|
||||
service.searchByObject().subscribe();
|
||||
});
|
||||
|
||||
it('should call searchBy with the site\'s url and authenticated user\'s uuid', () => {
|
||||
expect(service.searchBy).toHaveBeenCalledWith('object', createExpected(site.self, ePerson.uuid));
|
||||
});
|
||||
});
|
||||
|
||||
describe('when no arguments except for a feature are provided and a user is authenticated', () => {
|
||||
beforeEach(() => {
|
||||
service.searchByObject(FeatureType.LoginOnBehalfOf).subscribe();
|
||||
});
|
||||
|
||||
it('should call searchBy with the site\'s url, authenticated user\'s uuid and the feature', () => {
|
||||
expect(service.searchBy).toHaveBeenCalledWith('object', createExpected(site.self, ePerson.uuid, FeatureType.LoginOnBehalfOf));
|
||||
});
|
||||
});
|
||||
|
||||
describe('when a feature and object url are provided, but no user uuid and a user is authenticated', () => {
|
||||
beforeEach(() => {
|
||||
service.searchByObject(FeatureType.LoginOnBehalfOf, objectUrl).subscribe();
|
||||
});
|
||||
|
||||
it('should call searchBy with the object\'s url, authenticated user\'s uuid and the feature', () => {
|
||||
expect(service.searchBy).toHaveBeenCalledWith('object', createExpected(objectUrl, ePerson.uuid, FeatureType.LoginOnBehalfOf));
|
||||
});
|
||||
});
|
||||
|
||||
describe('when all arguments are provided', () => {
|
||||
beforeEach(() => {
|
||||
service.searchByObject(FeatureType.LoginOnBehalfOf, objectUrl, ePersonUuid).subscribe();
|
||||
});
|
||||
|
||||
it('should call searchBy with the object\'s url, user\'s uuid and the feature', () => {
|
||||
expect(service.searchBy).toHaveBeenCalledWith('object', createExpected(objectUrl, ePersonUuid, FeatureType.LoginOnBehalfOf));
|
||||
});
|
||||
});
|
||||
|
||||
describe('when no arguments are provided and no user is authenticated', () => {
|
||||
beforeEach(() => {
|
||||
spyOn(authService, 'isAuthenticated').and.returnValue(observableOf(false));
|
||||
service.searchByObject().subscribe();
|
||||
});
|
||||
|
||||
it('should call searchBy with the site\'s url', () => {
|
||||
expect(service.searchBy).toHaveBeenCalledWith('object', createExpected(site.self));
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('isAuthenticated', () => {
|
||||
const validPayload = [
|
||||
Object.assign(new Authorization())
|
||||
]
|
||||
const emptyPayload = [];
|
||||
|
||||
describe('when searchByObject returns a 401', () => {
|
||||
beforeEach(() => {
|
||||
spyOn(service, 'searchByObject').and.returnValue(observableOf(new RemoteData(false, false, true, undefined, undefined, 401)));
|
||||
});
|
||||
|
||||
it('should return false', (done) => {
|
||||
service.isAuthenticated().subscribe((result) => {
|
||||
expect(result).toEqual(false);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('when searchByObject returns an empty list', () => {
|
||||
beforeEach(() => {
|
||||
spyOn(service, 'searchByObject').and.returnValue(createSuccessfulRemoteDataObject$(createPaginatedList(emptyPayload)));
|
||||
});
|
||||
|
||||
it('should return false', (done) => {
|
||||
service.isAuthenticated().subscribe((result) => {
|
||||
expect(result).toEqual(false);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('when searchByObject returns a valid list', () => {
|
||||
beforeEach(() => {
|
||||
spyOn(service, 'searchByObject').and.returnValue(createSuccessfulRemoteDataObject$(createPaginatedList(validPayload)));
|
||||
});
|
||||
|
||||
it('should return true', (done) => {
|
||||
service.isAuthenticated().subscribe((result) => {
|
||||
expect(result).toEqual(true);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
@@ -0,0 +1,67 @@
|
||||
import { FeatureAuthorizationGuard } from './feature-authorization.guard';
|
||||
import { AuthorizationDataService } from '../authorization-data.service';
|
||||
import { FeatureType } from '../feature-type';
|
||||
import { of as observableOf } from 'rxjs';
|
||||
|
||||
/**
|
||||
* Test implementation of abstract class FeatureAuthorizationGuard
|
||||
* Provide the return values of the overwritten getters as constructor arguments
|
||||
*/
|
||||
class FeatureAuthorizationGuardImpl extends FeatureAuthorizationGuard {
|
||||
constructor(protected authorizationService: AuthorizationDataService,
|
||||
protected featureType: FeatureType,
|
||||
protected objectUrl: string,
|
||||
protected ePersonUuid: string) {
|
||||
super(authorizationService);
|
||||
}
|
||||
|
||||
getFeatureType(): FeatureType {
|
||||
return this.featureType;
|
||||
}
|
||||
|
||||
getObjectUrl(): string {
|
||||
return this.objectUrl;
|
||||
}
|
||||
|
||||
getEPersonUuid(): string {
|
||||
return this.ePersonUuid;
|
||||
}
|
||||
}
|
||||
|
||||
describe('FeatureAuthorizationGuard', () => {
|
||||
let guard: FeatureAuthorizationGuard;
|
||||
let authorizationService: AuthorizationDataService;
|
||||
|
||||
let featureType: FeatureType;
|
||||
let objectUrl: string;
|
||||
let ePersonUuid: string;
|
||||
|
||||
function init() {
|
||||
featureType = FeatureType.LoginOnBehalfOf;
|
||||
objectUrl = 'fake-object-url';
|
||||
ePersonUuid = 'fake-eperson-uuid';
|
||||
|
||||
authorizationService = jasmine.createSpyObj('authorizationService', {
|
||||
isAuthenticated: observableOf(true)
|
||||
});
|
||||
guard = new FeatureAuthorizationGuardImpl(authorizationService, featureType, objectUrl, ePersonUuid);
|
||||
}
|
||||
|
||||
beforeEach(() => {
|
||||
init();
|
||||
});
|
||||
|
||||
describe('canActivate', () => {
|
||||
it('should call authorizationService.isAuthenticated with the appropriate arguments', () => {
|
||||
guard.canActivate(undefined, undefined).subscribe();
|
||||
expect(authorizationService.isAuthenticated).toHaveBeenCalledWith(featureType, objectUrl, ePersonUuid);
|
||||
});
|
||||
});
|
||||
|
||||
describe('canLoad', () => {
|
||||
it('should call authorizationService.isAuthenticated with the appropriate arguments', () => {
|
||||
guard.canLoad(undefined, undefined).subscribe();
|
||||
expect(authorizationService.isAuthenticated).toHaveBeenCalledWith(featureType, objectUrl, ePersonUuid);
|
||||
});
|
||||
});
|
||||
});
|
Reference in New Issue
Block a user