mirror of
https://github.com/DSpace/dspace-angular.git
synced 2025-10-07 01:54:15 +00:00
[CST-5339] Refactoring orcid services by adding OrcidAuthService
This commit is contained in:
329
src/app/core/orcid/orcid-auth.service.spec.ts
Normal file
329
src/app/core/orcid/orcid-auth.service.spec.ts
Normal file
@@ -0,0 +1,329 @@
|
||||
import { cold, getTestScheduler } from 'jasmine-marbles';
|
||||
import { TestScheduler } from 'rxjs/testing';
|
||||
import { createFailedRemoteDataObject$, createSuccessfulRemoteDataObject$ } from '../../shared/remote-data.utils';
|
||||
import { RouterMock } from '../../shared/mocks/router.mock';
|
||||
import { ResearcherProfile } from '../profile/model/researcher-profile.model';
|
||||
import { Item } from '../shared/item.model';
|
||||
import { AddOperation, RemoveOperation } from 'fast-json-patch';
|
||||
import { ConfigurationProperty } from '../shared/configuration-property.model';
|
||||
import { ConfigurationDataService } from '../data/configuration-data.service';
|
||||
import { createPaginatedList } from '../../shared/testing/utils.test';
|
||||
import { NativeWindowRefMock } from '../../shared/mocks/mock-native-window-ref';
|
||||
import { URLCombiner } from '../url-combiner/url-combiner';
|
||||
import { OrcidAuthService } from './orcid-auth.service';
|
||||
import { ResearcherProfileService } from '../profile/researcher-profile.service';
|
||||
|
||||
describe('OrcidAuthService', () => {
|
||||
let scheduler: TestScheduler;
|
||||
let service: OrcidAuthService;
|
||||
let serviceAsAny: any;
|
||||
|
||||
let researcherProfileService: jasmine.SpyObj<ResearcherProfileService>;
|
||||
let configurationDataService: ConfigurationDataService;
|
||||
let nativeWindowService: NativeWindowRefMock;
|
||||
let routerStub: any;
|
||||
|
||||
const researcherProfileId = 'beef9946-rt56-479e-8f11-b90cbe9f7241';
|
||||
const itemId = 'beef9946-rt56-479e-8f11-b90cbe9f7241';
|
||||
|
||||
const researcherProfile: ResearcherProfile = Object.assign(new ResearcherProfile(), {
|
||||
id: researcherProfileId,
|
||||
visible: false,
|
||||
type: 'profile',
|
||||
_links: {
|
||||
item: {
|
||||
href: `https://rest.api/rest/api/profiles/${researcherProfileId}/item`
|
||||
},
|
||||
self: {
|
||||
href: `https://rest.api/rest/api/profiles/${researcherProfileId}`
|
||||
},
|
||||
}
|
||||
});
|
||||
|
||||
const researcherProfilePatched: ResearcherProfile = Object.assign(new ResearcherProfile(), {
|
||||
id: researcherProfileId,
|
||||
visible: true,
|
||||
type: 'profile',
|
||||
_links: {
|
||||
item: {
|
||||
href: `https://rest.api/rest/api/profiles/${researcherProfileId}/item`
|
||||
},
|
||||
self: {
|
||||
href: `https://rest.api/rest/api/profiles/${researcherProfileId}`
|
||||
},
|
||||
}
|
||||
});
|
||||
|
||||
const mockItemUnlinkedToOrcid: Item = Object.assign(new Item(), {
|
||||
id: 'mockItemUnlinkedToOrcid',
|
||||
bundles: createSuccessfulRemoteDataObject$(createPaginatedList([])),
|
||||
metadata: {
|
||||
'dc.title': [{
|
||||
value: 'test person'
|
||||
}],
|
||||
'dspace.entity.type': [{
|
||||
'value': 'Person'
|
||||
}],
|
||||
'dspace.object.owner': [{
|
||||
'value': 'test person',
|
||||
'language': null,
|
||||
'authority': 'researcher-profile-id',
|
||||
'confidence': 600,
|
||||
'place': 0
|
||||
}],
|
||||
}
|
||||
});
|
||||
|
||||
const mockItemLinkedToOrcid: Item = Object.assign(new Item(), {
|
||||
bundles: createSuccessfulRemoteDataObject$(createPaginatedList([])),
|
||||
metadata: {
|
||||
'dc.title': [{
|
||||
value: 'test person'
|
||||
}],
|
||||
'dspace.entity.type': [{
|
||||
'value': 'Person'
|
||||
}],
|
||||
'dspace.object.owner': [{
|
||||
'value': 'test person',
|
||||
'language': null,
|
||||
'authority': 'researcher-profile-id',
|
||||
'confidence': 600,
|
||||
'place': 0
|
||||
}],
|
||||
'dspace.orcid.authenticated': [{
|
||||
'value': '2022-06-10T15:15:12.952872',
|
||||
'language': null,
|
||||
'authority': null,
|
||||
'confidence': -1,
|
||||
'place': 0
|
||||
}],
|
||||
'dspace.orcid.scope': [{
|
||||
'value': '/authenticate',
|
||||
'language': null,
|
||||
'authority': null,
|
||||
'confidence': -1,
|
||||
'place': 0
|
||||
}, {
|
||||
'value': '/read-limited',
|
||||
'language': null,
|
||||
'authority': null,
|
||||
'confidence': -1,
|
||||
'place': 1
|
||||
}, {
|
||||
'value': '/activities/update',
|
||||
'language': null,
|
||||
'authority': null,
|
||||
'confidence': -1,
|
||||
'place': 2
|
||||
}, {
|
||||
'value': '/person/update',
|
||||
'language': null,
|
||||
'authority': null,
|
||||
'confidence': -1,
|
||||
'place': 3
|
||||
}],
|
||||
'person.identifier.orcid': [{
|
||||
'value': 'orcid-id',
|
||||
'language': null,
|
||||
'authority': null,
|
||||
'confidence': -1,
|
||||
'place': 0
|
||||
}]
|
||||
}
|
||||
});
|
||||
|
||||
const disconnectionAllowAdmin = {
|
||||
uuid: 'orcid.disconnection.allowed-users',
|
||||
name: 'orcid.disconnection.allowed-users',
|
||||
values: ['only_admin']
|
||||
} as ConfigurationProperty;
|
||||
|
||||
const disconnectionAllowAdminOwner = {
|
||||
uuid: 'orcid.disconnection.allowed-users',
|
||||
name: 'orcid.disconnection.allowed-users',
|
||||
values: ['admin_and_owner']
|
||||
} as ConfigurationProperty;
|
||||
|
||||
const authorizeUrl = {
|
||||
uuid: 'orcid.authorize-url',
|
||||
name: 'orcid.authorize-url',
|
||||
values: ['orcid.authorize-url']
|
||||
} as ConfigurationProperty;
|
||||
const appClientId = {
|
||||
uuid: 'orcid.application-client-id',
|
||||
name: 'orcid.application-client-id',
|
||||
values: ['orcid.application-client-id']
|
||||
} as ConfigurationProperty;
|
||||
const orcidScope = {
|
||||
uuid: 'orcid.scope',
|
||||
name: 'orcid.scope',
|
||||
values: ['/authenticate', '/read-limited']
|
||||
} as ConfigurationProperty;
|
||||
|
||||
beforeEach(() => {
|
||||
scheduler = getTestScheduler();
|
||||
routerStub = new RouterMock();
|
||||
researcherProfileService = jasmine.createSpyObj('ResearcherProfileService', {
|
||||
findById: jasmine.createSpy('findById'),
|
||||
updateByOrcidOperations: jasmine.createSpy('updateByOrcidOperations')
|
||||
});
|
||||
configurationDataService = jasmine.createSpyObj('configurationDataService', {
|
||||
findByPropertyName: jasmine.createSpy('findByPropertyName')
|
||||
});
|
||||
nativeWindowService = new NativeWindowRefMock();
|
||||
|
||||
service = new OrcidAuthService(
|
||||
nativeWindowService,
|
||||
configurationDataService,
|
||||
researcherProfileService,
|
||||
routerStub);
|
||||
|
||||
serviceAsAny = service;
|
||||
});
|
||||
|
||||
|
||||
describe('isLinkedToOrcid', () => {
|
||||
it('should return true when item has metadata', () => {
|
||||
const result = service.isLinkedToOrcid(mockItemLinkedToOrcid);
|
||||
expect(result).toBeTrue();
|
||||
});
|
||||
|
||||
it('should return true when item has no metadata', () => {
|
||||
const result = service.isLinkedToOrcid(mockItemUnlinkedToOrcid);
|
||||
expect(result).toBeFalse();
|
||||
});
|
||||
});
|
||||
|
||||
describe('onlyAdminCanDisconnectProfileFromOrcid', () => {
|
||||
it('should return true when property is only_admin', () => {
|
||||
spyOn((service as any), 'getOrcidDisconnectionAllowedUsersConfiguration').and.returnValue(createSuccessfulRemoteDataObject$(disconnectionAllowAdmin));
|
||||
const result = service.onlyAdminCanDisconnectProfileFromOrcid();
|
||||
const expected = cold('(a|)', {
|
||||
a: true
|
||||
});
|
||||
expect(result).toBeObservable(expected);
|
||||
});
|
||||
|
||||
it('should return false on faild', () => {
|
||||
spyOn((service as any), 'getOrcidDisconnectionAllowedUsersConfiguration').and.returnValue(createFailedRemoteDataObject$());
|
||||
const result = service.onlyAdminCanDisconnectProfileFromOrcid();
|
||||
const expected = cold('(a|)', {
|
||||
a: false
|
||||
});
|
||||
expect(result).toBeObservable(expected);
|
||||
});
|
||||
});
|
||||
|
||||
describe('ownerCanDisconnectProfileFromOrcid', () => {
|
||||
it('should return true when property is admin_and_owner', () => {
|
||||
spyOn((service as any), 'getOrcidDisconnectionAllowedUsersConfiguration').and.returnValue(createSuccessfulRemoteDataObject$(disconnectionAllowAdminOwner));
|
||||
const result = service.ownerCanDisconnectProfileFromOrcid();
|
||||
const expected = cold('(a|)', {
|
||||
a: true
|
||||
});
|
||||
expect(result).toBeObservable(expected);
|
||||
});
|
||||
|
||||
it('should return false on faild', () => {
|
||||
spyOn((service as any), 'getOrcidDisconnectionAllowedUsersConfiguration').and.returnValue(createFailedRemoteDataObject$());
|
||||
const result = service.ownerCanDisconnectProfileFromOrcid();
|
||||
const expected = cold('(a|)', {
|
||||
a: false
|
||||
});
|
||||
expect(result).toBeObservable(expected);
|
||||
});
|
||||
});
|
||||
|
||||
describe('linkOrcidByItem', () => {
|
||||
beforeEach(() => {
|
||||
scheduler = getTestScheduler();
|
||||
researcherProfileService.updateByOrcidOperations.and.returnValue(createSuccessfulRemoteDataObject$(researcherProfilePatched));
|
||||
researcherProfileService.findById.and.returnValue(createSuccessfulRemoteDataObject$(researcherProfile));
|
||||
});
|
||||
|
||||
it('should call updateByOrcidOperations method properly', () => {
|
||||
const operations: AddOperation<string>[] = [{
|
||||
path: '/orcid',
|
||||
op: 'add',
|
||||
value: 'test-code'
|
||||
}];
|
||||
|
||||
scheduler.schedule(() => service.linkOrcidByItem(mockItemUnlinkedToOrcid, 'test-code').subscribe());
|
||||
scheduler.flush();
|
||||
|
||||
expect(researcherProfileService.updateByOrcidOperations).toHaveBeenCalledWith(researcherProfile, operations);
|
||||
});
|
||||
});
|
||||
|
||||
describe('unlinkOrcidByItem', () => {
|
||||
beforeEach(() => {
|
||||
scheduler = getTestScheduler();
|
||||
researcherProfileService.updateByOrcidOperations.and.returnValue(createSuccessfulRemoteDataObject$(researcherProfilePatched));
|
||||
researcherProfileService.findById.and.returnValue(createSuccessfulRemoteDataObject$(researcherProfile));
|
||||
});
|
||||
|
||||
it('should call updateByOrcidOperations method properly', () => {
|
||||
const operations: RemoveOperation[] = [{
|
||||
path: '/orcid',
|
||||
op: 'remove'
|
||||
}];
|
||||
|
||||
scheduler.schedule(() => service.unlinkOrcidByItem(mockItemLinkedToOrcid).subscribe());
|
||||
scheduler.flush();
|
||||
|
||||
expect(researcherProfileService.updateByOrcidOperations).toHaveBeenCalledWith(researcherProfile, operations);
|
||||
});
|
||||
});
|
||||
|
||||
describe('getOrcidAuthorizeUrl', () => {
|
||||
beforeEach(() => {
|
||||
routerStub.setRoute('/entities/person/uuid/orcid');
|
||||
(service as any).configurationService.findByPropertyName.and.returnValues(
|
||||
createSuccessfulRemoteDataObject$(authorizeUrl),
|
||||
createSuccessfulRemoteDataObject$(appClientId),
|
||||
createSuccessfulRemoteDataObject$(orcidScope)
|
||||
);
|
||||
});
|
||||
|
||||
it('should build the url properly', () => {
|
||||
const result = service.getOrcidAuthorizeUrl(mockItemUnlinkedToOrcid);
|
||||
const redirectUri: string = new URLCombiner(nativeWindowService.nativeWindow.origin, encodeURIComponent(routerStub.url.split('?')[0])).toString();
|
||||
const url = 'orcid.authorize-url?client_id=orcid.application-client-id&redirect_uri=' + redirectUri + '&response_type=code&scope=/authenticate /read-limited';
|
||||
|
||||
const expected = cold('(a|)', {
|
||||
a: url
|
||||
});
|
||||
expect(result).toBeObservable(expected);
|
||||
});
|
||||
});
|
||||
|
||||
describe('getOrcidAuthorizationScopesByItem', () => {
|
||||
it('should return list of scopes saved in the item', () => {
|
||||
const orcidScopes = [
|
||||
'/authenticate',
|
||||
'/read-limited',
|
||||
'/activities/update',
|
||||
'/person/update'
|
||||
];
|
||||
const result = service.getOrcidAuthorizationScopesByItem(mockItemLinkedToOrcid);
|
||||
expect(result).toEqual(orcidScopes);
|
||||
});
|
||||
});
|
||||
|
||||
describe('getOrcidAuthorizationScopes', () => {
|
||||
it('should return list of scopes by configuration', () => {
|
||||
(service as any).configurationService.findByPropertyName.and.returnValue(
|
||||
createSuccessfulRemoteDataObject$(orcidScope)
|
||||
);
|
||||
const orcidScopes = [
|
||||
'/authenticate',
|
||||
'/read-limited'
|
||||
];
|
||||
const expected = cold('(a|)', {
|
||||
a: orcidScopes
|
||||
});
|
||||
const result = service.getOrcidAuthorizationScopes();
|
||||
expect(result).toBeObservable(expected);
|
||||
});
|
||||
});
|
||||
});
|
147
src/app/core/orcid/orcid-auth.service.ts
Normal file
147
src/app/core/orcid/orcid-auth.service.ts
Normal file
@@ -0,0 +1,147 @@
|
||||
import { Inject, Injectable } from '@angular/core';
|
||||
import { Router } from '@angular/router';
|
||||
|
||||
import { combineLatest, Observable } from 'rxjs';
|
||||
import { map, switchMap } from 'rxjs/operators';
|
||||
import { AddOperation, RemoveOperation } from 'fast-json-patch';
|
||||
|
||||
import { ResearcherProfileService } from '../profile/researcher-profile.service';
|
||||
import { Item } from '../shared/item.model';
|
||||
import { isNotEmpty } from '../../shared/empty.util';
|
||||
import { getFirstCompletedRemoteData, getFirstSucceededRemoteDataPayload } from '../shared/operators';
|
||||
import { RemoteData } from '../data/remote-data';
|
||||
import { ConfigurationProperty } from '../shared/configuration-property.model';
|
||||
import { ConfigurationDataService } from '../data/configuration-data.service';
|
||||
import { ResearcherProfile } from '../profile/model/researcher-profile.model';
|
||||
import { URLCombiner } from '../url-combiner/url-combiner';
|
||||
import { NativeWindowRef, NativeWindowService } from '../services/window.service';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class OrcidAuthService {
|
||||
|
||||
constructor(
|
||||
@Inject(NativeWindowService) protected _window: NativeWindowRef,
|
||||
private configurationService: ConfigurationDataService,
|
||||
private researcherProfileService: ResearcherProfileService,
|
||||
private router: Router) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the given item is linked to an ORCID profile.
|
||||
*
|
||||
* @param item the item to check
|
||||
* @returns the check result
|
||||
*/
|
||||
public isLinkedToOrcid(item: Item): boolean {
|
||||
return item.hasMetadata('dspace.orcid.authenticated');
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if only the admin users can disconnect a researcher profile from ORCID.
|
||||
*
|
||||
* @returns the check result
|
||||
*/
|
||||
public onlyAdminCanDisconnectProfileFromOrcid(): Observable<boolean> {
|
||||
return this.getOrcidDisconnectionAllowedUsersConfiguration().pipe(
|
||||
map((propertyRD: RemoteData<ConfigurationProperty>) => {
|
||||
return propertyRD.hasSucceeded && propertyRD.payload.values.map((value) => value.toLowerCase()).includes('only_admin');
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the profile's owner can disconnect that profile from ORCID.
|
||||
*
|
||||
* @returns the check result
|
||||
*/
|
||||
public ownerCanDisconnectProfileFromOrcid(): Observable<boolean> {
|
||||
return this.getOrcidDisconnectionAllowedUsersConfiguration().pipe(
|
||||
map((propertyRD: RemoteData<ConfigurationProperty>) => {
|
||||
return propertyRD.hasSucceeded && propertyRD.payload.values.map( (value) => value.toLowerCase()).includes('admin_and_owner');
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform a link operation to ORCID profile.
|
||||
*
|
||||
* @param person The person item related to the researcher profile
|
||||
* @param code The auth-code received from orcid
|
||||
*/
|
||||
public linkOrcidByItem(person: Item, code: string): Observable<RemoteData<ResearcherProfile>> {
|
||||
const operations: AddOperation<string>[] = [{
|
||||
path: '/orcid',
|
||||
op: 'add',
|
||||
value: code
|
||||
}];
|
||||
|
||||
return this.researcherProfileService.findById(person.firstMetadata('dspace.object.owner').authority).pipe(
|
||||
getFirstCompletedRemoteData(),
|
||||
switchMap((profileRD) => this.researcherProfileService.updateByOrcidOperations(profileRD.payload, operations))
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform unlink operation from ORCID profile.
|
||||
*
|
||||
* @param person The person item related to the researcher profile
|
||||
*/
|
||||
public unlinkOrcidByItem(person: Item): Observable<RemoteData<ResearcherProfile>> {
|
||||
const operations: RemoveOperation[] = [{
|
||||
path:'/orcid',
|
||||
op:'remove'
|
||||
}];
|
||||
|
||||
return this.researcherProfileService.findById(person.firstMetadata('dspace.object.owner').authority).pipe(
|
||||
getFirstCompletedRemoteData(),
|
||||
switchMap((profileRD) => this.researcherProfileService.updateByOrcidOperations(profileRD.payload, operations))
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Build and return the url to authenticate with orcid
|
||||
*
|
||||
* @param profile
|
||||
*/
|
||||
public getOrcidAuthorizeUrl(profile: Item): Observable<string> {
|
||||
return combineLatest([
|
||||
this.configurationService.findByPropertyName('orcid.authorize-url').pipe(getFirstSucceededRemoteDataPayload()),
|
||||
this.configurationService.findByPropertyName('orcid.application-client-id').pipe(getFirstSucceededRemoteDataPayload()),
|
||||
this.configurationService.findByPropertyName('orcid.scope').pipe(getFirstSucceededRemoteDataPayload())]
|
||||
).pipe(
|
||||
map(([authorizeUrl, clientId, scopes]) => {
|
||||
const redirectUri = new URLCombiner(this._window.nativeWindow.origin, encodeURIComponent(this.router.url.split('?')[0]));
|
||||
console.log(redirectUri.toString());
|
||||
return authorizeUrl.values[0] + '?client_id=' + clientId.values[0] + '&redirect_uri=' + redirectUri + '&response_type=code&scope='
|
||||
+ scopes.values.join(' ');
|
||||
}));
|
||||
}
|
||||
|
||||
/**
|
||||
* Return all orcid authorization scopes saved in the given item
|
||||
*
|
||||
* @param item
|
||||
*/
|
||||
public getOrcidAuthorizationScopesByItem(item: Item): string[] {
|
||||
return isNotEmpty(item) ? item.allMetadataValues('dspace.orcid.scope') : [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Return all orcid authorization scopes available by configuration
|
||||
*/
|
||||
public getOrcidAuthorizationScopes(): Observable<string[]> {
|
||||
return this.configurationService.findByPropertyName('orcid.scope').pipe(
|
||||
getFirstCompletedRemoteData(),
|
||||
map((propertyRD: RemoteData<ConfigurationProperty>) => propertyRD.hasSucceeded ? propertyRD.payload.values : [])
|
||||
);
|
||||
}
|
||||
|
||||
private getOrcidDisconnectionAllowedUsersConfiguration(): Observable<RemoteData<ConfigurationProperty>> {
|
||||
return this.configurationService.findByPropertyName('orcid.disconnection.allowed-users').pipe(
|
||||
getFirstCompletedRemoteData()
|
||||
);
|
||||
}
|
||||
|
||||
}
|
@@ -13,16 +13,13 @@ import { Injectable } from '@angular/core';
|
||||
import { dataService } from '../cache/builders/build-decorators';
|
||||
import { ORCID_QUEUE } from './model/orcid-queue.resource-type';
|
||||
import { ItemDataService } from '../data/item-data.service';
|
||||
import { combineLatest, Observable } from 'rxjs';
|
||||
import { Observable } from 'rxjs';
|
||||
import { RemoteData } from '../data/remote-data';
|
||||
import { PaginatedList } from '../data/paginated-list.model';
|
||||
import { RequestParam } from '../cache/models/request-param.model';
|
||||
import { PaginationComponentOptions } from '../../shared/pagination/pagination-component-options.model';
|
||||
import { NoContent } from '../shared/NoContent.model';
|
||||
import { ConfigurationDataService } from '../data/configuration-data.service';
|
||||
import { map } from 'rxjs/operators';
|
||||
import { getFirstSucceededRemoteDataPayload } from '../shared/operators';
|
||||
import { environment } from '../../../environments/environment';
|
||||
import { Router } from '@angular/router';
|
||||
import { CoreState } from '../core-state.model';
|
||||
|
||||
@@ -110,20 +107,4 @@ export class OrcidQueueService {
|
||||
this.requestService.setStaleByHrefSubstring(this.dataService.linkPath + '/search/findByOwner');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param profileId represent a uuid of that user
|
||||
* @returns orcid authorized url of that user
|
||||
*/
|
||||
getOrcidAuthorizeUrl(profileId: string): Observable<string> {
|
||||
return combineLatest([
|
||||
this.configurationService.findByPropertyName('orcid.authorize-url').pipe(getFirstSucceededRemoteDataPayload()),
|
||||
this.configurationService.findByPropertyName('orcid.application-client-id').pipe(getFirstSucceededRemoteDataPayload()),
|
||||
this.configurationService.findByPropertyName('orcid.scope').pipe(getFirstSucceededRemoteDataPayload())]
|
||||
).pipe(
|
||||
map(([authorizeUrl, clientId, scopes]) => {
|
||||
const redirectUri = environment.rest.baseUrl + '/api/cris/orcid/' + profileId + '/?url=' + encodeURIComponent(this.router.url);
|
||||
return authorizeUrl.values[0] + '?client_id=' + clientId.values[0] + '&redirect_uri=' + redirectUri + '&response_type=code&scope='
|
||||
+ scopes.values.join(' ');
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
@@ -12,7 +12,6 @@ import { RequestService } from '../data/request.service';
|
||||
import { PageInfo } from '../shared/page-info.model';
|
||||
import { buildPaginatedList } from '../data/paginated-list.model';
|
||||
import {
|
||||
createFailedRemoteDataObject$,
|
||||
createNoContentRemoteDataObject$,
|
||||
createSuccessfulRemoteDataObject,
|
||||
createSuccessfulRemoteDataObject$
|
||||
@@ -23,15 +22,12 @@ import { ResearcherProfileService } from './researcher-profile.service';
|
||||
import { RouterMock } from '../../shared/mocks/router.mock';
|
||||
import { ResearcherProfile } from './model/researcher-profile.model';
|
||||
import { Item } from '../shared/item.model';
|
||||
import { AddOperation, RemoveOperation, ReplaceOperation } from 'fast-json-patch';
|
||||
import { ReplaceOperation } from 'fast-json-patch';
|
||||
import { HttpOptions } from '../dspace-rest/dspace-rest.service';
|
||||
import { PostRequest } from '../data/request.models';
|
||||
import { followLink } from '../../shared/utils/follow-link-config.model';
|
||||
import { ConfigurationProperty } from '../shared/configuration-property.model';
|
||||
import { ConfigurationDataService } from '../data/configuration-data.service';
|
||||
import { createPaginatedList } from '../../shared/testing/utils.test';
|
||||
import { NativeWindowRefMock } from '../../shared/mocks/mock-native-window-ref';
|
||||
import { URLCombiner } from '../url-combiner/url-combiner';
|
||||
|
||||
describe('ResearcherProfileService', () => {
|
||||
let scheduler: TestScheduler;
|
||||
@@ -42,8 +38,6 @@ describe('ResearcherProfileService', () => {
|
||||
let objectCache: ObjectCacheService;
|
||||
let halService: HALEndpointService;
|
||||
let responseCacheEntry: RequestEntry;
|
||||
let configurationDataService: ConfigurationDataService;
|
||||
let nativeWindowService: NativeWindowRefMock;
|
||||
let routerStub: any;
|
||||
|
||||
const researcherProfileId = 'beef9946-rt56-479e-8f11-b90cbe9f7241';
|
||||
@@ -252,13 +246,8 @@ describe('ResearcherProfileService', () => {
|
||||
const itemService = jasmine.createSpyObj('ItemService', {
|
||||
findByHref: jasmine.createSpy('findByHref')
|
||||
});
|
||||
configurationDataService = jasmine.createSpyObj('configurationDataService', {
|
||||
findByPropertyName: jasmine.createSpy('findByPropertyName')
|
||||
});
|
||||
nativeWindowService = new NativeWindowRefMock();
|
||||
|
||||
service = new ResearcherProfileService(
|
||||
nativeWindowService,
|
||||
requestService,
|
||||
rdbService,
|
||||
objectCache,
|
||||
@@ -267,8 +256,7 @@ describe('ResearcherProfileService', () => {
|
||||
http,
|
||||
routerStub,
|
||||
comparator,
|
||||
itemService,
|
||||
configurationDataService
|
||||
itemService
|
||||
);
|
||||
serviceAsAny = service;
|
||||
|
||||
@@ -415,121 +403,6 @@ describe('ResearcherProfileService', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('isLinkedToOrcid', () => {
|
||||
it('should return true when item has metadata', () => {
|
||||
const result = service.isLinkedToOrcid(mockItemLinkedToOrcid);
|
||||
expect(result).toBeTrue();
|
||||
});
|
||||
|
||||
it('should return true when item has no metadata', () => {
|
||||
const result = service.isLinkedToOrcid(mockItemUnlinkedToOrcid);
|
||||
expect(result).toBeFalse();
|
||||
});
|
||||
});
|
||||
|
||||
describe('onlyAdminCanDisconnectProfileFromOrcid', () => {
|
||||
it('should return true when property is only_admin', () => {
|
||||
spyOn((service as any), 'getOrcidDisconnectionAllowedUsersConfiguration').and.returnValue(createSuccessfulRemoteDataObject$(disconnectionAllowAdmin));
|
||||
const result = service.onlyAdminCanDisconnectProfileFromOrcid();
|
||||
const expected = cold('(a|)', {
|
||||
a: true
|
||||
});
|
||||
expect(result).toBeObservable(expected);
|
||||
});
|
||||
|
||||
it('should return false on faild', () => {
|
||||
spyOn((service as any), 'getOrcidDisconnectionAllowedUsersConfiguration').and.returnValue(createFailedRemoteDataObject$());
|
||||
const result = service.onlyAdminCanDisconnectProfileFromOrcid();
|
||||
const expected = cold('(a|)', {
|
||||
a: false
|
||||
});
|
||||
expect(result).toBeObservable(expected);
|
||||
});
|
||||
});
|
||||
|
||||
describe('ownerCanDisconnectProfileFromOrcid', () => {
|
||||
it('should return true when property is admin_and_owner', () => {
|
||||
spyOn((service as any), 'getOrcidDisconnectionAllowedUsersConfiguration').and.returnValue(createSuccessfulRemoteDataObject$(disconnectionAllowAdminOwner));
|
||||
const result = service.ownerCanDisconnectProfileFromOrcid();
|
||||
const expected = cold('(a|)', {
|
||||
a: true
|
||||
});
|
||||
expect(result).toBeObservable(expected);
|
||||
});
|
||||
|
||||
it('should return false on faild', () => {
|
||||
spyOn((service as any), 'getOrcidDisconnectionAllowedUsersConfiguration').and.returnValue(createFailedRemoteDataObject$());
|
||||
const result = service.ownerCanDisconnectProfileFromOrcid();
|
||||
const expected = cold('(a|)', {
|
||||
a: false
|
||||
});
|
||||
expect(result).toBeObservable(expected);
|
||||
});
|
||||
});
|
||||
|
||||
describe('linkOrcidByItem', () => {
|
||||
beforeEach(() => {
|
||||
scheduler = getTestScheduler();
|
||||
spyOn((service as any).dataService, 'patch').and.returnValue(createSuccessfulRemoteDataObject$(researcherProfilePatched));
|
||||
spyOn((service as any), 'findById').and.returnValue(createSuccessfulRemoteDataObject$(researcherProfile));
|
||||
});
|
||||
|
||||
it('should call patch method properly', () => {
|
||||
const operations: AddOperation<string>[] = [{
|
||||
path: '/orcid',
|
||||
op: 'add',
|
||||
value: 'test-code'
|
||||
}];
|
||||
|
||||
scheduler.schedule(() => service.linkOrcidByItem(mockItemUnlinkedToOrcid, 'test-code').subscribe());
|
||||
scheduler.flush();
|
||||
|
||||
expect((service as any).dataService.patch).toHaveBeenCalledWith(researcherProfile, operations);
|
||||
});
|
||||
});
|
||||
|
||||
describe('unlinkOrcidByItem', () => {
|
||||
beforeEach(() => {
|
||||
scheduler = getTestScheduler();
|
||||
spyOn((service as any).dataService, 'patch').and.returnValue(createSuccessfulRemoteDataObject$(researcherProfilePatched));
|
||||
spyOn((service as any), 'findById').and.returnValue(createSuccessfulRemoteDataObject$(researcherProfile));
|
||||
});
|
||||
|
||||
it('should call patch method properly', () => {
|
||||
const operations: RemoveOperation[] = [{
|
||||
path: '/orcid',
|
||||
op: 'remove'
|
||||
}];
|
||||
|
||||
scheduler.schedule(() => service.unlinkOrcidByItem(mockItemLinkedToOrcid).subscribe());
|
||||
scheduler.flush();
|
||||
|
||||
expect((service as any).dataService.patch).toHaveBeenCalledWith(researcherProfile, operations);
|
||||
});
|
||||
});
|
||||
|
||||
describe('getOrcidAuthorizeUrl', () => {
|
||||
beforeEach(() => {
|
||||
routerStub.setRoute('/entities/person/uuid/orcid');
|
||||
(service as any).configurationService.findByPropertyName.and.returnValues(
|
||||
createSuccessfulRemoteDataObject$(authorizeUrl),
|
||||
createSuccessfulRemoteDataObject$(appClientId),
|
||||
createSuccessfulRemoteDataObject$(orcidScope)
|
||||
);
|
||||
});
|
||||
|
||||
it('should build the url properly', () => {
|
||||
const result = service.getOrcidAuthorizeUrl(mockItemUnlinkedToOrcid);
|
||||
const redirectUri: string = new URLCombiner(nativeWindowService.nativeWindow.origin, encodeURIComponent(routerStub.url.split('?')[0])).toString();
|
||||
const url = 'orcid.authorize-url?client_id=orcid.application-client-id&redirect_uri=' + redirectUri + '&response_type=code&scope=/authenticate /read-limited';
|
||||
|
||||
const expected = cold('(a|)', {
|
||||
a: url
|
||||
});
|
||||
expect(result).toBeObservable(expected);
|
||||
});
|
||||
});
|
||||
|
||||
describe('updateByOrcidOperations', () => {
|
||||
beforeEach(() => {
|
||||
scheduler = getTestScheduler();
|
||||
@@ -543,34 +416,4 @@ describe('ResearcherProfileService', () => {
|
||||
expect((service as any).dataService.patch).toHaveBeenCalledWith(researcherProfile, []);
|
||||
});
|
||||
});
|
||||
|
||||
describe('getOrcidAuthorizationScopesByItem', () => {
|
||||
it('should return list of scopes saved in the item', () => {
|
||||
const orcidScopes = [
|
||||
'/authenticate',
|
||||
'/read-limited',
|
||||
'/activities/update',
|
||||
'/person/update'
|
||||
];
|
||||
const result = service.getOrcidAuthorizationScopesByItem(mockItemLinkedToOrcid);
|
||||
expect(result).toEqual(orcidScopes);
|
||||
});
|
||||
});
|
||||
|
||||
describe('getOrcidAuthorizationScopes', () => {
|
||||
it('should return list of scopes by configuration', () => {
|
||||
(service as any).configurationService.findByPropertyName.and.returnValue(
|
||||
createSuccessfulRemoteDataObject$(orcidScope)
|
||||
);
|
||||
const orcidScopes = [
|
||||
'/authenticate',
|
||||
'/read-limited'
|
||||
];
|
||||
const expected = cold('(a|)', {
|
||||
a: orcidScopes
|
||||
});
|
||||
const result = service.getOrcidAuthorizationScopes();
|
||||
expect(result).toBeObservable(expected);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@@ -1,41 +1,33 @@
|
||||
/* eslint-disable max-classes-per-file */
|
||||
import { HttpClient, HttpHeaders } from '@angular/common/http';
|
||||
import { Inject, Injectable } from '@angular/core';
|
||||
import { Injectable } from '@angular/core';
|
||||
import { Router } from '@angular/router';
|
||||
|
||||
import { Store } from '@ngrx/store';
|
||||
import { AddOperation, Operation, RemoveOperation, ReplaceOperation } from 'fast-json-patch';
|
||||
import { combineLatest, Observable } from 'rxjs';
|
||||
import { find, map, switchMap } from 'rxjs/operators';
|
||||
import { Operation, ReplaceOperation } from 'fast-json-patch';
|
||||
import { Observable } from 'rxjs';
|
||||
import { find, map } from 'rxjs/operators';
|
||||
import { NotificationsService } from '../../shared/notifications/notifications.service';
|
||||
import { dataService } from '../cache/builders/build-decorators';
|
||||
import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service';
|
||||
import { ObjectCacheService } from '../cache/object-cache.service';
|
||||
import { ConfigurationDataService } from '../data/configuration-data.service';
|
||||
import { DataService } from '../data/data.service';
|
||||
import { DefaultChangeAnalyzer } from '../data/default-change-analyzer.service';
|
||||
import { ItemDataService } from '../data/item-data.service';
|
||||
import { RemoteData } from '../data/remote-data';
|
||||
import { RequestService } from '../data/request.service';
|
||||
import { ConfigurationProperty } from '../shared/configuration-property.model';
|
||||
import { HALEndpointService } from '../shared/hal-endpoint.service';
|
||||
import { NoContent } from '../shared/NoContent.model';
|
||||
import {
|
||||
getAllCompletedRemoteData,
|
||||
getFirstCompletedRemoteData,
|
||||
getFirstSucceededRemoteDataPayload
|
||||
} from '../shared/operators';
|
||||
import { getAllCompletedRemoteData, getFirstCompletedRemoteData } from '../shared/operators';
|
||||
import { ResearcherProfile } from './model/researcher-profile.model';
|
||||
import { RESEARCHER_PROFILE } from './model/researcher-profile.resource-type';
|
||||
import { HttpOptions } from '../dspace-rest/dspace-rest.service';
|
||||
import { PostRequest } from '../data/request.models';
|
||||
import { hasValue, isEmpty, isNotEmpty } from '../../shared/empty.util';
|
||||
import { hasValue, isEmpty } from '../../shared/empty.util';
|
||||
import { CoreState } from '../core-state.model';
|
||||
import { followLink, FollowLinkConfig } from '../../shared/utils/follow-link-config.model';
|
||||
import { Item } from '../shared/item.model';
|
||||
import { createFailedRemoteDataObject$ } from '../../shared/remote-data.utils';
|
||||
import { NativeWindowRef, NativeWindowService } from '../services/window.service';
|
||||
import { URLCombiner } from '../url-combiner/url-combiner';
|
||||
|
||||
/**
|
||||
* A private DataService implementation to delegate specific methods to.
|
||||
@@ -69,7 +61,6 @@ export class ResearcherProfileService {
|
||||
protected responseMsToLive: number = 10 * 1000;
|
||||
|
||||
constructor(
|
||||
@Inject(NativeWindowService) protected _window: NativeWindowRef,
|
||||
protected requestService: RequestService,
|
||||
protected rdbService: RemoteDataBuildService,
|
||||
protected objectCache: ObjectCacheService,
|
||||
@@ -78,8 +69,7 @@ export class ResearcherProfileService {
|
||||
protected http: HttpClient,
|
||||
protected router: Router,
|
||||
protected comparator: DefaultChangeAnalyzer<ResearcherProfile>,
|
||||
protected itemService: ItemDataService,
|
||||
protected configurationService: ConfigurationDataService) {
|
||||
protected itemService: ItemDataService) {
|
||||
|
||||
this.dataService = new ResearcherProfileServiceImpl(requestService, rdbService, null, objectCache, halService,
|
||||
notificationsService, http, comparator);
|
||||
@@ -165,98 +155,6 @@ export class ResearcherProfileService {
|
||||
return this.dataService.patch(researcherProfile, [replaceOperation]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the given item is linked to an ORCID profile.
|
||||
*
|
||||
* @param item the item to check
|
||||
* @returns the check result
|
||||
*/
|
||||
public isLinkedToOrcid(item: Item): boolean {
|
||||
return item.hasMetadata('dspace.orcid.authenticated');
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if only the admin users can disconnect a researcher profile from ORCID.
|
||||
*
|
||||
* @returns the check result
|
||||
*/
|
||||
public onlyAdminCanDisconnectProfileFromOrcid(): Observable<boolean> {
|
||||
return this.getOrcidDisconnectionAllowedUsersConfiguration().pipe(
|
||||
map((propertyRD: RemoteData<ConfigurationProperty>) => {
|
||||
return propertyRD.hasSucceeded && propertyRD.payload.values.map((value) => value.toLowerCase()).includes('only_admin');
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the profile's owner can disconnect that profile from ORCID.
|
||||
*
|
||||
* @returns the check result
|
||||
*/
|
||||
public ownerCanDisconnectProfileFromOrcid(): Observable<boolean> {
|
||||
return this.getOrcidDisconnectionAllowedUsersConfiguration().pipe(
|
||||
map((propertyRD: RemoteData<ConfigurationProperty>) => {
|
||||
return propertyRD.hasSucceeded && propertyRD.payload.values.map( (value) => value.toLowerCase()).includes('admin_and_owner');
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform a link operation to ORCID profile.
|
||||
*
|
||||
* @param person The person item related to the researcher profile
|
||||
* @param code The auth-code received from orcid
|
||||
*/
|
||||
public linkOrcidByItem(person: Item, code: string): Observable<RemoteData<ResearcherProfile>> {
|
||||
const operations: AddOperation<string>[] = [{
|
||||
path: '/orcid',
|
||||
op: 'add',
|
||||
value: code
|
||||
}];
|
||||
|
||||
return this.findById(person.firstMetadata('dspace.object.owner').authority).pipe(
|
||||
getFirstCompletedRemoteData(),
|
||||
switchMap((profileRD) => this.updateByOrcidOperations(profileRD.payload, operations))
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform unlink operation from ORCID profile.
|
||||
*
|
||||
* @param person The person item related to the researcher profile
|
||||
*/
|
||||
public unlinkOrcidByItem(person: Item): Observable<RemoteData<ResearcherProfile>> {
|
||||
const operations: RemoveOperation[] = [{
|
||||
path:'/orcid',
|
||||
op:'remove'
|
||||
}];
|
||||
|
||||
return this.findById(person.firstMetadata('dspace.object.owner').authority).pipe(
|
||||
getFirstCompletedRemoteData(),
|
||||
switchMap((profileRD) => this.updateByOrcidOperations(profileRD.payload, operations))
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Build and return the url to authenticate with orcid
|
||||
*
|
||||
* @param profile
|
||||
*/
|
||||
public getOrcidAuthorizeUrl(profile: Item): Observable<string> {
|
||||
return combineLatest([
|
||||
this.configurationService.findByPropertyName('orcid.authorize-url').pipe(getFirstSucceededRemoteDataPayload()),
|
||||
this.configurationService.findByPropertyName('orcid.application-client-id').pipe(getFirstSucceededRemoteDataPayload()),
|
||||
this.configurationService.findByPropertyName('orcid.scope').pipe(getFirstSucceededRemoteDataPayload())]
|
||||
).pipe(
|
||||
map(([authorizeUrl, clientId, scopes]) => {
|
||||
console.log(this._window.nativeWindow.origin, this.router.url);
|
||||
const redirectUri = new URLCombiner(this._window.nativeWindow.origin, encodeURIComponent(this.router.url.split('?')[0]));
|
||||
console.log(redirectUri.toString());
|
||||
return authorizeUrl.values[0] + '?client_id=' + clientId.values[0] + '&redirect_uri=' + redirectUri + '&response_type=code&scope='
|
||||
+ scopes.values.join(' ');
|
||||
}));
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a researcher profile starting from an external source URI
|
||||
* @param sourceUri URI of source item of researcher profile.
|
||||
@@ -291,29 +189,6 @@ export class ResearcherProfileService {
|
||||
return this.dataService.patch(researcherProfile, operations);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return all orcid authorization scopes saved in the given item
|
||||
*
|
||||
* @param item
|
||||
*/
|
||||
public getOrcidAuthorizationScopesByItem(item: Item): string[] {
|
||||
return isNotEmpty(item) ? item.allMetadataValues('dspace.orcid.scope') : [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Return all orcid authorization scopes available by configuration
|
||||
*/
|
||||
public getOrcidAuthorizationScopes(): Observable<string[]> {
|
||||
return this.configurationService.findByPropertyName('orcid.scope').pipe(
|
||||
getFirstCompletedRemoteData(),
|
||||
map((propertyRD: RemoteData<ConfigurationProperty>) => propertyRD.hasSucceeded ? propertyRD.payload.values : [])
|
||||
);
|
||||
}
|
||||
|
||||
private getOrcidDisconnectionAllowedUsersConfiguration(): Observable<RemoteData<ConfigurationProperty>> {
|
||||
return this.configurationService.findByPropertyName('orcid.disconnection.allowed-users').pipe(
|
||||
getFirstCompletedRemoteData()
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -9,7 +9,7 @@ import { of } from 'rxjs';
|
||||
import { TestScheduler } from 'rxjs/testing';
|
||||
import { TranslateLoader, TranslateModule } from '@ngx-translate/core';
|
||||
|
||||
import { ResearcherProfileService } from '../../../core/profile/researcher-profile.service';
|
||||
import { OrcidAuthService } from '../../../core/orcid/orcid-auth.service';
|
||||
import { createFailedRemoteDataObject$, createSuccessfulRemoteDataObject$ } from '../../../shared/remote-data.utils';
|
||||
import { Item } from '../../../core/shared/item.model';
|
||||
import { createPaginatedList } from '../../../shared/testing/utils.test';
|
||||
@@ -25,7 +25,7 @@ describe('OrcidAuthComponent test suite', () => {
|
||||
let comp: OrcidAuthComponent;
|
||||
let fixture: ComponentFixture<OrcidAuthComponent>;
|
||||
let scheduler: TestScheduler;
|
||||
let researcherProfileService: jasmine.SpyObj<ResearcherProfileService>;
|
||||
let orcidAuthService: jasmine.SpyObj<OrcidAuthService>;
|
||||
let nativeWindowRef;
|
||||
let notificationsService;
|
||||
|
||||
@@ -112,7 +112,7 @@ describe('OrcidAuthComponent test suite', () => {
|
||||
});
|
||||
|
||||
beforeEach(waitForAsync(() => {
|
||||
researcherProfileService = jasmine.createSpyObj('researcherProfileService', {
|
||||
orcidAuthService = jasmine.createSpyObj('researcherProfileService', {
|
||||
getOrcidAuthorizationScopes: jasmine.createSpy('getOrcidAuthorizationScopes'),
|
||||
getOrcidAuthorizationScopesByItem: jasmine.createSpy('getOrcidAuthorizationScopesByItem'),
|
||||
getOrcidAuthorizeUrl: jasmine.createSpy('getOrcidAuthorizeUrl'),
|
||||
@@ -137,7 +137,7 @@ describe('OrcidAuthComponent test suite', () => {
|
||||
providers: [
|
||||
{ provide: NativeWindowService, useFactory: NativeWindowMockFactory },
|
||||
{ provide: NotificationsService, useClass: NotificationsServiceStub },
|
||||
{ provide: ResearcherProfileService, useValue: researcherProfileService }
|
||||
{ provide: OrcidAuthService, useValue: orcidAuthService }
|
||||
],
|
||||
schemas: [NO_ERRORS_SCHEMA]
|
||||
}).overrideComponent(OrcidAuthComponent, {
|
||||
@@ -149,17 +149,17 @@ describe('OrcidAuthComponent test suite', () => {
|
||||
scheduler = getTestScheduler();
|
||||
fixture = TestBed.createComponent(OrcidAuthComponent);
|
||||
comp = fixture.componentInstance;
|
||||
researcherProfileService.getOrcidAuthorizationScopes.and.returnValue(of(orcidScopes));
|
||||
orcidAuthService.getOrcidAuthorizationScopes.and.returnValue(of(orcidScopes));
|
||||
}));
|
||||
|
||||
describe('when orcid profile is not linked', () => {
|
||||
beforeEach(waitForAsync(() => {
|
||||
comp.item = mockItemUnlinkedToOrcid;
|
||||
researcherProfileService.getOrcidAuthorizationScopesByItem.and.returnValue([]);
|
||||
researcherProfileService.isLinkedToOrcid.and.returnValue(false);
|
||||
researcherProfileService.onlyAdminCanDisconnectProfileFromOrcid.and.returnValue(of(false));
|
||||
researcherProfileService.ownerCanDisconnectProfileFromOrcid.and.returnValue(of(true));
|
||||
researcherProfileService.getOrcidAuthorizeUrl.and.returnValue(of('oarcidUrl'));
|
||||
orcidAuthService.getOrcidAuthorizationScopesByItem.and.returnValue([]);
|
||||
orcidAuthService.isLinkedToOrcid.and.returnValue(false);
|
||||
orcidAuthService.onlyAdminCanDisconnectProfileFromOrcid.and.returnValue(of(false));
|
||||
orcidAuthService.ownerCanDisconnectProfileFromOrcid.and.returnValue(of(true));
|
||||
orcidAuthService.getOrcidAuthorizeUrl.and.returnValue(of('oarcidUrl'));
|
||||
fixture.detectChanges();
|
||||
}));
|
||||
|
||||
@@ -183,7 +183,7 @@ describe('OrcidAuthComponent test suite', () => {
|
||||
describe('when orcid profile is linked', () => {
|
||||
beforeEach(waitForAsync(() => {
|
||||
comp.item = mockItemLinkedToOrcid;
|
||||
researcherProfileService.isLinkedToOrcid.and.returnValue(true);
|
||||
orcidAuthService.isLinkedToOrcid.and.returnValue(true);
|
||||
}));
|
||||
|
||||
describe('', () => {
|
||||
@@ -191,16 +191,16 @@ describe('OrcidAuthComponent test suite', () => {
|
||||
beforeEach(waitForAsync(() => {
|
||||
comp.item = mockItemLinkedToOrcid;
|
||||
notificationsService = (comp as any).notificationsService;
|
||||
researcherProfileService.getOrcidAuthorizationScopesByItem.and.returnValue([...orcidScopes]);
|
||||
researcherProfileService.isLinkedToOrcid.and.returnValue(true);
|
||||
researcherProfileService.onlyAdminCanDisconnectProfileFromOrcid.and.returnValue(of(false));
|
||||
researcherProfileService.ownerCanDisconnectProfileFromOrcid.and.returnValue(of(true));
|
||||
orcidAuthService.getOrcidAuthorizationScopesByItem.and.returnValue([...orcidScopes]);
|
||||
orcidAuthService.isLinkedToOrcid.and.returnValue(true);
|
||||
orcidAuthService.onlyAdminCanDisconnectProfileFromOrcid.and.returnValue(of(false));
|
||||
orcidAuthService.ownerCanDisconnectProfileFromOrcid.and.returnValue(of(true));
|
||||
}));
|
||||
|
||||
describe('and unlink is successfully', () => {
|
||||
beforeEach(waitForAsync(() => {
|
||||
comp.item = mockItemLinkedToOrcid;
|
||||
researcherProfileService.unlinkOrcidByItem.and.returnValue(createSuccessfulRemoteDataObject$(new ResearcherProfile()));
|
||||
orcidAuthService.unlinkOrcidByItem.and.returnValue(createSuccessfulRemoteDataObject$(new ResearcherProfile()));
|
||||
spyOn(comp.unlink, 'emit');
|
||||
fixture.detectChanges();
|
||||
}));
|
||||
@@ -217,7 +217,7 @@ describe('OrcidAuthComponent test suite', () => {
|
||||
describe('and unlink is failed', () => {
|
||||
beforeEach(waitForAsync(() => {
|
||||
comp.item = mockItemLinkedToOrcid;
|
||||
researcherProfileService.unlinkOrcidByItem.and.returnValue(createFailedRemoteDataObject$());
|
||||
orcidAuthService.unlinkOrcidByItem.and.returnValue(createFailedRemoteDataObject$());
|
||||
fixture.detectChanges();
|
||||
}));
|
||||
|
||||
@@ -234,10 +234,10 @@ describe('OrcidAuthComponent test suite', () => {
|
||||
|
||||
beforeEach(waitForAsync(() => {
|
||||
comp.item = mockItemLinkedToOrcid;
|
||||
researcherProfileService.getOrcidAuthorizationScopesByItem.and.returnValue([...orcidScopes]);
|
||||
researcherProfileService.isLinkedToOrcid.and.returnValue(true);
|
||||
researcherProfileService.onlyAdminCanDisconnectProfileFromOrcid.and.returnValue(of(false));
|
||||
researcherProfileService.ownerCanDisconnectProfileFromOrcid.and.returnValue(of(true));
|
||||
orcidAuthService.getOrcidAuthorizationScopesByItem.and.returnValue([...orcidScopes]);
|
||||
orcidAuthService.isLinkedToOrcid.and.returnValue(true);
|
||||
orcidAuthService.onlyAdminCanDisconnectProfileFromOrcid.and.returnValue(of(false));
|
||||
orcidAuthService.ownerCanDisconnectProfileFromOrcid.and.returnValue(of(true));
|
||||
fixture.detectChanges();
|
||||
}));
|
||||
|
||||
@@ -263,10 +263,10 @@ describe('OrcidAuthComponent test suite', () => {
|
||||
|
||||
beforeEach(waitForAsync(() => {
|
||||
comp.item = mockItemLinkedToOrcid;
|
||||
researcherProfileService.getOrcidAuthorizationScopesByItem.and.returnValue([...partialOrcidScopes]);
|
||||
researcherProfileService.isLinkedToOrcid.and.returnValue(true);
|
||||
researcherProfileService.onlyAdminCanDisconnectProfileFromOrcid.and.returnValue(of(false));
|
||||
researcherProfileService.ownerCanDisconnectProfileFromOrcid.and.returnValue(of(true));
|
||||
orcidAuthService.getOrcidAuthorizationScopesByItem.and.returnValue([...partialOrcidScopes]);
|
||||
orcidAuthService.isLinkedToOrcid.and.returnValue(true);
|
||||
orcidAuthService.onlyAdminCanDisconnectProfileFromOrcid.and.returnValue(of(false));
|
||||
orcidAuthService.ownerCanDisconnectProfileFromOrcid.and.returnValue(of(true));
|
||||
fixture.detectChanges();
|
||||
}));
|
||||
|
||||
@@ -294,10 +294,10 @@ describe('OrcidAuthComponent test suite', () => {
|
||||
|
||||
beforeEach(waitForAsync(() => {
|
||||
comp.item = mockItemLinkedToOrcid;
|
||||
researcherProfileService.getOrcidAuthorizationScopesByItem.and.returnValue([...orcidScopes]);
|
||||
researcherProfileService.isLinkedToOrcid.and.returnValue(true);
|
||||
researcherProfileService.onlyAdminCanDisconnectProfileFromOrcid.and.returnValue(of(true));
|
||||
researcherProfileService.ownerCanDisconnectProfileFromOrcid.and.returnValue(of(false));
|
||||
orcidAuthService.getOrcidAuthorizationScopesByItem.and.returnValue([...orcidScopes]);
|
||||
orcidAuthService.isLinkedToOrcid.and.returnValue(true);
|
||||
orcidAuthService.onlyAdminCanDisconnectProfileFromOrcid.and.returnValue(of(true));
|
||||
orcidAuthService.ownerCanDisconnectProfileFromOrcid.and.returnValue(of(false));
|
||||
fixture.detectChanges();
|
||||
}));
|
||||
|
||||
@@ -314,10 +314,10 @@ describe('OrcidAuthComponent test suite', () => {
|
||||
|
||||
beforeEach(waitForAsync(() => {
|
||||
comp.item = mockItemLinkedToOrcid;
|
||||
researcherProfileService.getOrcidAuthorizationScopesByItem.and.returnValue([...orcidScopes]);
|
||||
researcherProfileService.isLinkedToOrcid.and.returnValue(true);
|
||||
researcherProfileService.onlyAdminCanDisconnectProfileFromOrcid.and.returnValue(of(true));
|
||||
researcherProfileService.ownerCanDisconnectProfileFromOrcid.and.returnValue(of(true));
|
||||
orcidAuthService.getOrcidAuthorizationScopesByItem.and.returnValue([...orcidScopes]);
|
||||
orcidAuthService.isLinkedToOrcid.and.returnValue(true);
|
||||
orcidAuthService.onlyAdminCanDisconnectProfileFromOrcid.and.returnValue(of(true));
|
||||
orcidAuthService.ownerCanDisconnectProfileFromOrcid.and.returnValue(of(true));
|
||||
fixture.detectChanges();
|
||||
}));
|
||||
|
||||
|
@@ -3,14 +3,13 @@ import { Component, EventEmitter, Inject, Input, OnChanges, OnInit, Output, Simp
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { BehaviorSubject, Observable } from 'rxjs';
|
||||
import { map } from 'rxjs/operators';
|
||||
|
||||
import { ResearcherProfileService } from '../../../core/profile/researcher-profile.service';
|
||||
import { NativeWindowRef, NativeWindowService } from '../../../core/services/window.service';
|
||||
import { Item } from '../../../core/shared/item.model';
|
||||
import { NotificationsService } from '../../../shared/notifications/notifications.service';
|
||||
import { RemoteData } from '../../../core/data/remote-data';
|
||||
import { ResearcherProfile } from '../../../core/profile/model/researcher-profile.model';
|
||||
import { getFirstCompletedRemoteData } from '../../../core/shared/operators';
|
||||
import { OrcidAuthService } from '../../../core/orcid/orcid-auth.service';
|
||||
|
||||
@Component({
|
||||
selector: 'ds-orcid-auth',
|
||||
@@ -65,7 +64,7 @@ export class OrcidAuthComponent implements OnInit, OnChanges {
|
||||
@Output() unlink: EventEmitter<void> = new EventEmitter<void>();
|
||||
|
||||
constructor(
|
||||
private researcherProfileService: ResearcherProfileService,
|
||||
private orcidAuthService: OrcidAuthService,
|
||||
private translateService: TranslateService,
|
||||
private notificationsService: NotificationsService,
|
||||
@Inject(NativeWindowService) private _window: NativeWindowRef,
|
||||
@@ -73,7 +72,7 @@ export class OrcidAuthComponent implements OnInit, OnChanges {
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
this.researcherProfileService.getOrcidAuthorizationScopes().subscribe((scopes: string[]) => {
|
||||
this.orcidAuthService.getOrcidAuthorizationScopes().subscribe((scopes: string[]) => {
|
||||
this.orcidAuthorizationScopes.next(scopes);
|
||||
this.initOrcidAuthSettings();
|
||||
});
|
||||
@@ -160,7 +159,7 @@ export class OrcidAuthComponent implements OnInit, OnChanges {
|
||||
* Link existing person profile with orcid
|
||||
*/
|
||||
linkOrcid(): void {
|
||||
this.researcherProfileService.getOrcidAuthorizeUrl(this.item).subscribe((authorizeUrl) => {
|
||||
this.orcidAuthService.getOrcidAuthorizeUrl(this.item).subscribe((authorizeUrl) => {
|
||||
this._window.nativeWindow.location.href = authorizeUrl;
|
||||
});
|
||||
}
|
||||
@@ -170,7 +169,7 @@ export class OrcidAuthComponent implements OnInit, OnChanges {
|
||||
*/
|
||||
unlinkOrcid(): void {
|
||||
this.unlinkProcessing.next(true);
|
||||
this.researcherProfileService.unlinkOrcidByItem(this.item).pipe(
|
||||
this.orcidAuthService.unlinkOrcidByItem(this.item).pipe(
|
||||
getFirstCompletedRemoteData()
|
||||
).subscribe((remoteData: RemoteData<ResearcherProfile>) => {
|
||||
this.unlinkProcessing.next(false);
|
||||
@@ -193,19 +192,19 @@ export class OrcidAuthComponent implements OnInit, OnChanges {
|
||||
|
||||
this.setMissingOrcidAuthorizations();
|
||||
|
||||
this.researcherProfileService.onlyAdminCanDisconnectProfileFromOrcid().subscribe((result) => {
|
||||
this.orcidAuthService.onlyAdminCanDisconnectProfileFromOrcid().subscribe((result) => {
|
||||
this.onlyAdminCanDisconnectProfileFromOrcid$.next(result);
|
||||
});
|
||||
|
||||
this.researcherProfileService.ownerCanDisconnectProfileFromOrcid().subscribe((result) => {
|
||||
this.orcidAuthService.ownerCanDisconnectProfileFromOrcid().subscribe((result) => {
|
||||
this.ownerCanDisconnectProfileFromOrcid$.next(result);
|
||||
});
|
||||
|
||||
this.isOrcidLinked$.next(this.researcherProfileService.isLinkedToOrcid(this.item));
|
||||
this.isOrcidLinked$.next(this.orcidAuthService.isLinkedToOrcid(this.item));
|
||||
}
|
||||
|
||||
private setMissingOrcidAuthorizations(): void {
|
||||
const profileScopes = this.researcherProfileService.getOrcidAuthorizationScopesByItem(this.item);
|
||||
const profileScopes = this.orcidAuthService.getOrcidAuthorizationScopesByItem(this.item);
|
||||
const orcidScopes = this.orcidAuthorizationScopes.value;
|
||||
const missingScopes = orcidScopes.filter((scope) => !profileScopes.includes(scope));
|
||||
|
||||
@@ -213,7 +212,7 @@ export class OrcidAuthComponent implements OnInit, OnChanges {
|
||||
}
|
||||
|
||||
private setOrcidAuthorizationsFromItem(): void {
|
||||
this.profileAuthorizationScopes.next(this.researcherProfileService.getOrcidAuthorizationScopesByItem(this.item));
|
||||
this.profileAuthorizationScopes.next(this.orcidAuthService.getOrcidAuthorizationScopesByItem(this.item));
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -11,7 +11,6 @@ import { getTestScheduler } from 'jasmine-marbles';
|
||||
|
||||
import { AuthService } from '../../core/auth/auth.service';
|
||||
import { ActivatedRouteStub } from '../../shared/testing/active-router.stub';
|
||||
import { ResearcherProfileService } from '../../core/profile/researcher-profile.service';
|
||||
import { OrcidPageComponent } from './orcid-page.component';
|
||||
import {
|
||||
createFailedRemoteDataObject$,
|
||||
@@ -23,6 +22,7 @@ import { createPaginatedList } from '../../shared/testing/utils.test';
|
||||
import { TranslateLoaderMock } from '../../shared/mocks/translate-loader.mock';
|
||||
import { ItemDataService } from '../../core/data/item-data.service';
|
||||
import { ResearcherProfile } from '../../core/profile/model/researcher-profile.model';
|
||||
import { OrcidAuthService } from '../../core/orcid/orcid-auth.service';
|
||||
|
||||
describe('OrcidPageComponent test suite', () => {
|
||||
let comp: OrcidPageComponent;
|
||||
@@ -32,7 +32,7 @@ describe('OrcidPageComponent test suite', () => {
|
||||
let routeStub: jasmine.SpyObj<ActivatedRouteStub>;
|
||||
let routeData: any;
|
||||
let itemDataService: jasmine.SpyObj<ItemDataService>;
|
||||
let researcherProfileService: jasmine.SpyObj<ResearcherProfileService>;
|
||||
let orcidAuthService: jasmine.SpyObj<OrcidAuthService>;
|
||||
|
||||
const mockResearcherProfile: ResearcherProfile = Object.assign(new ResearcherProfile(), {
|
||||
id: 'test-id',
|
||||
@@ -88,7 +88,7 @@ describe('OrcidPageComponent test suite', () => {
|
||||
|
||||
routeStub = new ActivatedRouteStub({}, routeData);
|
||||
|
||||
researcherProfileService = jasmine.createSpyObj('researcherProfileService', {
|
||||
orcidAuthService = jasmine.createSpyObj('OrcidAuthService', {
|
||||
isLinkedToOrcid: jasmine.createSpy('isLinkedToOrcid'),
|
||||
linkOrcidByItem: jasmine.createSpy('linkOrcidByItem'),
|
||||
});
|
||||
@@ -110,7 +110,7 @@ describe('OrcidPageComponent test suite', () => {
|
||||
declarations: [OrcidPageComponent],
|
||||
providers: [
|
||||
{ provide: ActivatedRoute, useValue: routeStub },
|
||||
{ provide: ResearcherProfileService, useValue: researcherProfileService },
|
||||
{ provide: OrcidAuthService, useValue: orcidAuthService },
|
||||
{ provide: AuthService, useValue: authService },
|
||||
{ provide: ItemDataService, useValue: itemDataService },
|
||||
{ provide: PLATFORM_ID, useValue: 'browser' },
|
||||
@@ -146,7 +146,7 @@ describe('OrcidPageComponent test suite', () => {
|
||||
it('should call isLinkedToOrcid', () => {
|
||||
comp.isLinkedToOrcid();
|
||||
|
||||
expect(researcherProfileService.isLinkedToOrcid).toHaveBeenCalledWith(comp.item.value);
|
||||
expect(orcidAuthService.isLinkedToOrcid).toHaveBeenCalledWith(comp.item.value);
|
||||
});
|
||||
|
||||
it('should update item', fakeAsync(() => {
|
||||
@@ -168,13 +168,13 @@ describe('OrcidPageComponent test suite', () => {
|
||||
|
||||
describe('and linking to orcid profile is successfully', () => {
|
||||
beforeEach(waitForAsync(() => {
|
||||
researcherProfileService.linkOrcidByItem.and.returnValue(createSuccessfulRemoteDataObject$(mockResearcherProfile));
|
||||
orcidAuthService.linkOrcidByItem.and.returnValue(createSuccessfulRemoteDataObject$(mockResearcherProfile));
|
||||
itemDataService.findById.and.returnValue(createSuccessfulRemoteDataObject$(mockItemLinkedToOrcid));
|
||||
fixture.detectChanges();
|
||||
}));
|
||||
|
||||
it('should call linkOrcidByItem', () => {
|
||||
expect(researcherProfileService.linkOrcidByItem).toHaveBeenCalledWith(mockItem, 'orcid-code');
|
||||
expect(orcidAuthService.linkOrcidByItem).toHaveBeenCalledWith(mockItem, 'orcid-code');
|
||||
expect(comp.updateItem).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
@@ -193,13 +193,13 @@ describe('OrcidPageComponent test suite', () => {
|
||||
|
||||
describe('and linking to orcid profile is failed', () => {
|
||||
beforeEach(waitForAsync(() => {
|
||||
researcherProfileService.linkOrcidByItem.and.returnValue(createFailedRemoteDataObject$());
|
||||
orcidAuthService.linkOrcidByItem.and.returnValue(createFailedRemoteDataObject$());
|
||||
itemDataService.findById.and.returnValue(createSuccessfulRemoteDataObject$(mockItemLinkedToOrcid));
|
||||
fixture.detectChanges();
|
||||
}));
|
||||
|
||||
it('should call linkOrcidByItem', () => {
|
||||
expect(researcherProfileService.linkOrcidByItem).toHaveBeenCalledWith(mockItem, 'orcid-code');
|
||||
expect(orcidAuthService.linkOrcidByItem).toHaveBeenCalledWith(mockItem, 'orcid-code');
|
||||
expect(comp.updateItem).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
|
@@ -1,10 +1,11 @@
|
||||
import { Component, Inject, OnInit, PLATFORM_ID } from '@angular/core';
|
||||
import { ActivatedRoute, ParamMap, Router } from '@angular/router';
|
||||
import { isPlatformBrowser } from '@angular/common';
|
||||
|
||||
import { BehaviorSubject, combineLatest } from 'rxjs';
|
||||
import { map, take } from 'rxjs/operators';
|
||||
|
||||
import { ResearcherProfileService } from '../../core/profile/researcher-profile.service';
|
||||
import { OrcidAuthService } from '../../core/orcid/orcid-auth.service';
|
||||
import { getFirstCompletedRemoteData, getFirstSucceededRemoteDataPayload } from '../../core/shared/operators';
|
||||
import { RemoteData } from '../../core/data/remote-data';
|
||||
import { Item } from '../../core/shared/item.model';
|
||||
@@ -14,7 +15,6 @@ import { redirectOn4xx } from '../../core/shared/authorized.operators';
|
||||
import { ItemDataService } from '../../core/data/item-data.service';
|
||||
import { isNotEmpty } from '../../shared/empty.util';
|
||||
import { ResearcherProfile } from '../../core/profile/model/researcher-profile.model';
|
||||
import { isPlatformBrowser } from '@angular/common';
|
||||
|
||||
/**
|
||||
* A component that represents the orcid settings page
|
||||
@@ -50,7 +50,7 @@ export class OrcidPageComponent implements OnInit {
|
||||
@Inject(PLATFORM_ID) private platformId: any,
|
||||
private authService: AuthService,
|
||||
private itemService: ItemDataService,
|
||||
private researcherProfileService: ResearcherProfileService,
|
||||
private orcidAuthService: OrcidAuthService,
|
||||
private route: ActivatedRoute,
|
||||
private router: Router
|
||||
) {
|
||||
@@ -95,7 +95,7 @@ export class OrcidPageComponent implements OnInit {
|
||||
* @returns the check result
|
||||
*/
|
||||
isLinkedToOrcid(): boolean {
|
||||
return this.researcherProfileService.isLinkedToOrcid(this.item.value);
|
||||
return this.orcidAuthService.isLinkedToOrcid(this.item.value);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -126,7 +126,7 @@ export class OrcidPageComponent implements OnInit {
|
||||
* @param code The auth-code received from ORCID
|
||||
*/
|
||||
private linkProfileToOrcid(person: Item, code: string) {
|
||||
this.researcherProfileService.linkOrcidByItem(person, code).pipe(
|
||||
this.orcidAuthService.linkOrcidByItem(person, code).pipe(
|
||||
getFirstCompletedRemoteData()
|
||||
).subscribe((profileRD: RemoteData<ResearcherProfile>) => {
|
||||
this.processingConnection.next(false);
|
||||
|
@@ -16,13 +16,14 @@ import { createPaginatedList } from '../../../shared/testing/utils.test';
|
||||
import { PaginatedList } from '../../../core/data/paginated-list.model';
|
||||
import { By } from '@angular/platform-browser';
|
||||
import { Item } from '../../../core/shared/item.model';
|
||||
|
||||
import { OrcidAuthService } from '../../../core/orcid/orcid-auth.service';
|
||||
|
||||
describe('OrcidQueueComponent test suite', () => {
|
||||
let component: OrcidQueueComponent;
|
||||
let fixture: ComponentFixture<OrcidQueueComponent>;
|
||||
let debugElement: DebugElement;
|
||||
let orcidQueueService: OrcidQueueService;
|
||||
let orcidAuthService: jasmine.SpyObj<OrcidAuthService>;
|
||||
|
||||
const testOwnerId = 'test-owner-id';
|
||||
|
||||
@@ -102,6 +103,10 @@ describe('OrcidQueueComponent test suite', () => {
|
||||
orcidQueueServiceSpy.searchByOwnerId.and.returnValue(createSuccessfulRemoteDataObject$<PaginatedList<OrcidQueue>>(createPaginatedList<OrcidQueue>(orcidQueueElements)));
|
||||
|
||||
beforeEach(waitForAsync(() => {
|
||||
orcidAuthService = jasmine.createSpyObj('OrcidAuthService', {
|
||||
getOrcidAuthorizeUrl: jasmine.createSpy('getOrcidAuthorizeUrl')
|
||||
});
|
||||
|
||||
void TestBed.configureTestingModule({
|
||||
imports: [
|
||||
TranslateModule.forRoot({
|
||||
@@ -114,6 +119,7 @@ describe('OrcidQueueComponent test suite', () => {
|
||||
],
|
||||
declarations: [OrcidQueueComponent],
|
||||
providers: [
|
||||
{ provide: OrcidAuthService, useValue: orcidAuthService },
|
||||
{ provide: OrcidQueueService, useValue: orcidQueueServiceSpy },
|
||||
{ provide: OrcidHistoryDataService, useValue: {} },
|
||||
{ provide: PaginationService, useValue: new PaginationServiceStub() },
|
||||
|
@@ -17,6 +17,7 @@ import { NotificationsService } from '../../../shared/notifications/notification
|
||||
import { PaginationComponentOptions } from '../../../shared/pagination/pagination-component-options.model';
|
||||
import { AlertType } from '../../../shared/alert/aletr-type';
|
||||
import { Item } from '../../../core/shared/item.model';
|
||||
import { OrcidAuthService } from '../../../core/orcid/orcid-auth.service';
|
||||
|
||||
@Component({
|
||||
selector: 'ds-orcid-queue',
|
||||
@@ -60,7 +61,8 @@ export class OrcidQueueComponent implements OnInit, OnDestroy {
|
||||
*/
|
||||
private subs: Subscription[] = [];
|
||||
|
||||
constructor(private orcidQueueService: OrcidQueueService,
|
||||
constructor(private orcidAuthService: OrcidAuthService,
|
||||
private orcidQueueService: OrcidQueueService,
|
||||
protected translateService: TranslateService,
|
||||
private paginationService: PaginationService,
|
||||
private notificationsService: NotificationsService,
|
||||
@@ -228,8 +230,11 @@ export class OrcidQueueComponent implements OnInit, OnDestroy {
|
||||
* @private
|
||||
*/
|
||||
private getUnauthorizedErrorContent(): Observable<string> {
|
||||
return this.orcidQueueService.getOrcidAuthorizeUrl(this.item.id).pipe(
|
||||
switchMap((authorizeUrl) => this.translateService.get('person.page.orcid.sync-queue.send.unauthorized-error.content', { orcid: authorizeUrl }))
|
||||
return this.orcidAuthService.getOrcidAuthorizeUrl(this.item).pipe(
|
||||
switchMap((authorizeUrl) => this.translateService.get(
|
||||
'person.page.orcid.sync-queue.send.unauthorized-error.content',
|
||||
{ orcid: authorizeUrl }
|
||||
))
|
||||
);
|
||||
}
|
||||
|
||||
@@ -246,24 +251,24 @@ export class OrcidQueueComponent implements OnInit, OnDestroy {
|
||||
this.updateList();
|
||||
break;
|
||||
case 400:
|
||||
this.notificationsService.error(this.translateService.get('person.page.orcid.sync-queue.send.bad-request-error'), null, { timeOut: -1 });
|
||||
this.notificationsService.error(this.translateService.get('person.page.orcid.sync-queue.send.bad-request-error'), null, { timeOut: 0 });
|
||||
break;
|
||||
case 401:
|
||||
combineLatest([
|
||||
this.translateService.get('person.page.orcid.sync-queue.send.unauthorized-error.title'),
|
||||
this.getUnauthorizedErrorContent()],
|
||||
).subscribe(([title, content]) => {
|
||||
this.notificationsService.error(title, content, { timeOut: -1 }, true);
|
||||
this.notificationsService.error(title, content, { timeOut: 0 }, true);
|
||||
});
|
||||
break;
|
||||
case 404:
|
||||
this.notificationsService.warning(this.translateService.get('person.page.orcid.sync-queue.send.not-found-warning'));
|
||||
break;
|
||||
case 409:
|
||||
this.notificationsService.error(this.translateService.get('person.page.orcid.sync-queue.send.conflict-error'), null, { timeOut: -1 });
|
||||
this.notificationsService.error(this.translateService.get('person.page.orcid.sync-queue.send.conflict-error'), null, { timeOut: 0 });
|
||||
break;
|
||||
default:
|
||||
this.notificationsService.error(this.translateService.get('person.page.orcid.sync-queue.send.error'), null, { timeOut: -1 });
|
||||
this.notificationsService.error(this.translateService.get('person.page.orcid.sync-queue.send.error'), null, { timeOut: 0 });
|
||||
}
|
||||
}
|
||||
|
||||
@@ -281,11 +286,10 @@ export class OrcidQueueComponent implements OnInit, OnDestroy {
|
||||
combineLatest(translations).subscribe((messages) => {
|
||||
const title = messages.shift();
|
||||
const content = '<ul>' + messages.map((message) => `<li>${message}</li>`).join('') + '</ul>';
|
||||
this.notificationsService.error(title, content, { timeOut: -1 }, true);
|
||||
this.notificationsService.error(title, content, { timeOut: 0 }, true);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Unsubscribe from all subscriptions
|
||||
*/
|
||||
|
Reference in New Issue
Block a user