From 4aa936bb9c098c5fccffe706f87668a09a324fa4 Mon Sep 17 00:00:00 2001 From: Denys Vuika Date: Wed, 12 Aug 2020 13:45:48 +0100 Subject: [PATCH] use people api and new js api where possible (#5888) * use people api and new js api where possible * fix code and tests * cleanup tests --- .../property-groups-translator.service.ts | 6 +- .../document-list.component.spec.ts | 45 +++++----- .../services/custom-resources.service.spec.ts | 15 ++-- .../services/custom-resources.service.ts | 88 +++++++++++++------ lib/core/services/ecm-user.service.spec.ts | 53 +++-------- lib/core/services/ecm-user.service.ts | 38 +++----- .../core/actions/identity/identity.service.ts | 9 +- 7 files changed, 119 insertions(+), 135 deletions(-) diff --git a/lib/content-services/src/lib/content-metadata/services/property-groups-translator.service.ts b/lib/content-services/src/lib/content-metadata/services/property-groups-translator.service.ts index 551aba3c92..68713f1969 100644 --- a/lib/content-services/src/lib/content-metadata/services/property-groups-translator.service.ts +++ b/lib/content-services/src/lib/content-metadata/services/property-groups-translator.service.ts @@ -76,7 +76,7 @@ export class PropertyGroupTranslatorService { } private translate(property: Property, propertyValues: any, constraints: Constraint[]): CardViewItem { - let propertyValue; + let propertyValue: any; if (propertyValues && propertyValues[property.name]) { propertyValue = propertyValues[property.name]; } @@ -94,7 +94,7 @@ export class PropertyGroupTranslatorService { constraints: constraints }; - let cardViewItemProperty; + let cardViewItemProperty: CardViewItem; if (this.isListOfValues(propertyDefinition.constraints)) { const options = propertyDefinition.constraints[0].parameters.allowedValues.map((value) => ({ key: value, label: value })); @@ -154,7 +154,7 @@ export class PropertyGroupTranslatorService { return definition?.properties.find((item) => item.id === propertyName)?.constraints ?? []; } - private checkECMTypeValidity(ecmPropertyType) { + private checkECMTypeValidity(ecmPropertyType: string) { if (PropertyGroupTranslatorService.RECOGNISED_ECM_TYPES.indexOf(ecmPropertyType) === -1) { this.logService.error(`Unknown type for mapping: ${ecmPropertyType}`); } diff --git a/lib/content-services/src/lib/document-list/components/document-list.component.spec.ts b/lib/content-services/src/lib/document-list/components/document-list.component.spec.ts index 2c9ba0284e..4ccdaf9341 100644 --- a/lib/content-services/src/lib/document-list/components/document-list.component.spec.ts +++ b/lib/content-services/src/lib/document-list/components/document-list.component.spec.ts @@ -74,14 +74,14 @@ describe('DocumentList', () => { beforeEach(() => { eventMock = { - preventDefault: function () { - } + preventDefault: function () {} }; fixture = TestBed.createComponent(DocumentListComponent); element = fixture.nativeElement; documentList = fixture.componentInstance; + documentListService = TestBed.inject(DocumentListService); apiService = TestBed.inject(AlfrescoApiService); customResourcesService = TestBed.inject(CustomResourcesService); @@ -101,8 +101,8 @@ describe('DocumentList', () => { documentList.ngOnInit(); documentList.currentFolderId = 'no-node'; - spyGetSites = spyOn(apiService.sitesApi, 'getSites').and.returnValue(Promise.resolve(fakeGetSitesAnswer)); - spyFavorite = spyOn(apiService.favoritesApi, 'getFavorites').and.returnValue(Promise.resolve({ list: { entries: [] } })); + spyGetSites = spyOn(customResourcesService.sitesApi, 'listSites').and.returnValue(Promise.resolve(fakeGetSitesAnswer)); + spyFavorite = spyOn(customResourcesService.favoritesApi, 'listFavorites').and.returnValue(Promise.resolve({ list: { entries: [] } })); }); afterEach(() => { @@ -1287,15 +1287,16 @@ describe('DocumentList', () => { }); it('should fetch trashcan', () => { - spyOn(apiService.nodesApi, 'getDeletedNodes').and.returnValue(Promise.resolve(null)); + const trashcanApi = customResourcesService.trashcanApi; + spyOn(trashcanApi, 'listDeletedNodes').and.returnValue(Promise.resolve(null)); documentList.currentFolderId = '-trashcan-'; documentList.loadFolder(); - expect(apiService.nodesApi.getDeletedNodes).toHaveBeenCalled(); + expect(trashcanApi.listDeletedNodes).toHaveBeenCalled(); }); it('should emit error when fetch trashcan fails', (done) => { - spyOn(apiService.nodesApi, 'getDeletedNodes').and.returnValue(Promise.reject('error')); + spyOn(customResourcesService.trashcanApi, 'listDeletedNodes').and.returnValue(Promise.reject('error')); const disposableError = documentList.error.subscribe((val) => { expect(val).toBe('error'); @@ -1308,17 +1309,16 @@ describe('DocumentList', () => { }); it('should fetch shared links', () => { - const sharedlinksApi = apiService.getInstance().core.sharedlinksApi; - spyOn(sharedlinksApi, 'findSharedLinks').and.returnValue(Promise.resolve(null)); + const sharedlinksApi = customResourcesService.sharedLinksApi; + spyOn(sharedlinksApi, 'listSharedLinks').and.returnValue(Promise.resolve(null)); documentList.currentFolderId = '-sharedlinks-'; documentList.loadFolder(); - expect(sharedlinksApi.findSharedLinks).toHaveBeenCalled(); + expect(sharedlinksApi.listSharedLinks).toHaveBeenCalled(); }); it('should emit error when fetch shared links fails', (done) => { - spyOn(apiService.getInstance().core.sharedlinksApi, 'findSharedLinks') - .and.returnValue(Promise.reject('error')); + spyOn(customResourcesService.sharedLinksApi, 'listSharedLinks').and.returnValue(Promise.reject('error')); const disposableError = documentList.error.subscribe((val) => { expect(val).toBe('error'); @@ -1331,11 +1331,11 @@ describe('DocumentList', () => { }); it('should fetch sites', () => { - const sitesApi = apiService.getInstance().core.sitesApi; + const sitesApi = customResourcesService.sitesApi; documentList.currentFolderId = '-sites-'; documentList.loadFolder(); - expect(sitesApi.getSites).toHaveBeenCalled(); + expect(sitesApi.listSites).toHaveBeenCalled(); }); it('should emit error when fetch sites fails', (done) => { @@ -1352,17 +1352,16 @@ describe('DocumentList', () => { }); it('should fetch user membership sites', () => { - const peopleApi = apiService.getInstance().core.peopleApi; - spyOn(peopleApi, 'listSiteMembershipsForPerson').and.returnValue(Promise.resolve(fakeGetSiteMembership)); + const sitesApi = customResourcesService.sitesApi; + spyOn(sitesApi, 'listSiteMembershipsForPerson').and.returnValue(Promise.resolve(fakeGetSiteMembership)); documentList.currentFolderId = '-mysites-'; documentList.loadFolder(); - expect(peopleApi.listSiteMembershipsForPerson).toHaveBeenCalled(); + expect(sitesApi.listSiteMembershipsForPerson).toHaveBeenCalled(); }); it('should emit error when fetch membership sites fails', (done) => { - spyOn(apiService.getInstance().core.peopleApi, 'listSiteMembershipsForPerson') - .and.returnValue(Promise.reject('error')); + spyOn(customResourcesService.sitesApi, 'listSiteMembershipsForPerson').and.returnValue(Promise.reject('error')); const disposableError = documentList.error.subscribe((val) => { expect(val).toBe('error'); @@ -1375,11 +1374,11 @@ describe('DocumentList', () => { }); it('should fetch favorites', () => { - const favoritesApi = apiService.getInstance().core.favoritesApi; + const favoritesApi = customResourcesService.favoritesApi; documentList.currentFolderId = '-favorites-'; documentList.loadFolder(); - expect(favoritesApi.getFavorites).toHaveBeenCalled(); + expect(favoritesApi.listFavorites).toHaveBeenCalled(); }); it('should emit error when fetch favorites fails', (done) => { @@ -1410,9 +1409,7 @@ describe('DocumentList', () => { it('should have correct currentFolderId on loading folder by node id', () => { documentList.currentFolderId = '12345-some-id-6789'; - - const peopleApi = apiService.getInstance().core.peopleApi; - spyOn(peopleApi, 'listSiteMembershipsForPerson').and.returnValue(Promise.resolve(fakeGetSiteMembership)); + spyOn(customResourcesService.sitesApi, 'listSiteMembershipsForPerson').and.returnValue(Promise.resolve(fakeGetSiteMembership)); documentList.currentFolderId = '-mysites-'; documentList.loadFolder(); diff --git a/lib/content-services/src/lib/document-list/services/custom-resources.service.spec.ts b/lib/content-services/src/lib/document-list/services/custom-resources.service.spec.ts index 5532b5e78d..4219858680 100644 --- a/lib/content-services/src/lib/document-list/services/custom-resources.service.spec.ts +++ b/lib/content-services/src/lib/document-list/services/custom-resources.service.spec.ts @@ -19,19 +19,18 @@ import { CustomResourcesService } from './custom-resources.service'; import { PaginationModel, AlfrescoApiServiceMock, AppConfigService, LogService, AppConfigServiceMock, StorageService } from '@alfresco/adf-core'; describe('CustomResourcesService', () => { - let customActionService: CustomResourcesService; - let alfrescoApiService: AlfrescoApiServiceMock; + let customResourcesService: CustomResourcesService; beforeEach(() => { const logService = new LogService(new AppConfigServiceMock(null)); + const alfrescoApiService = new AlfrescoApiServiceMock(new AppConfigService(null), new StorageService()); - alfrescoApiService = new AlfrescoApiServiceMock(new AppConfigService(null), new StorageService()); - customActionService = new CustomResourcesService(alfrescoApiService, logService); + customResourcesService = new CustomResourcesService(alfrescoApiService, logService); }); describe('loadFavorites', () => { it('should return a list of items with default properties when target properties does not exist', (done) => { - spyOn(alfrescoApiService.favoritesApi, 'getFavorites').and.returnValue(Promise.resolve({ + spyOn(customResourcesService.favoritesApi, 'listFavorites').and.returnValue(Promise.resolve({ list: { entries: [ { @@ -52,7 +51,7 @@ describe('CustomResourcesService', () => { skipCount: 0 }; - customActionService.loadFavorites(pagination).subscribe((result) => { + customResourcesService.loadFavorites(pagination).subscribe((result) => { expect(result.list.entries).toEqual([ { entry: { @@ -70,7 +69,7 @@ describe('CustomResourcesService', () => { }); it('should return a list of items with merged properties when target properties exist', (done) => { - spyOn(alfrescoApiService.favoritesApi, 'getFavorites').and.returnValue(Promise.resolve({ + spyOn(customResourcesService.favoritesApi, 'listFavorites').and.returnValue(Promise.resolve({ list: { entries: [ { @@ -94,7 +93,7 @@ describe('CustomResourcesService', () => { skipCount: 0 }; - customActionService.loadFavorites(pagination).subscribe((result) => { + customResourcesService.loadFavorites(pagination).subscribe((result) => { expect(result.list.entries).toEqual([ { entry: { diff --git a/lib/content-services/src/lib/document-list/services/custom-resources.service.ts b/lib/content-services/src/lib/document-list/services/custom-resources.service.ts index 4e57074e88..7a08c0866d 100644 --- a/lib/content-services/src/lib/document-list/services/custom-resources.service.ts +++ b/lib/content-services/src/lib/document-list/services/custom-resources.service.ts @@ -15,36 +15,72 @@ * limitations under the License. */ -import { - AlfrescoApiService, - LogService, - PaginationModel -} from '@alfresco/adf-core'; - +import { AlfrescoApiService, LogService, PaginationModel } from '@alfresco/adf-core'; import { NodePaging, - PersonEntry, - SitePaging, DeletedNodesPaging, SearchRequest, SharedLinkPaging, FavoritePaging, SiteMemberPaging, - SiteRolePaging + SiteRolePaging, + PeopleApi, + SitesApi, + SearchApi, + FavoritesApi, + SharedlinksApi, + TrashcanApi, + NodesApi } from '@alfresco/js-api'; import { Injectable } from '@angular/core'; import { Observable, from, of, throwError } from 'rxjs'; import { catchError, map } from 'rxjs/operators'; -@Injectable({ - providedIn: 'root' -}) +@Injectable({ providedIn: 'root' }) export class CustomResourcesService { private CREATE_PERMISSION = 'create'; - constructor(private apiService: AlfrescoApiService, - private logService: LogService) { + private _peopleApi: PeopleApi; + private _sitesApi: SitesApi; + private _trashcanApi: TrashcanApi; + private _searchApi: SearchApi; + private _sharedLinksApi: SharedlinksApi; + private _favoritesApi: FavoritesApi; + private _nodesApi: NodesApi; + + constructor(private apiService: AlfrescoApiService, private logService: LogService) {} + + private get api() { + return this.apiService.getInstance(); + } + + get peopleApi(): PeopleApi { + return this._peopleApi || (this._peopleApi = new PeopleApi(this.api)); + } + + get sitesApi(): SitesApi { + return this._sitesApi || (this._sitesApi = new SitesApi(this.api)); + } + + get searchApi(): SearchApi { + return this._searchApi || (this._searchApi = new SearchApi(this.api)); + } + + get favoritesApi(): FavoritesApi { + return this._favoritesApi || (this._favoritesApi = new FavoritesApi(this.api)); + } + + get sharedLinksApi(): SharedlinksApi { + return this._sharedLinksApi || (this._sharedLinksApi = new SharedlinksApi(this.api)); + } + + get trashcanApi(): TrashcanApi { + return this._trashcanApi || (this._trashcanApi = new TrashcanApi(this.api)); + } + + get nodesApi(): NodesApi { + return this._nodesApi || (this._nodesApi = new NodesApi(this.api)); } /** @@ -79,8 +115,8 @@ export class CustomResourcesService { ]; return new Observable((observer) => { - this.apiService.peopleApi.getPerson(personId) - .then((person: PersonEntry) => { + this.peopleApi.getPerson(personId) + .then((person) => { const username = person.entry.id; const filterQueries = [ { query: `cm:modified:[NOW/DAY-30DAYS TO NOW/DAY+1DAY]` }, @@ -94,7 +130,7 @@ export class CustomResourcesService { }); } - const query: SearchRequest = new SearchRequest({ + const query = new SearchRequest({ query: { query: '*', language: 'afts' @@ -111,7 +147,7 @@ export class CustomResourcesService { skipCount: pagination.skipCount } }); - return this.apiService.searchApi.search(query) + return this.searchApi.search(query) .then((searchResult) => { observer.next(searchResult); observer.complete(); @@ -147,7 +183,7 @@ export class CustomResourcesService { }; return new Observable((observer) => { - this.apiService.favoritesApi.getFavorites('-me-', options) + this.favoritesApi.listFavorites('-me-', options) .then((result: FavoritePaging) => { const page: FavoritePaging = { list: { @@ -195,7 +231,7 @@ export class CustomResourcesService { }; return new Observable((observer) => { - this.apiService.peopleApi.listSiteMembershipsForPerson('-me-', options) + this.sitesApi.listSiteMembershipsForPerson('-me-', options) .then((result: SiteRolePaging) => { const page: SiteMemberPaging = new SiteMemberPaging( { list: { @@ -236,8 +272,10 @@ export class CustomResourcesService { }; return new Observable((observer) => { - this.apiService.sitesApi.getSites(options) - .then((page: SitePaging) => { + this.sitesApi + .listSites(options) + .then( + (page) => { page.list.entries.map( ({ entry }: any) => { entry.name = entry.name || entry.title; @@ -269,7 +307,7 @@ export class CustomResourcesService { skipCount: pagination.skipCount }; - return from(this.apiService.nodesApi.getDeletedNodes(options)) + return from(this.trashcanApi.listDeletedNodes(options)) .pipe(catchError((err) => this.handleError(err))); } @@ -291,7 +329,7 @@ export class CustomResourcesService { where }; - return from(this.apiService.sharedLinksApi.findSharedLinks(options)) + return from(this.sharedLinksApi.listSharedLinks(options)) .pipe(catchError((err) => this.handleError(err))); } @@ -369,7 +407,7 @@ export class CustomResourcesService { } else if (nodeId) { // cases when nodeId is '-my-', '-root-' or '-shared-' - return from(this.apiService.nodesApi.getNode(nodeId) + return from(this.nodesApi.getNode(nodeId) .then((node) => [node.entry.id])); } diff --git a/lib/core/services/ecm-user.service.spec.ts b/lib/core/services/ecm-user.service.spec.ts index 0b7018adc0..4b9fc726fa 100644 --- a/lib/core/services/ecm-user.service.spec.ts +++ b/lib/core/services/ecm-user.service.spec.ts @@ -18,41 +18,30 @@ import { TestBed } from '@angular/core/testing'; import { fakeEcmUser } from '../mock/ecm-user.service.mock'; import { EcmUserService } from '../services/ecm-user.service'; -import { setupTestBed } from '../testing/setup-test-bed'; import { CoreTestingModule } from '../testing/core.testing.module'; import { TranslateModule } from '@ngx-translate/core'; import { AuthenticationService } from './authentication.service'; import { ContentService } from './content.service'; -declare let jasmine: any; - describe('EcmUserService', () => { let service: EcmUserService; let authService: AuthenticationService; let contentService: ContentService; - setupTestBed({ - imports: [ - TranslateModule.forRoot(), - CoreTestingModule - ] - }); - beforeEach(() => { + TestBed.configureTestingModule({ + imports: [ + TranslateModule.forRoot(), + CoreTestingModule + ] + }); + service = TestBed.inject(EcmUserService); authService = TestBed.inject(AuthenticationService); contentService = TestBed.inject(ContentService); }); - beforeEach(() => { - jasmine.Ajax.install(); - }); - - afterEach(() => { - jasmine.Ajax.uninstall(); - }); - describe('when user is logged in', () => { beforeEach(() => { @@ -60,6 +49,7 @@ describe('EcmUserService', () => { }); it('should be able to retrieve current user info', (done) => { + spyOn(service.peopleApi, 'getPerson').and.returnValue(Promise.resolve({ entry: fakeEcmUser })); service.getCurrentUserInfo().subscribe( (user) => { expect(user).toBeDefined(); @@ -67,23 +57,8 @@ describe('EcmUserService', () => { expect(user.lastName).toEqual('fake-ecm-last-name'); expect(user.email).toEqual('fakeEcm@ecmUser.com'); done(); - }); - jasmine.Ajax.requests.mostRecent().respondWith({ - status: 200, - contentType: 'application/json', - responseText: JSON.stringify({entry: fakeEcmUser}) - }); - }); - - it('should be able to log errors on call', (done) => { - service.getCurrentUserInfo().subscribe(() => { - }, () => { - done(); - }); - - jasmine.Ajax.requests.mostRecent().respondWith({ - status: 403 - }); + } + ); }); it('should retrieve avatar url for current user', () => { @@ -92,13 +67,5 @@ describe('EcmUserService', () => { expect(urlRs).toEqual('fake/url/image/for/ecm/user'); }); - - it('should not call content service without avatar id', () => { - spyOn(contentService, 'getContentUrl').and.callThrough(); - const urlRs = service.getUserProfileImage(undefined); - - expect(urlRs).toBeNull(); - expect(contentService.getContentUrl).not.toHaveBeenCalled(); - }); }); }); diff --git a/lib/core/services/ecm-user.service.ts b/lib/core/services/ecm-user.service.ts index cda8839794..c60272f056 100644 --- a/lib/core/services/ecm-user.service.ts +++ b/lib/core/services/ecm-user.service.ts @@ -16,22 +16,26 @@ */ import { Injectable } from '@angular/core'; -import { Observable, from, throwError } from 'rxjs'; -import { map, catchError } from 'rxjs/operators'; +import { Observable, from } from 'rxjs'; +import { map } from 'rxjs/operators'; import { ContentService } from './content.service'; import { AlfrescoApiService } from './alfresco-api.service'; -import { LogService } from './log.service'; import { EcmUserModel } from '../models/ecm-user.model'; -import { PersonEntry } from '@alfresco/js-api'; +import { PeopleApi } from '@alfresco/js-api'; @Injectable({ providedIn: 'root' }) export class EcmUserService { + private _peopleApi: PeopleApi; + constructor(private apiService: AlfrescoApiService, - private contentService: ContentService, - private logService: LogService) { + private contentService: ContentService) { + } + + get peopleApi(): PeopleApi { + return this._peopleApi || (this._peopleApi = new PeopleApi(this.apiService.getInstance())); } /** @@ -40,12 +44,9 @@ export class EcmUserService { * @returns User information */ getUserInfo(userName: string): Observable { - return from(this.apiService.getInstance().core.peopleApi.getPerson(userName)) + return from(this.peopleApi.getPerson(userName)) .pipe( - map((personEntry: PersonEntry) => { - return new EcmUserModel(personEntry.entry); - }), - catchError((err) => this.handleError(err)) + map((personEntry) => new EcmUserModel(personEntry.entry)) ); } @@ -63,19 +64,6 @@ export class EcmUserService { * @returns Image URL */ getUserProfileImage(avatarId: string): string { - if (avatarId) { - return this.contentService.getContentUrl(avatarId); - } - return null; + return this.contentService.getContentUrl(avatarId); } - - /** - * Throw the error - * @param error - */ - private handleError(error: any) { - this.logService.error(error); - return throwError(error || 'Server error'); - } - } diff --git a/lib/testing/src/lib/core/actions/identity/identity.service.ts b/lib/testing/src/lib/core/actions/identity/identity.service.ts index dd19d94930..d742fa4bf0 100644 --- a/lib/testing/src/lib/core/actions/identity/identity.service.ts +++ b/lib/testing/src/lib/core/actions/identity/identity.service.ts @@ -21,13 +21,6 @@ import { RolesService } from './roles.service'; import { Logger } from '../../utils/logger'; export class IdentityService { - - api: ApiService; - - constructor(api: ApiService) { - this.api = api; - } - ROLES = { ACTIVITI_USER: 'ACTIVITI_USER', ACTIVITI_ADMIN: 'ACTIVITI_ADMIN', @@ -35,6 +28,8 @@ export class IdentityService { ACTIVITI_IDENTITY: 'ACTIVITI_IDENTITY' }; + constructor(public api: ApiService) {} + async createIdentityUserWithRole(roles: string[]): Promise { const rolesService = new RolesService(this.api); const user = await this.createIdentityUser();