From 51c55674b4db77b2c86791b8ceb827f0ef7bb41c Mon Sep 17 00:00:00 2001 From: Amedeo Lepore Date: Wed, 3 Sep 2025 14:37:13 +0200 Subject: [PATCH] AAE-35340 Replace deprecated toPromise() usages with firstValueFrom / lastValueFrom (#11161) --- .../services/people-content.service.spec.ts | 22 ++++----- .../content-metadata.component.spec.ts | 16 +++---- .../services/content-metadata.service.spec.ts | 20 ++++---- .../new-version-uploader.service.spec.ts | 12 ++--- ...rols-groups-marks-security.service.spec.ts | 13 ++--- .../src/lib/tag/services/tag.service.spec.ts | 10 ++-- .../api/src/lib/adf-http-client.service.ts | 8 ++-- .../auth/mock/identity-user.service.mock.ts | 8 ++-- .../lib/auth/oidc/auth-config.service.spec.ts | 4 +- .../src/lib/auth/oidc/auth-config.service.ts | 8 +++- .../oidc/oidc-authentication.service.spec.ts | 8 ++-- .../auth/oidc/redirect-auth.service.spec.ts | 6 +-- .../auth/services/identity-user.service.ts | 16 ++++--- .../auth/services/time-sync.service.spec.ts | 48 +++++-------------- .../datatable/datatable.component.spec.ts | 5 +- .../components/form-cloud.component.spec.ts | 6 +-- .../content-cloud-node-selector.service.ts | 16 ++++--- .../group/components/group-cloud.component.ts | 4 +- .../components/people-cloud.component.ts | 12 +++-- .../process-filter-cloud.service.spec.ts | 2 +- .../process-list-cloud.service.spec.ts | 14 +++--- .../start-process-cloud.service.spec.ts | 38 +++++++-------- .../claim-task/claim-task-cloud.directive.ts | 3 +- .../unclaim-task-cloud.directive.ts | 9 +++- .../complete-task/complete-task.directive.ts | 9 +++- .../service-task-list-cloud.service.spec.ts | 48 +++++++------------ .../functional-group.widget.spec.ts | 4 +- 27 files changed, 178 insertions(+), 191 deletions(-) diff --git a/lib/content-services/src/lib/common/services/people-content.service.spec.ts b/lib/content-services/src/lib/common/services/people-content.service.spec.ts index 89c893db75..73eca98d52 100644 --- a/lib/content-services/src/lib/common/services/people-content.service.spec.ts +++ b/lib/content-services/src/lib/common/services/people-content.service.spec.ts @@ -21,7 +21,7 @@ import { PeopleContentQueryRequestModel, PeopleContentService } from './people-c import { TestBed } from '@angular/core/testing'; import { PersonPaging } from '@alfresco/js-api'; import { HttpClientTestingModule } from '@angular/common/http/testing'; -import { EMPTY, of } from 'rxjs'; +import { EMPTY, firstValueFrom, of } from 'rxjs'; import { AlfrescoApiService } from '../../services'; import { AlfrescoApiServiceMock } from '../../mock'; @@ -83,14 +83,14 @@ describe('PeopleContentService', () => { it('should be able to fetch person details based on id', async () => { spyOn(peopleContentService.peopleApi, 'getPerson').and.returnValue(Promise.resolve({ entry: fakeEcmUser } as any)); - const person = await peopleContentService.getPerson('fake-id').toPromise(); + const person = await firstValueFrom(peopleContentService.getPerson('fake-id')); expect(person.id).toEqual('fake-id'); expect(person.email).toEqual('fakeEcm@ecmUser.com'); }); it('should be able to list people', async () => { spyOn(peopleContentService.peopleApi, 'listPeople').and.returnValue(Promise.resolve(fakeEcmUserList)); - const response = await peopleContentService.listPeople().toPromise(); + const response = await firstValueFrom(peopleContentService.listPeople()); const people = response.entries; const pagination = response.pagination; @@ -112,7 +112,7 @@ describe('PeopleContentService', () => { }; const expectedValue = { skipCount: 10, maxItems: 20, orderBy: ['firstName ASC'] } as any; - await peopleContentService.listPeople(requestQueryParams).toPromise(); + await firstValueFrom(peopleContentService.listPeople(requestQueryParams)); expect(listPeopleSpy).toHaveBeenCalledWith(expectedValue); }); @@ -122,14 +122,14 @@ describe('PeopleContentService', () => { const requestQueryParams: PeopleContentQueryRequestModel = { skipCount: 10, maxItems: 20, sorting: undefined }; const expectedValue = { skipCount: 10, maxItems: 20 }; - await peopleContentService.listPeople(requestQueryParams).toPromise(); + await firstValueFrom(peopleContentService.listPeople(requestQueryParams)); expect(listPeopleSpy).toHaveBeenCalledWith(expectedValue); }); it('should be able to create new person', async () => { spyOn(peopleContentService.peopleApi, 'createPerson').and.returnValue(Promise.resolve({ entry: fakeEcmUser } as any)); - const newUser = await peopleContentService.createPerson(createNewPersonMock).toPromise(); + const newUser = await firstValueFrom(peopleContentService.createPerson(createNewPersonMock)); expect(newUser.id).toEqual('fake-id'); expect(newUser.email).toEqual('fakeEcm@ecmUser.com'); }); @@ -150,12 +150,12 @@ describe('PeopleContentService', () => { Promise.resolve({ entry: fakeEcmAdminUser } as any) ); - const user = await peopleContentService.getCurrentUserInfo().toPromise(); + const user = await firstValueFrom(peopleContentService.getCurrentUserInfo()); expect(user.id).toEqual('fake-id'); expect(peopleContentService.isCurrentUserAdmin()).toBe(true); expect(getCurrentPersonSpy.calls.count()).toEqual(1); - await peopleContentService.getCurrentUserInfo().toPromise(); + await firstValueFrom(peopleContentService.getCurrentUserInfo()); expect(peopleContentService.isCurrentUserAdmin()).toBe(true); expect(getCurrentPersonSpy.calls.count()).toEqual(1); @@ -165,13 +165,13 @@ describe('PeopleContentService', () => { const getCurrentPersonSpy = spyOn(peopleContentService.peopleApi, 'getPerson').and.returnValue( Promise.resolve({ entry: fakeEcmAdminUser } as any) ); - await peopleContentService.getCurrentUserInfo().toPromise(); + await firstValueFrom(peopleContentService.getCurrentUserInfo()); getCurrentPersonSpy.and.returnValue(Promise.resolve({ entry: fakeEcmUser2 } as any)); - await peopleContentService.getPerson('fake-id').toPromise(); + await firstValueFrom(peopleContentService.getPerson('fake-id')); expect(getCurrentPersonSpy.calls.count()).toEqual(2); - const currentUser = await peopleContentService.getCurrentUserInfo().toPromise(); + const currentUser = await firstValueFrom(peopleContentService.getCurrentUserInfo()); expect(peopleContentService.isCurrentUserAdmin()).toBe(true); expect(currentUser.id).toEqual(fakeEcmAdminUser.id); expect(currentUser.id).not.toEqual(fakeEcmUser2.id); diff --git a/lib/content-services/src/lib/content-metadata/components/content-metadata/content-metadata.component.spec.ts b/lib/content-services/src/lib/content-metadata/components/content-metadata/content-metadata.component.spec.ts index f88e797012..eba177f63f 100644 --- a/lib/content-services/src/lib/content-metadata/components/content-metadata/content-metadata.component.spec.ts +++ b/lib/content-services/src/lib/content-metadata/components/content-metadata/content-metadata.component.spec.ts @@ -32,7 +32,7 @@ import { MatChipHarness } from '@angular/material/chips/testing'; import { MatDialogModule } from '@angular/material/dialog'; import { MatExpansionPanel } from '@angular/material/expansion'; import { MatSnackBarModule } from '@angular/material/snack-bar'; -import { EMPTY, of, throwError } from 'rxjs'; +import { EMPTY, firstValueFrom, of, throwError } from 'rxjs'; import { CategoriesManagementComponent, CategoriesManagementMode } from '../../../category'; import { TagsCreatorComponent, TagsCreatorMode } from '../../../tag'; import { ContentTestingModule } from '../../../testing/content.testing.module'; @@ -1144,7 +1144,7 @@ describe('ContentMetadataComponent', () => { component.ngOnChanges({ node: new SimpleChange(node, expectedNode, false) }); fixture.detectChanges(); - await component.groupedProperties$.toPromise(); + await firstValueFrom(component.groupedProperties$); fixture.detectChanges(); const verProp = queryDom('Versionable'); @@ -1164,7 +1164,7 @@ describe('ContentMetadataComponent', () => { component.ngOnChanges({ node: new SimpleChange(node, expectedNode, false) }); fixture.detectChanges(); - await component.groupedProperties$.toPromise(); + await firstValueFrom(component.groupedProperties$); fixture.detectChanges(); const verProps = fixture.debugElement.queryAll(By.css('[data-automation-id="adf-metadata-group-Versionable"]')); @@ -1184,7 +1184,7 @@ describe('ContentMetadataComponent', () => { component.ngOnChanges({ node: new SimpleChange(node, expectedNode, false) }); fixture.detectChanges(); - await component.groupedProperties$.toPromise(); + await firstValueFrom(component.groupedProperties$); fixture.detectChanges(); const verProp = queryDom('Versionable'); @@ -1205,7 +1205,7 @@ describe('ContentMetadataComponent', () => { component.ngOnChanges({ node: new SimpleChange(node, expectedNode, false) }); fixture.detectChanges(); - await component.groupedProperties$.toPromise(); + await firstValueFrom(component.groupedProperties$); fixture.detectChanges(); const verProp = queryDom('Versionable'); @@ -1225,7 +1225,7 @@ describe('ContentMetadataComponent', () => { component.ngOnChanges({ node: new SimpleChange(node, expectedNode, false) }); fixture.detectChanges(); - await component.groupedProperties$.toPromise(); + await firstValueFrom(component.groupedProperties$); fixture.detectChanges(); const verProp = queryDom('Versionable'); @@ -1249,7 +1249,7 @@ describe('ContentMetadataComponent', () => { component.ngOnChanges({ node: new SimpleChange(node, expectedNode, false) }); fixture.detectChanges(); - await component.groupedProperties$.toPromise(); + await firstValueFrom(component.groupedProperties$); fixture.detectChanges(); const exifProp = queryDom('Exif'); @@ -1283,7 +1283,7 @@ describe('ContentMetadataComponent', () => { component.ngOnChanges({ node: new SimpleChange(node, expectedNode, false) }); fixture.detectChanges(); - await component.groupedProperties$.toPromise(); + await firstValueFrom(component.groupedProperties$); fixture.detectChanges(); const exifProps = fixture.debugElement.queryAll(By.css('[data-automation-id="adf-metadata-group-Exif"]')); diff --git a/lib/content-services/src/lib/content-metadata/services/content-metadata.service.spec.ts b/lib/content-services/src/lib/content-metadata/services/content-metadata.service.spec.ts index 8291284f5e..e66d359d51 100644 --- a/lib/content-services/src/lib/content-metadata/services/content-metadata.service.spec.ts +++ b/lib/content-services/src/lib/content-metadata/services/content-metadata.service.spec.ts @@ -18,7 +18,7 @@ import { AppConfigService } from '@alfresco/adf-core'; import { ClassesApi, Node } from '@alfresco/js-api'; import { TestBed } from '@angular/core/testing'; -import { of } from 'rxjs'; +import { firstValueFrom, of } from 'rxjs'; import { ContentTestingModule } from '../../testing/content.testing.module'; import { OrganisedPropertyGroup } from '../interfaces/content-metadata.interfaces'; import { PropertyGroup } from '../interfaces/property-group.interface'; @@ -253,7 +253,7 @@ describe('ContentMetaDataService', () => { spyOn(classesApi, 'getClass').and.returnValue(Promise.resolve(exifResponse)); - const groupedProperties = await service.getGroupedProperties(fakeNode).toPromise(); + const groupedProperties = await firstValueFrom(service.getGroupedProperties(fakeNode)); expect(groupedProperties.length).toEqual(1); expect(groupedProperties[0].title).toEqual('Exif'); @@ -267,7 +267,7 @@ describe('ContentMetaDataService', () => { spyOn(classesApi, 'getClass').and.returnValue(Promise.resolve(exifResponse)); - const groupedProperties = await service.getGroupedProperties(fakeNode).toPromise(); + const groupedProperties = await firstValueFrom(service.getGroupedProperties(fakeNode)); expect(groupedProperties.length).toEqual(1); expect(groupedProperties[0].title).toEqual('Exif'); @@ -284,7 +284,7 @@ describe('ContentMetaDataService', () => { spyOn(classesApi, 'getClass').and.returnValue(Promise.resolve(verResponse)); - const groupedProperties = await service.getGroupedProperties(fakeContentNode).toPromise(); + const groupedProperties = await firstValueFrom(service.getGroupedProperties(fakeContentNode)); expect(groupedProperties.length).toEqual(1); expect(groupedProperties[0].title).toEqual('Versionable'); @@ -301,7 +301,7 @@ describe('ContentMetaDataService', () => { spyOn(classesApi, 'getClass').and.returnValue(Promise.resolve(verResponse)); - const groupedProperties = await service.getGroupedProperties(fakeContentNode).toPromise(); + const groupedProperties = await firstValueFrom(service.getGroupedProperties(fakeContentNode)); expect(groupedProperties.length).toEqual(2); expect(groupedProperties[0].title).toEqual('Versionable'); @@ -319,7 +319,7 @@ describe('ContentMetaDataService', () => { spyOn(classesApi, 'getClass').and.returnValue(Promise.resolve(verResponse)); - const groupedProperties = await service.getGroupedProperties(fakeContentNode).toPromise(); + const groupedProperties = await firstValueFrom(service.getGroupedProperties(fakeContentNode)); expect(groupedProperties.length).toEqual(0); expect(classesApi.getClass).toHaveBeenCalledTimes(1 + fakeContentNode.aspectNames.length); @@ -335,7 +335,7 @@ describe('ContentMetaDataService', () => { spyOn(classesApi, 'getClass').and.returnValue(Promise.resolve(verResponse)); - const groupedProperties = await service.getGroupedProperties(fakeContentNode).toPromise(); + const groupedProperties = await firstValueFrom(service.getGroupedProperties(fakeContentNode)); expect(groupedProperties.length).toEqual(1); expect(groupedProperties[0].title).toEqual('Versionable'); @@ -351,7 +351,7 @@ describe('ContentMetaDataService', () => { spyOn(classesApi, 'getClass').and.returnValue(Promise.resolve(verResponse)); - const groupedProperties = await service.getGroupedProperties(fakeContentNode).toPromise(); + const groupedProperties = await firstValueFrom(service.getGroupedProperties(fakeContentNode)); expect(groupedProperties.length).toEqual(0); expect(classesApi.getClass).toHaveBeenCalledTimes(1 + fakeContentNode.aspectNames.length); @@ -367,7 +367,7 @@ describe('ContentMetaDataService', () => { spyOn(classesApi, 'getClass').and.returnValue(Promise.resolve(exifResponse)); - const groupedProperties = await service.getGroupedProperties(fakeNode).toPromise(); + const groupedProperties = await firstValueFrom(service.getGroupedProperties(fakeNode)); expect(groupedProperties.length).toEqual(1); expect(groupedProperties[0].title).toEqual('Exif'); @@ -387,7 +387,7 @@ describe('ContentMetaDataService', () => { spyOn(classesApi, 'getClass').and.returnValue(Promise.resolve(exifResponse)); - const groupedProperties = await service.getGroupedProperties(fakeNode).toPromise(); + const groupedProperties = await firstValueFrom(service.getGroupedProperties(fakeNode)); expect(groupedProperties.length).toEqual(2); expect(groupedProperties[0].title).toEqual('Exif'); diff --git a/lib/content-services/src/lib/new-version-uploader/new-version-uploader.service.spec.ts b/lib/content-services/src/lib/new-version-uploader/new-version-uploader.service.spec.ts index 43dd6f8e64..d98c33b483 100644 --- a/lib/content-services/src/lib/new-version-uploader/new-version-uploader.service.spec.ts +++ b/lib/content-services/src/lib/new-version-uploader/new-version-uploader.service.spec.ts @@ -18,7 +18,7 @@ import { Component, EventEmitter, Output } from '@angular/core'; import { ComponentFixture, fakeAsync, TestBed, tick } from '@angular/core/testing'; import { MatDialog, MatDialogConfig } from '@angular/material/dialog'; -import { BehaviorSubject, of, Subject } from 'rxjs'; +import { BehaviorSubject, firstValueFrom, of, Subject } from 'rxjs'; import { mockFile, mockNewVersionUploaderData, mockNode } from '../mock'; import { ContentTestingModule } from '../testing/content.testing.module'; import { @@ -114,7 +114,7 @@ describe('NewVersionUploaderService', () => { }); it('should open dialog with default configuration', fakeAsync(() => { - service.openUploadNewVersionDialog(mockNewVersionUploaderDialogData).toPromise(); + firstValueFrom(service.openUploadNewVersionDialog(mockNewVersionUploaderDialogData)); tick(); expect(spyOnDialogOpen).toHaveBeenCalledWith(NewVersionUploaderDialogComponent, expectedConfig); })); @@ -124,7 +124,7 @@ describe('NewVersionUploaderService', () => { panelClass: 'adf-custom-class', width: '500px' }; - service.openUploadNewVersionDialog(mockNewVersionUploaderDialogData, mockDialogConfiguration).toPromise(); + firstValueFrom(service.openUploadNewVersionDialog(mockNewVersionUploaderDialogData, mockDialogConfiguration)); tick(); expectedConfig.panelClass = 'adf-custom-class'; expectedConfig.width = '500px'; @@ -135,7 +135,7 @@ describe('NewVersionUploaderService', () => { const mockDialogConfiguration: MatDialogConfig = { height: '600px' }; - service.openUploadNewVersionDialog(mockNewVersionUploaderDialogData, mockDialogConfiguration).toPromise(); + firstValueFrom(service.openUploadNewVersionDialog(mockNewVersionUploaderDialogData, mockDialogConfiguration)); tick(); expectedConfig.height = '600px'; expect(spyOnDialogOpen).toHaveBeenCalledWith(NewVersionUploaderDialogComponent, expectedConfig); @@ -143,7 +143,7 @@ describe('NewVersionUploaderService', () => { it('should not override dialog configuration, if dialog configuration is empty', fakeAsync(() => { const mockDialogConfiguration: MatDialogConfig = {}; - service.openUploadNewVersionDialog(mockNewVersionUploaderDialogData, mockDialogConfiguration).toPromise(); + firstValueFrom(service.openUploadNewVersionDialog(mockNewVersionUploaderDialogData, mockDialogConfiguration)); tick(); expect(spyOnDialogOpen).toHaveBeenCalledWith(NewVersionUploaderDialogComponent, expectedConfig); })); @@ -156,7 +156,7 @@ describe('NewVersionUploaderService', () => { showComments: true, allowDownload: true }; - service.openUploadNewVersionDialog(mockNewVersionUploaderDialogDataWithVersionsOnly).toPromise(); + firstValueFrom(service.openUploadNewVersionDialog(mockNewVersionUploaderDialogDataWithVersionsOnly)); tick(); expectedConfig.data.showVersionsOnly = true; expectedConfig.panelClass = ['adf-new-version-uploader-dialog', 'adf-new-version-uploader-dialog-list']; diff --git a/lib/content-services/src/lib/security/services/security-controls-groups-marks-security.service.spec.ts b/lib/content-services/src/lib/security/services/security-controls-groups-marks-security.service.spec.ts index 9f68ce5042..a0c3ef89c6 100644 --- a/lib/content-services/src/lib/security/services/security-controls-groups-marks-security.service.spec.ts +++ b/lib/content-services/src/lib/security/services/security-controls-groups-marks-security.service.spec.ts @@ -21,6 +21,7 @@ import { fakeAuthorityClearanceApiResponse } from './mock/security-authorities.m import { fakeGroupsApiResponse, createNewSecurityGroupMock } from './mock/security-groups.mock'; import { fakeMarksApiResponse, createNewSecurityMarkMock } from './mock/security-marks.mock'; import { SecurityGroupBody, SecurityMarkBody, SecurityMarkEntry } from '@alfresco/js-api'; +import { firstValueFrom } from 'rxjs'; describe('SecurityControlsService', () => { let service: SecurityControlsService; @@ -78,7 +79,7 @@ describe('SecurityControlsService', () => { } }) ); - const response = await service.createSecurityGroup(createNewSecurityGroupMock).toPromise(); + const response = await firstValueFrom(service.createSecurityGroup(createNewSecurityGroupMock)); securityGroupId = response.entry.id; expect(response.entry.groupName).toEqual('TestGroup'); @@ -176,7 +177,7 @@ describe('SecurityControlsService', () => { it('should delete a security group', async () => { spyOn(service.groupsApi, 'deleteSecurityGroup').and.returnValue(Promise.resolve()); - await service.deleteSecurityGroup(securityGroupId).toPromise(); + await firstValueFrom(service.deleteSecurityGroup(securityGroupId)); expect(service.groupsApi.deleteSecurityGroup).toHaveBeenCalled(); }); @@ -185,7 +186,7 @@ describe('SecurityControlsService', () => { Promise.resolve(fakeAuthorityClearanceApiResponse) ); const clearancePromise = service.getClearancesForAuthority('test-id', 0, 10); - const clearance = await clearancePromise.toPromise(); + const clearance = await firstValueFrom(clearancePromise); expect(getClearancesForAuthoritySpy).toHaveBeenCalledWith('test-id', { skipCount: 0, @@ -210,15 +211,15 @@ describe('SecurityControlsService', () => { } }) ); - const response = (await service - .updateClearancesForAuthority('test-id', [ + const response = (await firstValueFrom( + service.updateClearancesForAuthority('test-id', [ { groupId: 'test-group-id', op: 'test-op', id: 'test-id' } ]) - .toPromise()) as SecurityMarkEntry; + )) as SecurityMarkEntry; expect(response.entry.id).toEqual('test-id'); expect(response.entry.groupId).toEqual('test-groupId'); diff --git a/lib/content-services/src/lib/tag/services/tag.service.spec.ts b/lib/content-services/src/lib/tag/services/tag.service.spec.ts index c89767e9fc..5b945d0c68 100644 --- a/lib/content-services/src/lib/tag/services/tag.service.spec.ts +++ b/lib/content-services/src/lib/tag/services/tag.service.spec.ts @@ -19,7 +19,7 @@ import { AppConfigService, UserPreferencesService } from '@alfresco/adf-core'; import { TagService } from './tag.service'; import { fakeAsync, TestBed, tick } from '@angular/core/testing'; import { ContentTestingModule } from '../../testing/content.testing.module'; -import { throwError } from 'rxjs'; +import { firstValueFrom, throwError } from 'rxjs'; import { Pagination, Tag, TagBody, TagEntry, TagPaging, TagPagingList } from '@alfresco/js-api'; describe('TagService', () => { @@ -75,7 +75,7 @@ describe('TagService', () => { let lastValue: any; service.refresh.subscribe((res) => (lastValue = res)); - await service.addTag('fake-node-id', 'fake-tag').toPromise(); + await firstValueFrom(service.addTag('fake-node-id', 'fake-tag')); expect(lastValue).toBe(tagEntry); }); @@ -83,7 +83,7 @@ describe('TagService', () => { let lastValue = false; service.refresh.subscribe(() => (lastValue = true)); - await service.deleteTag('fake-tag-id').toPromise(); + await firstValueFrom(service.deleteTag('fake-tag-id')); expect(lastValue).toBeTrue(); }); @@ -110,7 +110,7 @@ describe('TagService', () => { spyOn(service.refresh, 'emit'); spyOn(service.tagsApi, 'createTags').and.returnValue(Promise.resolve(tag)); - await service.createTags([]).toPromise(); + await firstValueFrom(service.createTags([])); expect(service.refresh.emit).toHaveBeenCalledWith(tag); }); }); @@ -248,7 +248,7 @@ describe('TagService', () => { it('should emit refresh when tag updated successfully', async () => { spyOn(service.refresh, 'emit'); spyOn(service.tagsApi, 'updateTag').and.returnValue(Promise.resolve(updatedTag)); - await service.updateTag(tag.entry.id, tagBody).toPromise(); + await firstValueFrom(service.updateTag(tag.entry.id, tagBody)); expect(service.refresh.emit).toHaveBeenCalledWith(updatedTag); }); }); diff --git a/lib/core/api/src/lib/adf-http-client.service.ts b/lib/core/api/src/lib/adf-http-client.service.ts index 5d7e9ae66f..eeee981177 100644 --- a/lib/core/api/src/lib/adf-http-client.service.ts +++ b/lib/core/api/src/lib/adf-http-client.service.ts @@ -19,7 +19,7 @@ import { SHOULD_ADD_AUTH_TOKEN } from '@alfresco/adf-core/auth'; import { Emitters as JsApiEmitters, HttpClient as JsApiHttpClient } from '@alfresco/js-api'; import { HttpClient, HttpContext, HttpErrorResponse, HttpEvent, HttpHeaders, HttpParams, HttpResponse } from '@angular/common/http'; import { Injectable } from '@angular/core'; -import { Observable, of, Subject, throwError } from 'rxjs'; +import { lastValueFrom, Observable, of, Subject, throwError } from 'rxjs'; import { catchError, map, takeUntil } from 'rxjs/operators'; import { convertObjectToFormData, @@ -196,8 +196,8 @@ export class AdfHttpClient implements JsApiHttpClient { const abort$ = new Subject(); const { eventEmitter, apiClientEmitter } = emitters; - const promise = request$ - .pipe( + const promise = lastValueFrom( + request$.pipe( map((res) => { if (isHttpUploadProgressEvent(res)) { const percent = Math.round((res.loaded / res.total) * 100); @@ -243,7 +243,7 @@ export class AdfHttpClient implements JsApiHttpClient { }), takeUntil(abort$) ) - .toPromise(); + ); (promise as any).abort = function () { eventEmitter.emit('abort'); diff --git a/lib/core/src/lib/auth/mock/identity-user.service.mock.ts b/lib/core/src/lib/auth/mock/identity-user.service.mock.ts index 69d9d225ea..c2b4585af2 100644 --- a/lib/core/src/lib/auth/mock/identity-user.service.mock.ts +++ b/lib/core/src/lib/auth/mock/identity-user.service.mock.ts @@ -27,7 +27,7 @@ import { IdentityJoinGroupRequestModel } from '../interfaces/identity-user.service.interface'; import { mockIdentityGroups } from './identity-group.mock'; -import { Observable, of } from 'rxjs'; +import { firstValueFrom, Observable, of } from 'rxjs'; import { map, switchMap } from 'rxjs/operators'; import { mockAssignedRoles, mockAvailableRoles, mockEffectiveRoles, mockIdentityUser1, mockIdentityUsers } from './identity-user.mock'; @@ -127,7 +127,7 @@ export class IdentityUserServiceMock implements IdentityUserServiceInterface { async getUsersByRolesWithCurrentUser(roleNames: string[]): Promise { const filteredUsers: IdentityUserModel[] = []; if (roleNames && roleNames.length > 0) { - const users = await this.getUsers().toPromise(); + const users = await firstValueFrom(this.getUsers()); for (let i = 0; i < users.length; i++) { const hasAnyRole = await this.userHasAnyRole(users[i].id, roleNames); @@ -144,7 +144,7 @@ export class IdentityUserServiceMock implements IdentityUserServiceInterface { const filteredUsers: IdentityUserModel[] = []; if (roleNames && roleNames.length > 0) { const currentUser = this.getCurrentUserInfo(); - let users = await this.getUsers().toPromise(); + let users = await firstValueFrom(this.getUsers()); users = users.filter(({ username }) => username !== currentUser.username); @@ -160,7 +160,7 @@ export class IdentityUserServiceMock implements IdentityUserServiceInterface { } private async userHasAnyRole(userId: string, roleNames: string[]): Promise { - const userRoles = await this.getUserRoles(userId).toPromise(); + const userRoles = await firstValueFrom(this.getUserRoles(userId)); const hasAnyRole = roleNames.some((roleName) => { const filteredRoles = userRoles.filter((userRole) => userRole.name.toLocaleLowerCase() === roleName.toLocaleLowerCase()); diff --git a/lib/core/src/lib/auth/oidc/auth-config.service.spec.ts b/lib/core/src/lib/auth/oidc/auth-config.service.spec.ts index 43f159c794..f7e71983e9 100644 --- a/lib/core/src/lib/auth/oidc/auth-config.service.spec.ts +++ b/lib/core/src/lib/auth/oidc/auth-config.service.spec.ts @@ -17,7 +17,7 @@ import { HttpClientTestingModule } from '@angular/common/http/testing'; import { TestBed } from '@angular/core/testing'; -import { EMPTY } from 'rxjs'; +import { of } from 'rxjs'; import { AppConfigService } from '../../app-config/app-config.service'; import { AUTH_MODULE_CONFIG } from './auth-config'; import { AuthConfigService } from './auth-config.service'; @@ -102,7 +102,7 @@ describe('AuthConfigService', () => { spyOn(service, 'getLocationOrigin').and.returnValue('http://localhost:3000'); appConfigService = TestBed.inject(AppConfigService); - appConfigService.onLoad = EMPTY; + appConfigService.onLoad = of(true); }); describe('load auth config using hash', () => { diff --git a/lib/core/src/lib/auth/oidc/auth-config.service.ts b/lib/core/src/lib/auth/oidc/auth-config.service.ts index 845e7bd03b..0e0128ca0e 100644 --- a/lib/core/src/lib/auth/oidc/auth-config.service.ts +++ b/lib/core/src/lib/auth/oidc/auth-config.service.ts @@ -21,6 +21,7 @@ import { take } from 'rxjs/operators'; import { AppConfigService } from '../../app-config/app-config.service'; import { AUTH_MODULE_CONFIG, AuthModuleConfig } from './auth-config'; import { OauthConfigModel } from '../models/oauth-config.model'; +import { firstValueFrom } from 'rxjs'; /** * Create auth configuration factory @@ -36,7 +37,10 @@ export function authConfigFactory(authConfigService: AuthConfigService): Promise providedIn: 'root' }) export class AuthConfigService { - constructor(private appConfigService: AppConfigService, @Inject(AUTH_MODULE_CONFIG) private readonly authModuleConfig: AuthModuleConfig) {} + constructor( + private appConfigService: AppConfigService, + @Inject(AUTH_MODULE_CONFIG) private readonly authModuleConfig: AuthModuleConfig + ) {} private _authConfig!: AuthConfig; get authConfig(): AuthConfig { @@ -44,7 +48,7 @@ export class AuthConfigService { } loadConfig(): Promise { - return this.appConfigService.onLoad.pipe(take(1)).toPromise().then(this.loadAppConfig.bind(this)); + return firstValueFrom(this.appConfigService.onLoad.pipe(take(1))).then(this.loadAppConfig.bind(this)); } loadAppConfig(): AuthConfig { diff --git a/lib/core/src/lib/auth/oidc/oidc-authentication.service.spec.ts b/lib/core/src/lib/auth/oidc/oidc-authentication.service.spec.ts index b489541e99..67d5ab38a0 100644 --- a/lib/core/src/lib/auth/oidc/oidc-authentication.service.spec.ts +++ b/lib/core/src/lib/auth/oidc/oidc-authentication.service.spec.ts @@ -214,7 +214,7 @@ describe('OidcAuthenticationService shouldPerformSsoLogin', () => { }; configureTestingModule({ provide: AuthService, useValue: mockAuthServiceValue }); - const shouldPerformSsoLogin = await service.shouldPerformSsoLogin$.toPromise(); + const shouldPerformSsoLogin = await firstValueFrom(service.shouldPerformSsoLogin$); expect(shouldPerformSsoLogin).toBeTrue(); }); @@ -225,7 +225,7 @@ describe('OidcAuthenticationService shouldPerformSsoLogin', () => { }; configureTestingModule({ provide: AuthService, useValue: mockAuthServiceValue }); - const shouldPerformSsoLogin = await service.shouldPerformSsoLogin$.toPromise(); + const shouldPerformSsoLogin = await firstValueFrom(service.shouldPerformSsoLogin$); expect(shouldPerformSsoLogin).toBeFalse(); }); @@ -236,7 +236,7 @@ describe('OidcAuthenticationService shouldPerformSsoLogin', () => { }; configureTestingModule({ provide: AuthService, useValue: mockAuthServiceValue }); - const shouldPerformSsoLogin = await service.shouldPerformSsoLogin$.toPromise(); + const shouldPerformSsoLogin = await firstValueFrom(service.shouldPerformSsoLogin$); expect(shouldPerformSsoLogin).toBeFalse(); }); @@ -247,7 +247,7 @@ describe('OidcAuthenticationService shouldPerformSsoLogin', () => { }; configureTestingModule({ provide: AuthService, useValue: mockAuthServiceValue }); - const shouldPerformSsoLogin = await service.shouldPerformSsoLogin$.toPromise(); + const shouldPerformSsoLogin = await firstValueFrom(service.shouldPerformSsoLogin$); expect(shouldPerformSsoLogin).toBeFalse(); }); }); diff --git a/lib/core/src/lib/auth/oidc/redirect-auth.service.spec.ts b/lib/core/src/lib/auth/oidc/redirect-auth.service.spec.ts index ad8dfede7b..bc16799499 100644 --- a/lib/core/src/lib/auth/oidc/redirect-auth.service.spec.ts +++ b/lib/core/src/lib/auth/oidc/redirect-auth.service.spec.ts @@ -28,7 +28,7 @@ import { OAuthSuccessEvent, OAuthInfoEvent } from 'angular-oauth2-oidc'; -import { of, Subject, timeout } from 'rxjs'; +import { firstValueFrom, of, Subject, timeout } from 'rxjs'; import { RedirectAuthService } from './redirect-auth.service'; import { AUTH_MODULE_CONFIG } from './auth-config'; import { RetryLoginService } from './retry-login.service'; @@ -389,8 +389,8 @@ describe('RedirectAuthService', () => { it('should NOT logout user if the refresh token failed first time', fakeAsync(async () => { const expectedFakeErrorEvent = new OAuthErrorEvent('token_refresh_error', { reason: 'error' }, {}); - const firstEventOccurPromise = service.firstOauthErrorEventOccur$.toPromise(); - const secondTokenRefreshErrorEventPromise = service.secondTokenRefreshErrorEventOccur$.pipe(timeout(1000)).toPromise(); + const firstEventOccurPromise = firstValueFrom(service.firstOauthErrorEventOccur$); + const secondTokenRefreshErrorEventPromise = firstValueFrom(service.secondTokenRefreshErrorEventOccur$.pipe(timeout(1000))); oauthEvents$.next(new OAuthErrorEvent('token_refresh_error', { reason: 'error' }, {})); diff --git a/lib/core/src/lib/auth/services/identity-user.service.ts b/lib/core/src/lib/auth/services/identity-user.service.ts index 6457f20c8f..e0a031bcc0 100644 --- a/lib/core/src/lib/auth/services/identity-user.service.ts +++ b/lib/core/src/lib/auth/services/identity-user.service.ts @@ -16,7 +16,7 @@ */ import { Injectable } from '@angular/core'; -import { Observable, of } from 'rxjs'; +import { firstValueFrom, Observable, of } from 'rxjs'; import { map, switchMap } from 'rxjs/operators'; import { AppConfigService } from '../../app-config/app-config.service'; import { IdentityGroupModel } from '../models/identity-group.model'; @@ -36,7 +36,11 @@ import { OAuth2Service } from './oauth2.service'; providedIn: 'root' }) export class IdentityUserService implements IdentityUserServiceInterface { - constructor(private jwtHelperService: JwtHelperService, private oAuth2Service: OAuth2Service, private appConfigService: AppConfigService) {} + constructor( + private jwtHelperService: JwtHelperService, + private oAuth2Service: OAuth2Service, + private appConfigService: AppConfigService + ) {} private get identityHost(): string { return `${this.appConfigService.get('identityHost')}`; @@ -239,7 +243,7 @@ export class IdentityUserService implements IdentityUserServiceInterface { async getUsersByRolesWithCurrentUser(roleNames: string[]): Promise { const filteredUsers: IdentityUserModel[] = []; if (roleNames && roleNames.length > 0) { - const users = await this.getUsers().toPromise(); + const users = await firstValueFrom(this.getUsers()); for (let i = 0; i < users.length; i++) { const hasAnyRole = await this.userHasAnyRole(users[i].id, roleNames); @@ -262,7 +266,7 @@ export class IdentityUserService implements IdentityUserServiceInterface { const filteredUsers: IdentityUserModel[] = []; if (roleNames && roleNames.length > 0) { const currentUser = this.getCurrentUserInfo(); - let users = await this.getUsers().toPromise(); + let users = await firstValueFrom(this.getUsers()); users = users.filter(({ username }) => username !== currentUser.username); @@ -278,7 +282,7 @@ export class IdentityUserService implements IdentityUserServiceInterface { } private async userHasAnyRole(userId: string, roleNames: string[]): Promise { - const userRoles = await this.getUserRoles(userId).toPromise(); + const userRoles = await firstValueFrom(this.getUserRoles(userId)); const hasAnyRole = roleNames.some((roleName) => { const filteredRoles = userRoles.filter((userRole) => userRole.name.toLocaleLowerCase() === roleName.toLocaleLowerCase()); @@ -337,7 +341,7 @@ export class IdentityUserService implements IdentityUserServiceInterface { hasMoreItems: false, totalItems: totalCount } - } as IdentityUserQueryResponse) + }) as IdentityUserQueryResponse ) ) ) diff --git a/lib/core/src/lib/auth/services/time-sync.service.spec.ts b/lib/core/src/lib/auth/services/time-sync.service.spec.ts index d2064309a9..d6d7157a81 100644 --- a/lib/core/src/lib/auth/services/time-sync.service.spec.ts +++ b/lib/core/src/lib/auth/services/time-sync.service.spec.ts @@ -19,6 +19,7 @@ import { HttpClientTestingModule, HttpTestingController } from '@angular/common/ import { TestBed } from '@angular/core/testing'; import { AppConfigService } from '../../app-config/app-config.service'; import { TimeSyncService } from './time-sync.service'; +import { firstValueFrom } from 'rxjs'; describe('TimeSyncService', () => { let service: TimeSyncService; @@ -30,10 +31,7 @@ describe('TimeSyncService', () => { TestBed.configureTestingModule({ imports: [HttpClientTestingModule], - providers: [ - TimeSyncService, - { provide: AppConfigService, useValue: appConfigSpy } - ] + providers: [TimeSyncService, { provide: AppConfigService, useValue: appConfigSpy }] }); service = TestBed.inject(TimeSyncService); @@ -45,7 +43,6 @@ describe('TimeSyncService', () => { }); describe('checkTimeSync', () => { - it('should check time sync and return outOfSync as false when time is within allowed skew', () => { appConfigSpy.get.and.returnValue('http://fake-server-time-url'); @@ -58,15 +55,11 @@ describe('TimeSyncService', () => { const serverTime = 1728911640000; // (GMT): Monday, October 14, 2024 1:14:00 PM - spyOn(Date, 'now').and.returnValues( - timeBeforeCallingServerTimeEndpoint, - timeResponseReceivedFromServerTimeEndpoint, - localCurrentTime - ); + spyOn(Date, 'now').and.returnValues(timeBeforeCallingServerTimeEndpoint, timeResponseReceivedFromServerTimeEndpoint, localCurrentTime); // difference between localCurrentTime and serverTime is 60 seconds plus the round trip time of 1 second const allowedClockSkewInSec = 61; - service.checkTimeSync(allowedClockSkewInSec).subscribe(sync => { + service.checkTimeSync(allowedClockSkewInSec).subscribe((sync) => { expect(sync.outOfSync).toBeFalse(); expect(sync.localDateTimeISO).toEqual('2024-10-14T13:13:00.000Z'); expect(sync.serverDateTimeISO).toEqual('2024-10-14T13:14:00.500Z'); @@ -89,16 +82,12 @@ describe('TimeSyncService', () => { const serverTime = 1728911640000; // (GMT): Monday, October 14, 2024 1:14:00 PM - spyOn(Date, 'now').and.returnValues( - timeBeforeCallingServerTimeEndpoint, - timeResponseReceivedFromServerTimeEndpoint, - localCurrentTime - ); + spyOn(Date, 'now').and.returnValues(timeBeforeCallingServerTimeEndpoint, timeResponseReceivedFromServerTimeEndpoint, localCurrentTime); // difference between localCurrentTime and serverTime is 60 seconds plus the round trip time of 1 second // setting allowedClockSkewInSec to 60 seconds will make the local time out of sync const allowedClockSkewInSec = 60; - service.checkTimeSync(allowedClockSkewInSec).subscribe(sync => { + service.checkTimeSync(allowedClockSkewInSec).subscribe((sync) => { expect(sync.outOfSync).toBeTrue(); expect(sync.localDateTimeISO).toEqual('2024-10-14T13:13:00.000Z'); expect(sync.serverDateTimeISO).toEqual('2024-10-14T13:14:00.500Z'); @@ -113,12 +102,11 @@ describe('TimeSyncService', () => { appConfigSpy.get.and.returnValue(''); try { - await service.checkTimeSync(60).toPromise(); + await firstValueFrom(service.checkTimeSync(60)); fail('Expected to throw an error'); } catch (error) { expect(error.message).toBe('serverTimeUrl is not configured.'); } - }); it('should throw an error if the server time endpoint returns an error', () => { @@ -130,7 +118,7 @@ describe('TimeSyncService', () => { next: () => { fail('Expected to throw an error'); }, - error: error => { + error: (error) => { expect(error.message).toBe('Error: Failed to get server time'); } }); @@ -139,12 +127,10 @@ describe('TimeSyncService', () => { expect(req.request.method).toBe('GET'); req.error(new ProgressEvent('')); }); - }); describe('isLocalTimeOutOfSync', () => { it('should return clock is out of sync', () => { - appConfigSpy.get.and.returnValue('http://fake-server-time-url'); const expectedServerTimeUrl = 'http://fake-server-time-url'; @@ -156,16 +142,12 @@ describe('TimeSyncService', () => { const serverTime = 1728911640000; // (GMT): Monday, October 14, 2024 1:14:00 PM - spyOn(Date, 'now').and.returnValues( - timeBeforeCallingServerTimeEndpoint, - timeResponseReceivedFromServerTimeEndpoint, - localCurrentTime - ); + spyOn(Date, 'now').and.returnValues(timeBeforeCallingServerTimeEndpoint, timeResponseReceivedFromServerTimeEndpoint, localCurrentTime); // difference between localCurrentTime and serverTime is 60 seconds plus the round trip time of 1 second // setting allowedClockSkewInSec to 60 seconds will make the local time out of sync const allowedClockSkewInSec = 60; - service.isLocalTimeOutOfSync(allowedClockSkewInSec).subscribe(isOutOfSync => { + service.isLocalTimeOutOfSync(allowedClockSkewInSec).subscribe((isOutOfSync) => { expect(isOutOfSync).toBeTrue(); }); @@ -186,15 +168,11 @@ describe('TimeSyncService', () => { const serverTime = 1728911640000; // (GMT): Monday, October 14, 2024 1:14:00 PM - spyOn(Date, 'now').and.returnValues( - timeBeforeCallingServerTimeEndpoint, - timeResponseReceivedFromServerTimeEndpoint, - localCurrentTime - ); + spyOn(Date, 'now').and.returnValues(timeBeforeCallingServerTimeEndpoint, timeResponseReceivedFromServerTimeEndpoint, localCurrentTime); // difference between localCurrentTime and serverTime is 60 seconds plus the round trip time of 1 second const allowedClockSkewInSec = 61; - service.isLocalTimeOutOfSync(allowedClockSkewInSec).subscribe(isOutOfSync => { + service.isLocalTimeOutOfSync(allowedClockSkewInSec).subscribe((isOutOfSync) => { expect(isOutOfSync).toBeFalse(); }); @@ -203,6 +181,4 @@ describe('TimeSyncService', () => { req.flush(serverTime); }); }); - - }); diff --git a/lib/core/src/lib/datatable/components/datatable/datatable.component.spec.ts b/lib/core/src/lib/datatable/components/datatable/datatable.component.spec.ts index 4d26a6a6ea..37e3bc0b0e 100644 --- a/lib/core/src/lib/datatable/components/datatable/datatable.component.spec.ts +++ b/lib/core/src/lib/datatable/components/datatable/datatable.component.spec.ts @@ -35,6 +35,7 @@ import { UnitTestingUtils } from '../../../testing/unit-testing-utils'; import { HarnessLoader } from '@angular/cdk/testing'; import { ConfigurableFocusTrapFactory } from '@angular/cdk/a11y'; import { provideRouter } from '@angular/router'; +import { firstValueFrom } from 'rxjs'; @Component({ selector: 'adf-custom-column-template-component', @@ -1353,7 +1354,7 @@ describe('DataTable', () => { expect(rows[1].isSelected).toBeFalsy(); dataTable.resetSelection(); - const rowClickPromise = dataTable.rowClick.pipe(take(1)).toPromise(); + const rowClickPromise = firstValueFrom(dataTable.rowClick.pipe(take(1))); testingUtils.clickByCSS('[data-automation-id="datatable-row-0"] > div'); fixture.detectChanges(); await rowClickPromise; @@ -1363,7 +1364,7 @@ describe('DataTable', () => { expect(rows2[1].isSelected).toBeFalsy(); dataTable.resetSelection(); - const cellClickPromise = dataTable.rowClick.pipe(take(1)).toPromise(); + const cellClickPromise = firstValueFrom(dataTable.rowClick.pipe(take(1))); testingUtils.clickByCSS('[data-automation-id="datatable-row-1"] > div'); fixture.detectChanges(); await cellClickPromise; diff --git a/lib/process-services-cloud/src/lib/form/components/form-cloud.component.spec.ts b/lib/process-services-cloud/src/lib/form/components/form-cloud.component.spec.ts index 6f2be25c51..d850f6c17b 100644 --- a/lib/process-services-cloud/src/lib/form/components/form-cloud.component.spec.ts +++ b/lib/process-services-cloud/src/lib/form/components/form-cloud.component.spec.ts @@ -46,7 +46,7 @@ import { MatDialog } from '@angular/material/dialog'; import { MatDialogHarness } from '@angular/material/dialog/testing'; import { By } from '@angular/platform-browser'; import { TranslateLoader, TranslateService, provideTranslateService } from '@ngx-translate/core'; -import { Observable, of, throwError } from 'rxjs'; +import { firstValueFrom, Observable, of, throwError } from 'rxjs'; import { cloudFormMock, conditionalUploadWidgetsMock, @@ -1616,7 +1616,7 @@ describe('Multilingual Form', () => { formComponent.ngOnChanges({ appName: new SimpleChange(null, appName, true) }); expect(formCloudService.getForm).toHaveBeenCalledWith(appName, formId, 1); - await translateService.use('fr').toPromise(); + await firstValueFrom(translateService.use('fr')); fixture.detectChanges(); await fixture.whenStable(); @@ -1626,7 +1626,7 @@ describe('Multilingual Form', () => { expect(getLabelValue('dateField')).toEqual('Champ de date (D-M-YYYY)'); expect(getLabelValue('amountField')).toEqual('Champ Montant'); - await translateService.use('en').toPromise(); + await firstValueFrom(translateService.use('en')); fixture.detectChanges(); await fixture.whenStable(); diff --git a/lib/process-services-cloud/src/lib/form/services/content-cloud-node-selector.service.ts b/lib/process-services-cloud/src/lib/form/services/content-cloud-node-selector.service.ts index e702a64a50..9d029c1a14 100644 --- a/lib/process-services-cloud/src/lib/form/services/content-cloud-node-selector.service.ts +++ b/lib/process-services-cloud/src/lib/form/services/content-cloud-node-selector.service.ts @@ -20,7 +20,7 @@ import { NotificationService } from '@alfresco/adf-core'; import { MatDialog } from '@angular/material/dialog'; import { ContentNodeSelectorComponent, ContentNodeSelectorComponentData, NodeAction, AlfrescoApiService } from '@alfresco/adf-content-services'; import { Node, NodeEntry, NodesApi } from '@alfresco/js-api'; -import { from, Observable, Subject, throwError } from 'rxjs'; +import { firstValueFrom, from, Observable, Subject, throwError } from 'rxjs'; import { catchError, map, mapTo } from 'rxjs/operators'; import { DestinationFolderPathModel } from '../models/form-cloud-representation.model'; @@ -36,7 +36,11 @@ export class ContentCloudNodeSelectorService { sourceNodeNotFound = false; - constructor(private apiService: AlfrescoApiService, private notificationService: NotificationService, private dialog: MatDialog) {} + constructor( + private apiService: AlfrescoApiService, + private notificationService: NotificationService, + private dialog: MatDialog + ) {} openUploadFileDialog( currentFolderId?: string, @@ -65,25 +69,25 @@ export class ContentCloudNodeSelectorService { async getNodeIdFromPath(destinationFolderPath: DestinationFolderPathModel): Promise { if (destinationFolderPath.alias && destinationFolderPath.path) { try { - return await this.getNodeId(destinationFolderPath.alias, destinationFolderPath.path).toPromise(); + return await firstValueFrom(this.getNodeId(destinationFolderPath.alias, destinationFolderPath.path)); } catch { /*empty*/ } } - return this.getNodeId(destinationFolderPath.alias).toPromise(); + return firstValueFrom(this.getNodeId(destinationFolderPath.alias)); } async getNodeIdFromFolderVariableValue(variableValue: string, defaultAlias?: string): Promise { const isExistingNode = await this.isExistingNode(variableValue); - return isExistingNode ? variableValue : this.getNodeId(defaultAlias).toPromise(); + return isExistingNode ? variableValue : firstValueFrom(this.getNodeId(defaultAlias)); } async isExistingNode(nodeId: string): Promise { let isExistingNode = false; if (nodeId) { try { - isExistingNode = await this.getNodeId(nodeId).pipe(mapTo(true)).toPromise(); + isExistingNode = await firstValueFrom(this.getNodeId(nodeId).pipe(mapTo(true))); } catch { /*empty*/ } diff --git a/lib/process-services-cloud/src/lib/group/components/group-cloud.component.ts b/lib/process-services-cloud/src/lib/group/components/group-cloud.component.ts index 6f014d2204..7c9aecab3d 100644 --- a/lib/process-services-cloud/src/lib/group/components/group-cloud.component.ts +++ b/lib/process-services-cloud/src/lib/group/components/group-cloud.component.ts @@ -31,7 +31,7 @@ import { } from '@angular/core'; import { ReactiveFormsModule, UntypedFormControl } from '@angular/forms'; import { animate, state, style, transition, trigger } from '@angular/animations'; -import { BehaviorSubject, Observable } from 'rxjs'; +import { BehaviorSubject, firstValueFrom, Observable } from 'rxjs'; import { debounceTime, distinctUntilChanged, filter, mergeMap, switchMap, tap } from 'rxjs/operators'; import { ComponentSelectionMode } from '../../types'; import { IdentityGroupModel } from '../models/identity-group.model'; @@ -248,7 +248,7 @@ export class GroupCloudComponent implements OnInit, OnChanges { } private async searchGroup(name: string): Promise { - return (await this.identityGroupService.search(name).toPromise())[0]; + return (await firstValueFrom(this.identityGroupService.search(name)))[0]; } private getPreselectedGroups(): IdentityGroupModel[] { diff --git a/lib/process-services-cloud/src/lib/people/components/people-cloud.component.ts b/lib/process-services-cloud/src/lib/people/components/people-cloud.component.ts index b4c6aa3a0c..9553e88d6c 100644 --- a/lib/process-services-cloud/src/lib/people/components/people-cloud.component.ts +++ b/lib/process-services-cloud/src/lib/people/components/people-cloud.component.ts @@ -31,7 +31,7 @@ import { ViewChild, ViewEncapsulation } from '@angular/core'; -import { BehaviorSubject, Observable } from 'rxjs'; +import { BehaviorSubject, firstValueFrom, Observable } from 'rxjs'; import { debounceTime, distinctUntilChanged, filter, mergeMap, switchMap, tap } from 'rxjs/operators'; import { FullNamePipe, InitialUsernamePipe } from '@alfresco/adf-core'; import { animate, state, style, transition, trigger } from '@angular/animations'; @@ -368,9 +368,13 @@ export class PeopleCloudComponent implements OnInit, OnChanges, AfterViewInit { for (const user of this.getPreselectedUsers()) { try { const validationResult = ( - await this.identityUserService - .search(user.username, { roles: this.roles, withinApplication: this.appName, groups: this.groupsRestriction }) - .toPromise() + await firstValueFrom( + this.identityUserService.search(user.username, { + roles: this.roles, + withinApplication: this.appName, + groups: this.groupsRestriction + }) + ) )[0]; if (!this.equalsUsers(user, validationResult)) { diff --git a/lib/process-services-cloud/src/lib/process/process-filters/services/process-filter-cloud.service.spec.ts b/lib/process-services-cloud/src/lib/process/process-filters/services/process-filter-cloud.service.spec.ts index a426b4b5eb..97b9690fb2 100644 --- a/lib/process-services-cloud/src/lib/process/process-filters/services/process-filter-cloud.service.spec.ts +++ b/lib/process-services-cloud/src/lib/process/process-filters/services/process-filter-cloud.service.spec.ts @@ -246,7 +246,7 @@ describe('ProcessFilterCloudService', () => { changedFilter.processDefinitionKey = 'modifiedProcessDefinitionKey'; spyOn(service, 'defaultProcessFilters').and.returnValue(fakeProcessCloudFilters); - await service.resetProcessFilterToDefaults('mock-appName', changedFilter).toPromise(); + await firstValueFrom(service.resetProcessFilterToDefaults('mock-appName', changedFilter)); expect(updatePreferenceSpy).toHaveBeenCalledWith('mock-appName', 'process-filters-mock-appName-mock-username', fakeProcessCloudFilters); }); diff --git a/lib/process-services-cloud/src/lib/process/process-list/services/process-list-cloud.service.spec.ts b/lib/process-services-cloud/src/lib/process/process-list/services/process-list-cloud.service.spec.ts index 9ae668a52f..dcc0322f93 100644 --- a/lib/process-services-cloud/src/lib/process/process-list/services/process-list-cloud.service.spec.ts +++ b/lib/process-services-cloud/src/lib/process/process-list/services/process-list-cloud.service.spec.ts @@ -182,7 +182,7 @@ describe('ProcessListCloudService', () => { it('should append to the call all the parameters', async () => { const processRequest = { appName: 'fakeName', skipCount: 0, maxItems: 20, service: 'fake-service' } as ProcessQueryCloudRequestModel; requestSpy.and.callFake(returnCallQueryParameters); - const request = await service.getAdminProcessByRequest(processRequest).toPromise(); + const request = await firstValueFrom(service.getAdminProcessByRequest(processRequest)); expect(request).toBeDefined(); expect(request).not.toBeNull(); @@ -194,7 +194,7 @@ describe('ProcessListCloudService', () => { it('should concat the app name to the request url', async () => { const processRequest = { appName: 'fakeName', skipCount: 0, maxItems: 20, service: 'fake-service' } as ProcessQueryCloudRequestModel; requestSpy.and.callFake(returnCallUrl); - const requestUrl = await service.getAdminProcessByRequest(processRequest).toPromise(); + const requestUrl = await firstValueFrom(service.getAdminProcessByRequest(processRequest)); expect(requestUrl).toBeDefined(); expect(requestUrl).not.toBeNull(); @@ -213,7 +213,7 @@ describe('ProcessListCloudService', () => { ] } as ProcessQueryCloudRequestModel; requestSpy.and.callFake(returnCallQueryParameters); - const request = await service.getAdminProcessByRequest(processRequest).toPromise(); + const request = await firstValueFrom(service.getAdminProcessByRequest(processRequest)); expect(request).toBeDefined(); expect(request).not.toBeNull(); @@ -225,7 +225,7 @@ describe('ProcessListCloudService', () => { requestSpy.and.callFake(returnCallUrl); try { - await service.getAdminProcessByRequest(processRequest).toPromise(); + await firstValueFrom(service.getAdminProcessByRequest(processRequest)); fail('Should have thrown error'); } catch (error) { @@ -236,7 +236,7 @@ describe('ProcessListCloudService', () => { it('should make post request', async () => { const processRequest = { appName: 'fakeName', skipCount: 0, maxItems: 20, service: 'fake-service' } as ProcessQueryCloudRequestModel; requestSpy.and.callFake(returnCallOperation); - const adminProcessResponse = await service.getAdminProcessByRequest(processRequest).toPromise(); + const adminProcessResponse = await firstValueFrom(service.getAdminProcessByRequest(processRequest)); expect(adminProcessResponse).toBeDefined(); expect(adminProcessResponse).not.toBeNull(); expect(adminProcessResponse.httpMethod).toBe('POST'); @@ -251,7 +251,7 @@ describe('ProcessListCloudService', () => { variableKeys: ['test-one', 'test-two'] } as ProcessQueryCloudRequestModel; requestSpy.and.callFake(returnCallQueryParameters); - const requestParams = await service.getAdminProcessByRequest(processRequest).toPromise(); + const requestParams = await firstValueFrom(service.getAdminProcessByRequest(processRequest)); expect(requestParams).toBeDefined(); expect(requestParams).not.toBeNull(); @@ -267,7 +267,7 @@ describe('ProcessListCloudService', () => { variableKeys: ['test-one', 'test-two'] } as ProcessQueryCloudRequestModel; requestSpy.and.callFake(returnCallBody); - const requestBodyParams = await service.getAdminProcessByRequest(processRequest).toPromise(); + const requestBodyParams = await firstValueFrom(service.getAdminProcessByRequest(processRequest)); expect(requestBodyParams).toBeDefined(); expect(requestBodyParams).not.toBeNull(); diff --git a/lib/process-services-cloud/src/lib/process/start-process/services/start-process-cloud.service.spec.ts b/lib/process-services-cloud/src/lib/process/start-process/services/start-process-cloud.service.spec.ts index 6a4df24c1f..c649c831d9 100755 --- a/lib/process-services-cloud/src/lib/process/start-process/services/start-process-cloud.service.spec.ts +++ b/lib/process-services-cloud/src/lib/process/start-process/services/start-process-cloud.service.spec.ts @@ -16,7 +16,7 @@ */ import { TestBed } from '@angular/core/testing'; -import { of, throwError } from 'rxjs'; +import { firstValueFrom, of, throwError } from 'rxjs'; import { StartProcessCloudService } from './start-process-cloud.service'; import { fakeProcessPayload } from '../mock/start-process.component.mock'; import { ProcessDefinitionCloud } from '../../../models/process-definition-cloud.model'; @@ -37,7 +37,7 @@ describe('StartProcessCloudService', () => { it('should be able to create a new process', async () => { spyOn(service, 'startProcess').and.returnValue(of({ id: 'fake-id', name: 'fake-name' })); - const result = await service.startProcess('appName1', fakeProcessPayload).toPromise(); + const result = await firstValueFrom(service.startProcess('appName1', fakeProcessPayload)); expect(result).toBeDefined(); expect(result.id).toEqual('fake-id'); @@ -46,7 +46,7 @@ describe('StartProcessCloudService', () => { it('should be able to create a new process with form', async () => { spyOn(service, 'startProcessWithForm').and.returnValue(of({ id: 'fake-id', name: 'fake-name' })); - const result = await service.startProcessWithForm('appName1', 'mockFormId', 1, fakeProcessPayload).toPromise(); + const result = await firstValueFrom(service.startProcessWithForm('appName1', 'mockFormId', 1, fakeProcessPayload)); expect(result).toBeDefined(); expect(result.id).toEqual('fake-id'); @@ -61,14 +61,11 @@ describe('StartProcessCloudService', () => { }); spyOn(service, 'startProcess').and.returnValue(throwError(errorResponse)); - const result = await service - .startProcess('appName1', fakeProcessPayload) - .toPromise() - .catch((error) => { - expect(error.status).toEqual(404); - expect(error.statusText).toEqual('Not Found'); - expect(error.error).toEqual('Mock Error'); - }); + const result = await firstValueFrom(service.startProcess('appName1', fakeProcessPayload)).catch((error) => { + expect(error.status).toEqual(404); + expect(error.statusText).toEqual('Not Found'); + expect(error.error).toEqual('Mock Error'); + }); if (result) { fail('expected an error, not applications'); @@ -77,7 +74,7 @@ describe('StartProcessCloudService', () => { it('should be able to get all the process definitions', async () => { spyOn(service, 'getProcessDefinitions').and.returnValue(of([new ProcessDefinitionCloud({ id: 'fake-id', name: 'fake-name' })])); - const result = await service.getProcessDefinitions('appName1').toPromise(); + const result = await firstValueFrom(service.getProcessDefinitions('appName1')); expect(result).toBeDefined(); expect(result[0].id).toEqual('fake-id'); @@ -91,14 +88,11 @@ describe('StartProcessCloudService', () => { statusText: 'Not Found' }); spyOn(service, 'getProcessDefinitions').and.returnValue(throwError(errorResponse)); - const result = await service - .getProcessDefinitions('appName1') - .toPromise() - .catch((error) => { - expect(error.status).toEqual(404); - expect(error.statusText).toEqual('Not Found'); - expect(error.error).toEqual('Mock Error'); - }); + const result = await firstValueFrom(service.getProcessDefinitions('appName1')).catch((error) => { + expect(error.status).toEqual(404); + expect(error.statusText).toEqual('Not Found'); + expect(error.error).toEqual('Mock Error'); + }); if (result) { fail('expected an error, not applications'); @@ -111,7 +105,7 @@ describe('StartProcessCloudService', () => { const requestSpy = spyOn(adfHttpClient, 'request'); requestSpy.and.returnValue(Promise.resolve({ static1: 'value', static2: 0, static3: true })); - const result = await service.getStartEventFormStaticValuesMapping(appName, processDefinitionId).toPromise(); + const result = await firstValueFrom(service.getStartEventFormStaticValuesMapping(appName, processDefinitionId)); expect(result.length).toEqual(3); expect(result[0].name).toEqual('static1'); expect(result[0].id).toEqual('static1'); @@ -132,7 +126,7 @@ describe('StartProcessCloudService', () => { const requestSpy = spyOn(adfHttpClient, 'request'); requestSpy.and.returnValue(Promise.resolve({ constant1: 'value', constant2: '0', constant3: 'true' })); - const result = await service.getStartEventConstants(appName, processDefinitionId).toPromise(); + const result = await firstValueFrom(service.getStartEventConstants(appName, processDefinitionId)); expect(result.length).toEqual(3); expect(result[0].name).toEqual('constant1'); diff --git a/lib/process-services-cloud/src/lib/task/task-form/components/user-task-cloud-buttons/claim-task/claim-task-cloud.directive.ts b/lib/process-services-cloud/src/lib/task/task-form/components/user-task-cloud-buttons/claim-task/claim-task-cloud.directive.ts index e9df114cfd..5c16642d01 100644 --- a/lib/process-services-cloud/src/lib/task/task-form/components/user-task-cloud-buttons/claim-task/claim-task-cloud.directive.ts +++ b/lib/process-services-cloud/src/lib/task/task-form/components/user-task-cloud-buttons/claim-task/claim-task-cloud.directive.ts @@ -18,6 +18,7 @@ import { Directive, Input, HostListener, Output, EventEmitter, OnInit, ElementRef, Renderer2 } from '@angular/core'; import { IdentityUserService } from '../../../../../people/services/identity-user.service'; import { TaskCloudService } from '../../../../services/task-cloud.service'; +import { firstValueFrom } from 'rxjs'; @Directive({ // eslint-disable-next-line @angular-eslint/directive-selector @@ -86,7 +87,7 @@ export class ClaimTaskCloudDirective implements OnInit { const currentUser: string = this.identityUserService.getCurrentUserInfo().username; try { this.renderer.setAttribute(this.el.nativeElement, 'disabled', 'true'); - const result = await this.taskListService.claimTask(this.appName, this.taskId, currentUser).toPromise(); + const result = await firstValueFrom(this.taskListService.claimTask(this.appName, this.taskId, currentUser)); if (result) { this.success.emit(result); } diff --git a/lib/process-services-cloud/src/lib/task/task-form/components/user-task-cloud-buttons/unclaim-task/unclaim-task-cloud.directive.ts b/lib/process-services-cloud/src/lib/task/task-form/components/user-task-cloud-buttons/unclaim-task/unclaim-task-cloud.directive.ts index 40b9c4fa6e..23d1aa4957 100644 --- a/lib/process-services-cloud/src/lib/task/task-form/components/user-task-cloud-buttons/unclaim-task/unclaim-task-cloud.directive.ts +++ b/lib/process-services-cloud/src/lib/task/task-form/components/user-task-cloud-buttons/unclaim-task/unclaim-task-cloud.directive.ts @@ -17,6 +17,7 @@ import { Directive, Input, HostListener, Output, EventEmitter, OnInit, ElementRef, Renderer2 } from '@angular/core'; import { TaskCloudService } from '../../../../services/task-cloud.service'; +import { firstValueFrom } from 'rxjs'; @Directive({ // eslint-disable-next-line @angular-eslint/directive-selector @@ -41,7 +42,11 @@ export class UnClaimTaskCloudDirective implements OnInit { invalidParams: string[] = []; - constructor(private readonly el: ElementRef, private readonly renderer: Renderer2, private taskListService: TaskCloudService) {} + constructor( + private readonly el: ElementRef, + private readonly renderer: Renderer2, + private taskListService: TaskCloudService + ) {} ngOnInit() { this.validateInputs(); @@ -71,7 +76,7 @@ export class UnClaimTaskCloudDirective implements OnInit { async onClick() { try { this.renderer.setAttribute(this.el.nativeElement, 'disabled', 'true'); - await this.taskListService.unclaimTask(this.appName, this.taskId).toPromise(); + await firstValueFrom(this.taskListService.unclaimTask(this.appName, this.taskId)); this.success.emit(this.taskId); } catch (error) { this.renderer.removeAttribute(this.el.nativeElement, 'disabled'); diff --git a/lib/process-services-cloud/src/lib/task/task-form/components/user-task-cloud/complete-task/complete-task.directive.ts b/lib/process-services-cloud/src/lib/task/task-form/components/user-task-cloud/complete-task/complete-task.directive.ts index 9510193360..cb558b9272 100644 --- a/lib/process-services-cloud/src/lib/task/task-form/components/user-task-cloud/complete-task/complete-task.directive.ts +++ b/lib/process-services-cloud/src/lib/task/task-form/components/user-task-cloud/complete-task/complete-task.directive.ts @@ -17,6 +17,7 @@ import { Directive, Input, HostListener, Output, EventEmitter, OnInit, ElementRef, Renderer2 } from '@angular/core'; import { TaskCloudService } from '../../../../services/task-cloud.service'; +import { firstValueFrom } from 'rxjs'; @Directive({ // eslint-disable-next-line @angular-eslint/directive-selector @@ -41,7 +42,11 @@ export class CompleteTaskDirective implements OnInit { invalidParams: string[] = []; - constructor(private readonly el: ElementRef, private readonly renderer: Renderer2, private readonly taskListService: TaskCloudService) {} + constructor( + private readonly el: ElementRef, + private readonly renderer: Renderer2, + private readonly taskListService: TaskCloudService + ) {} ngOnInit() { this.validateInputs(); @@ -71,7 +76,7 @@ export class CompleteTaskDirective implements OnInit { async onClick() { try { this.renderer.setAttribute(this.el.nativeElement, 'disabled', 'true'); - const result = await this.taskListService.completeTask(this.appName, this.taskId).toPromise(); + const result = await firstValueFrom(this.taskListService.completeTask(this.appName, this.taskId)); if (result) { this.success.emit(result); } diff --git a/lib/process-services-cloud/src/lib/task/task-list/services/service-task-list-cloud.service.spec.ts b/lib/process-services-cloud/src/lib/task/task-list/services/service-task-list-cloud.service.spec.ts index ff4675d8ba..15c0aa254b 100644 --- a/lib/process-services-cloud/src/lib/task/task-list/services/service-task-list-cloud.service.spec.ts +++ b/lib/process-services-cloud/src/lib/task/task-list/services/service-task-list-cloud.service.spec.ts @@ -18,7 +18,7 @@ import { TestBed } from '@angular/core/testing'; import { ServiceTaskListCloudService } from './service-task-list-cloud.service'; import { ServiceTaskQueryCloudRequestModel } from '../models/service-task-cloud.model'; -import { of } from 'rxjs'; +import { firstValueFrom, of } from 'rxjs'; import { AdfHttpClient } from '@alfresco/adf-core/api'; import { NoopTranslateModule } from '@alfresco/adf-core'; @@ -112,56 +112,44 @@ describe('Activiti ServiceTaskList Cloud Service', () => { const spyOnPost = spyOn(service, 'post').and.returnValue(of({})); const params = ['fakeName', 'executionId_1', 'flowNodeId_1'] as const; - await service.replayServiceTaskRequest(...params).toPromise(); + await firstValueFrom(service.replayServiceTaskRequest(...params)); expect(spyOnPost).toHaveBeenCalledWith(expected.expectedQueryUrl, expected.expectedPayload); }); it('should throw an exeption and execute logService error if appName is null', (done) => { const expectedErrorMessage = 'Appname/executionId/flowNodeId not configured'; const params = [null, 'executionId_1', 'flowNodeId_1'] as const; - service - .replayServiceTaskRequest(...params) - .toPromise() - .catch((error) => { - expect(error).toEqual(expectedErrorMessage); - done(); - }); + firstValueFrom(service.replayServiceTaskRequest(...params)).catch((error) => { + expect(error).toEqual(expectedErrorMessage); + done(); + }); }); it('should throw an exeption and execute logService error if executionId is null', (done) => { const expectedErrorMessage = 'Appname/executionId/flowNodeId not configured'; const params = ['fakeName', null, 'flowNodeId_1'] as const; - service - .replayServiceTaskRequest(...params) - .toPromise() - .catch((error) => { - expect(error).toEqual(expectedErrorMessage); - done(); - }); + firstValueFrom(service.replayServiceTaskRequest(...params)).catch((error) => { + expect(error).toEqual(expectedErrorMessage); + done(); + }); }); it('should throw an exeption and execute logService error if flowNodeId is null', (done) => { const expectedErrorMessage = 'Appname/executionId/flowNodeId not configured'; const params = ['fakeName', 'executionId_1', null] as const; - service - .replayServiceTaskRequest(...params) - .toPromise() - .catch((error) => { - expect(error).toEqual(expectedErrorMessage); - done(); - }); + firstValueFrom(service.replayServiceTaskRequest(...params)).catch((error) => { + expect(error).toEqual(expectedErrorMessage); + done(); + }); }); it('should throw an exeption and execute logService error if appName, executionId and flowNodeId are null', (done) => { const expectedErrorMessage = 'Appname/executionId/flowNodeId not configured'; const params = [null, null, null] as const; - service - .replayServiceTaskRequest(...params) - .toPromise() - .catch((error) => { - expect(error).toEqual(expectedErrorMessage); - done(); - }); + firstValueFrom(service.replayServiceTaskRequest(...params)).catch((error) => { + expect(error).toEqual(expectedErrorMessage); + done(); + }); }); }); }); diff --git a/lib/process-services/src/lib/form/widgets/functional-group/functional-group.widget.spec.ts b/lib/process-services/src/lib/form/widgets/functional-group/functional-group.widget.spec.ts index 8f80e88ab0..d80822d874 100644 --- a/lib/process-services/src/lib/form/widgets/functional-group/functional-group.widget.spec.ts +++ b/lib/process-services/src/lib/form/widgets/functional-group/functional-group.widget.spec.ts @@ -15,7 +15,7 @@ * limitations under the License. */ -import { of, timer } from 'rxjs'; +import { firstValueFrom, of, timer } from 'rxjs'; import { FormFieldModel, FormModel, GroupModel, FormFieldTypes, UnitTestingUtils } from '@alfresco/adf-core'; import { FunctionalGroupWidgetComponent } from './functional-group.widget'; import { ComponentFixture, TestBed } from '@angular/core/testing'; @@ -64,7 +64,7 @@ describe('FunctionalGroupWidgetComponent', () => { component.searchTerm.setValue(text); fixture.detectChanges(); - await timer(300).toPromise(); + await firstValueFrom(timer(300)); await fixture.whenStable(); fixture.detectChanges();