diff --git a/projects/aca-content/src/lib/components/view-profile/view-profile.guard.ts b/projects/aca-content/src/lib/components/view-profile/view-profile.guard.ts
index 2fd170aa59..eebda82213 100644
--- a/projects/aca-content/src/lib/components/view-profile/view-profile.guard.ts
+++ b/projects/aca-content/src/lib/components/view-profile/view-profile.guard.ts
@@ -22,22 +22,16 @@
* from Hyland Software. If not, see .
*/
-import { Injectable } from '@angular/core';
-import { CanActivate } from '@angular/router';
-import { Observable } from 'rxjs';
+import { inject } from '@angular/core';
+import { CanActivateFn } from '@angular/router';
import { AuthenticationService } from '@alfresco/adf-core';
-@Injectable({
- providedIn: 'root'
-})
-export class ViewProfileRuleGuard implements CanActivate {
- constructor(private authService: AuthenticationService) {}
+export const ViewProfileRuleGuard: CanActivateFn = () => {
+ const authService = inject(AuthenticationService);
- canActivate(): Observable | Promise | boolean {
- return this.isEcmLoggedIn() || this.authService.isOauth();
- }
+ const isEcmLoggedIn = (): boolean => {
+ return authService.isEcmLoggedIn() || (authService.isECMProvider() && authService.isKerberosEnabled());
+ };
- private isEcmLoggedIn(): boolean {
- return this.authService.isEcmLoggedIn() || (this.authService.isECMProvider() && this.authService.isKerberosEnabled());
- }
-}
+ return isEcmLoggedIn() || authService.isOauth();
+};
diff --git a/projects/aca-shared/src/lib/adf-extensions/extensions-data-loader.guard.spec.ts b/projects/aca-shared/src/lib/adf-extensions/extensions-data-loader.guard.spec.ts
index ea49e4ddfb..4cbbd5288c 100644
--- a/projects/aca-shared/src/lib/adf-extensions/extensions-data-loader.guard.spec.ts
+++ b/projects/aca-shared/src/lib/adf-extensions/extensions-data-loader.guard.spec.ts
@@ -22,9 +22,10 @@
* from Hyland Software. If not, see .
*/
-import { ExtensionsDataLoaderGuard } from './extensions-data-loader.guard';
-import { ActivatedRouteSnapshot } from '@angular/router';
-import { Subject, throwError } from 'rxjs';
+import { EXTENSION_DATA_LOADERS, ExtensionsDataLoaderGuard, resetInvoked } from './extensions-data-loader.guard';
+import { ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router';
+import { TestBed } from '@angular/core/testing';
+import { Observable, Subject, throwError } from 'rxjs';
describe('ExtensionsDataLoaderGuard', () => {
let route: ActivatedRouteSnapshot;
@@ -32,108 +33,110 @@ describe('ExtensionsDataLoaderGuard', () => {
let completedSpy;
let erroredSpy;
- describe('canActivate', () => {
- beforeEach(() => {
- route = {} as ActivatedRouteSnapshot;
- emittedSpy = jasmine.createSpy('emitted');
- completedSpy = jasmine.createSpy('completed');
- erroredSpy = jasmine.createSpy('errored');
- });
-
- it('should emit true and complete if no callback are present', () => {
- const guard = new ExtensionsDataLoaderGuard([]);
-
- guard.canActivate(route).subscribe(emittedSpy, erroredSpy, completedSpy);
- expect(emittedSpy).toHaveBeenCalledWith(true);
- expect(erroredSpy).not.toHaveBeenCalled();
- expect(completedSpy).toHaveBeenCalled();
- });
-
- it('should emit true and complete in case of only one callback is present, completed', () => {
- const subject = new Subject();
- const guard = new ExtensionsDataLoaderGuard([() => subject.asObservable()]);
-
- guard.canActivate(route).subscribe(emittedSpy, erroredSpy, completedSpy);
-
- subject.next(true);
- expect(emittedSpy).not.toHaveBeenCalled();
- expect(erroredSpy).not.toHaveBeenCalled();
- expect(completedSpy).not.toHaveBeenCalled();
-
- subject.complete();
- expect(emittedSpy).toHaveBeenCalledWith(true);
- expect(erroredSpy).not.toHaveBeenCalled();
- expect(completedSpy).toHaveBeenCalled();
- });
-
- it('should emit true and complete in case of only one callback is present, errored', () => {
- const guard = new ExtensionsDataLoaderGuard([() => throwError(new Error())]);
-
- guard.canActivate(route).subscribe(emittedSpy, erroredSpy, completedSpy);
- expect(emittedSpy).toHaveBeenCalledWith(true);
- expect(erroredSpy).not.toHaveBeenCalled();
- expect(completedSpy).toHaveBeenCalled();
- });
-
- it('should NOT complete in case of multiple callbacks are present and not all of them have been completed', () => {
- const subject1 = new Subject();
- const subject2 = new Subject();
- const guard = new ExtensionsDataLoaderGuard([() => subject1.asObservable(), () => subject2.asObservable()]);
-
- guard.canActivate(route).subscribe(emittedSpy, erroredSpy, completedSpy);
-
- subject1.next();
- subject2.next();
- subject1.complete();
- expect(emittedSpy).not.toHaveBeenCalled();
- expect(erroredSpy).not.toHaveBeenCalled();
- expect(completedSpy).not.toHaveBeenCalled();
- });
-
- it('should emit true and complete in case of multiple callbacks are present and all of them have been completed', () => {
- const subject1 = new Subject();
- const subject2 = new Subject();
- const guard = new ExtensionsDataLoaderGuard([() => subject1.asObservable(), () => subject2.asObservable()]);
-
- guard.canActivate(route).subscribe(emittedSpy, erroredSpy, completedSpy);
-
- subject1.next();
- subject2.next();
- subject1.complete();
- subject2.complete();
- expect(emittedSpy).toHaveBeenCalledWith(true);
- expect(erroredSpy).not.toHaveBeenCalled();
- expect(completedSpy).toHaveBeenCalled();
- });
-
- it('should emit true and complete even if one of the observables are errored, to not block the application loading', () => {
- const subject1 = new Subject();
- const guard = new ExtensionsDataLoaderGuard([() => subject1.asObservable(), () => throwError(new Error())]);
-
- guard.canActivate(route).subscribe(emittedSpy, erroredSpy, completedSpy);
-
- subject1.next();
- expect(emittedSpy).toHaveBeenCalledWith(true);
- expect(erroredSpy).not.toHaveBeenCalled();
- expect(completedSpy).toHaveBeenCalled();
- });
-
- it('should call canActivate only once', () => {
- const subject1 = new Subject();
- const extensionLoaders = {
- fct1: () => subject1.asObservable()
- };
- const extensionLoaderSpy = spyOn(extensionLoaders, 'fct1').and.callThrough();
- const guard = new ExtensionsDataLoaderGuard([extensionLoaders.fct1]);
-
- guard.canActivate(route).subscribe(emittedSpy, erroredSpy, completedSpy);
- expect(extensionLoaderSpy).toHaveBeenCalled();
-
- extensionLoaderSpy.calls.reset();
- subject1.next(true);
- subject1.complete();
- guard.canActivate(route).subscribe(emittedSpy, erroredSpy, completedSpy);
- expect(extensionLoaderSpy).not.toHaveBeenCalled();
- });
+ const setupTest = (extensionDataLoaders: any[]) => {
+ TestBed.overrideProvider(EXTENSION_DATA_LOADERS, { useValue: extensionDataLoaders });
+ return TestBed.runInInjectionContext(() => ExtensionsDataLoaderGuard(route, {} as RouterStateSnapshot)) as Observable;
+ };
+
+ beforeEach(() => {
+ route = {} as ActivatedRouteSnapshot;
+ emittedSpy = jasmine.createSpy('emitted');
+ completedSpy = jasmine.createSpy('completed');
+ erroredSpy = jasmine.createSpy('errored');
+ resetInvoked();
+ });
+
+ it('should emit true and complete if no callback are present', () => {
+ const guard = setupTest([]);
+ guard.subscribe(emittedSpy, erroredSpy, completedSpy);
+ expect(emittedSpy).toHaveBeenCalledWith(true);
+ expect(erroredSpy).not.toHaveBeenCalled();
+ expect(completedSpy).toHaveBeenCalled();
+ });
+
+ it('should emit true and complete in case of only one callback is present, completed', () => {
+ const subject = new Subject();
+ const guard = setupTest([() => subject.asObservable()]);
+ guard.subscribe(emittedSpy, erroredSpy, completedSpy);
+ subject.next(true);
+ expect(emittedSpy).not.toHaveBeenCalled();
+ expect(erroredSpy).not.toHaveBeenCalled();
+ expect(completedSpy).not.toHaveBeenCalled();
+
+ subject.complete();
+ expect(emittedSpy).toHaveBeenCalledWith(true);
+ expect(erroredSpy).not.toHaveBeenCalled();
+ expect(completedSpy).toHaveBeenCalled();
+ });
+
+ it('should emit true and complete in case of only one callback is present, errored', () => {
+ const guard = setupTest([() => throwError(new Error())]);
+ guard.subscribe(emittedSpy, erroredSpy, completedSpy);
+
+ expect(emittedSpy).toHaveBeenCalledWith(true);
+ expect(erroredSpy).not.toHaveBeenCalled();
+ expect(completedSpy).toHaveBeenCalled();
+ });
+
+ it('should NOT complete in case of multiple callbacks are present and not all of them have been completed', () => {
+ const subject1 = new Subject();
+ const subject2 = new Subject();
+ const guard = setupTest([() => subject1.asObservable(), () => subject2.asObservable()]);
+
+ guard.subscribe(emittedSpy, erroredSpy, completedSpy);
+ subject1.next();
+ subject2.next();
+ subject1.complete();
+
+ expect(emittedSpy).not.toHaveBeenCalled();
+ expect(erroredSpy).not.toHaveBeenCalled();
+ expect(completedSpy).not.toHaveBeenCalled();
+ });
+
+ it('should emit true and complete in case of multiple callbacks are present and all of them have been completed', () => {
+ const subject1 = new Subject();
+ const subject2 = new Subject();
+ const guard = setupTest([() => subject1.asObservable(), () => subject2.asObservable()]);
+
+ guard.subscribe(emittedSpy, erroredSpy, completedSpy);
+ subject1.next();
+ subject2.next();
+ subject1.complete();
+ subject2.complete();
+
+ expect(emittedSpy).toHaveBeenCalledWith(true);
+ expect(erroredSpy).not.toHaveBeenCalled();
+ expect(completedSpy).toHaveBeenCalled();
+ });
+
+ it('should emit true and complete even if one of the observables are errored, to not block the application loading', () => {
+ const subject1 = new Subject();
+ const guard = setupTest([() => subject1.asObservable(), () => throwError(new Error())]);
+
+ guard.subscribe(emittedSpy, erroredSpy, completedSpy);
+ subject1.next();
+
+ expect(emittedSpy).toHaveBeenCalledWith(true);
+ expect(erroredSpy).not.toHaveBeenCalled();
+ expect(completedSpy).toHaveBeenCalled();
+ });
+
+ it('should call canActivate only once', () => {
+ const subject1 = new Subject();
+ const extensionLoaders = {
+ fct1: () => subject1.asObservable()
+ };
+ const extensionLoaderSpy = spyOn(extensionLoaders, 'fct1').and.callThrough();
+ const guard = setupTest([extensionLoaders.fct1]);
+
+ guard.subscribe(emittedSpy, erroredSpy, completedSpy);
+ expect(extensionLoaderSpy).toHaveBeenCalled();
+
+ extensionLoaderSpy.calls.reset();
+ subject1.next(true);
+ subject1.complete();
+
+ guard.subscribe(emittedSpy, erroredSpy, completedSpy);
+ expect(extensionLoaderSpy).not.toHaveBeenCalled();
});
});
diff --git a/projects/aca-shared/src/lib/adf-extensions/extensions-data-loader.guard.ts b/projects/aca-shared/src/lib/adf-extensions/extensions-data-loader.guard.ts
index f79352486b..d9a5aa0e9c 100644
--- a/projects/aca-shared/src/lib/adf-extensions/extensions-data-loader.guard.ts
+++ b/projects/aca-shared/src/lib/adf-extensions/extensions-data-loader.guard.ts
@@ -22,8 +22,8 @@
* from Hyland Software. If not, see .
*/
-import { Injectable, InjectionToken, Inject } from '@angular/core';
-import { CanActivate, ActivatedRouteSnapshot } from '@angular/router';
+import { InjectionToken, inject } from '@angular/core';
+import { ActivatedRouteSnapshot, CanActivateFn } from '@angular/router';
import { Observable, forkJoin, of } from 'rxjs';
import { tap, map, catchError } from 'rxjs/operators';
@@ -36,44 +36,37 @@ export const EXTENSION_DATA_LOADERS = new InjectionToken {
- if (!this.invoked) {
- if (!this.extensionDataLoaders.length) {
- this.invoked = true;
- return of(true);
- }
-
- const dataLoaderCallbacks = this.extensionDataLoaders.map((callback) => callback(route));
-
- // Undocumented forkJoin behaviour/bug:
- // https://github.com/ReactiveX/rxjs/issues/3246
- // So all callbacks need to emit before completion, otherwise forkJoin will short circuit
- return forkJoin(...dataLoaderCallbacks).pipe(
- map(() => true),
- tap(() => (this.invoked = true)),
- catchError((e) => {
- // eslint-disable-next-line no-console
- console.error('Some of the extension data loader guards has been errored.');
- // eslint-disable-next-line no-console
- console.error(e);
- return of(true);
- })
- );
- } else {
+export const ExtensionsDataLoaderGuard: CanActivateFn = (route: ActivatedRouteSnapshot): Observable => {
+ const extensionDataLoaders = inject(EXTENSION_DATA_LOADERS);
+ if (!invoked) {
+ if (!extensionDataLoaders.length) {
+ invoked = true;
return of(true);
}
- }
- canActivateChild(): Observable {
+ const dataLoaderCallbacks = extensionDataLoaders.map((callback) => callback(route));
+
+ // Undocumented forkJoin behaviour/bug:
+ // https://github.com/ReactiveX/rxjs/issues/3246
+ // So all callbacks need to emit before completion, otherwise forkJoin will short circuit
+ return forkJoin(...dataLoaderCallbacks).pipe(
+ map(() => true),
+ tap(() => (invoked = true)),
+ catchError((e) => {
+ // eslint-disable-next-line no-console
+ console.error('Some of the extension data loader guards has been errored.');
+ // eslint-disable-next-line no-console
+ console.error(e);
+ return of(true);
+ })
+ );
+ } else {
return of(true);
}
-}
+};
+
+export const resetInvoked = () => {
+ invoked = false;
+};
diff --git a/projects/aca-shared/src/lib/routing/plugin-enabled.guard.spec.ts b/projects/aca-shared/src/lib/routing/plugin-enabled.guard.spec.ts
index 011477925e..819cc2ffed 100644
--- a/projects/aca-shared/src/lib/routing/plugin-enabled.guard.spec.ts
+++ b/projects/aca-shared/src/lib/routing/plugin-enabled.guard.spec.ts
@@ -25,11 +25,10 @@
import { AppConfigService } from '@alfresco/adf-core';
import { TestBed } from '@angular/core/testing';
import { PluginEnabledGuard } from './plugin-enabled.guard';
-import { ActivatedRouteSnapshot, Router } from '@angular/router';
+import { ActivatedRouteSnapshot, Router, RouterStateSnapshot } from '@angular/router';
import { HttpClientTestingModule } from '@angular/common/http/testing';
describe('PluginEnabledGuard', () => {
- let service: PluginEnabledGuard;
let getSpy: jasmine.Spy<(key: string, defaultValue?: boolean) => boolean>;
let route: ActivatedRouteSnapshot;
@@ -37,7 +36,6 @@ describe('PluginEnabledGuard', () => {
TestBed.configureTestingModule({
imports: [HttpClientTestingModule]
});
- service = TestBed.inject(PluginEnabledGuard);
getSpy = spyOn(TestBed.inject(AppConfigService), 'get');
route = new ActivatedRouteSnapshot();
route.data = {
@@ -45,41 +43,31 @@ describe('PluginEnabledGuard', () => {
};
});
- describe('canActivate', () => {
- it('should call appConfigService.get with correct parameters', () => {
- service.canActivate(route);
- expect(getSpy).toHaveBeenCalledWith(route.data.plugin, true);
- });
-
- it('should return true if appConfigService.get returns true', () => {
- getSpy.and.returnValue(true);
-
- expect(service.canActivate(route)).toBeTrue();
- });
+ it('should call appConfigService.get with correct parameters', () => {
+ TestBed.runInInjectionContext(() => PluginEnabledGuard(route, {} as RouterStateSnapshot));
+ expect(getSpy).toHaveBeenCalledWith(route.data.plugin, true);
+ });
- it('should return false if appConfigService.get returns false', () => {
- getSpy.and.returnValue(true);
+ it('should return true if appConfigService.get returns true', () => {
+ getSpy.and.returnValue(true);
+ const result = TestBed.runInInjectionContext(() => PluginEnabledGuard(route, {} as RouterStateSnapshot));
- expect(service.canActivate(route)).toBeTrue();
- });
-
- it('should navigate to root if plugin is not enabled', () => {
- getSpy.and.returnValue(false);
- const routerSpy = spyOn(TestBed.inject(Router), 'navigate');
+ expect(result).toBeTrue();
+ });
- service.canActivate(route);
+ it('should return false if appConfigService.get returns false', () => {
+ getSpy.and.returnValue(false);
+ const result = TestBed.runInInjectionContext(() => PluginEnabledGuard(route, {} as RouterStateSnapshot));
- expect(routerSpy).toHaveBeenCalledWith(['/']);
- });
+ expect(result).toBeFalse();
});
- describe('canActivateChild', () => {
- it('should call canActivate with the same route and return its result', () => {
- spyOn(service, 'canActivate').and.callThrough();
- const result = service.canActivateChild(route);
+ it('should navigate to root if plugin is not enabled', () => {
+ getSpy.and.returnValue(false);
+ const routerSpy = spyOn(TestBed.inject(Router), 'navigate');
- expect(service.canActivate).toHaveBeenCalledWith(route);
- expect(result).toBe(service.canActivate(route));
- });
+ TestBed.runInInjectionContext(() => PluginEnabledGuard(route, {} as RouterStateSnapshot));
+
+ expect(routerSpy).toHaveBeenCalledWith(['/']);
});
});
diff --git a/projects/aca-shared/src/lib/routing/plugin-enabled.guard.ts b/projects/aca-shared/src/lib/routing/plugin-enabled.guard.ts
index e8ac2ce284..b2a5a0e657 100644
--- a/projects/aca-shared/src/lib/routing/plugin-enabled.guard.ts
+++ b/projects/aca-shared/src/lib/routing/plugin-enabled.guard.ts
@@ -22,27 +22,19 @@
* from Hyland Software. If not, see .
*/
-import { ActivatedRouteSnapshot, CanActivate, CanActivateChild, Router } from '@angular/router';
+import { ActivatedRouteSnapshot, Router, CanActivateFn } from '@angular/router';
+import { inject } from '@angular/core';
import { AppConfigService } from '@alfresco/adf-core';
-import { Injectable } from '@angular/core';
-@Injectable({
- providedIn: 'root'
-})
-export class PluginEnabledGuard implements CanActivate, CanActivateChild {
- constructor(private appConfigService: AppConfigService, private router: Router) {}
+export const PluginEnabledGuard: CanActivateFn = (route: ActivatedRouteSnapshot) => {
+ const appConfigService = inject(AppConfigService);
+ const router = inject(Router);
- canActivate(route: ActivatedRouteSnapshot): boolean {
- const isPluginEnabled = this.appConfigService.get(route.data.plugin, true);
+ const isPluginEnabled = appConfigService.get(route.data.plugin, true);
- if (!isPluginEnabled) {
- this.router.navigate(['/']);
- }
-
- return isPluginEnabled;
+ if (!isPluginEnabled) {
+ router.navigate(['/']);
}
- canActivateChild(route: ActivatedRouteSnapshot): boolean {
- return this.canActivate(route);
- }
-}
+ return isPluginEnabled;
+};
diff --git a/projects/aca-shared/src/lib/routing/shared.guard.spec.ts b/projects/aca-shared/src/lib/routing/shared.guard.spec.ts
index 7782e4aa1d..685fb80a9b 100644
--- a/projects/aca-shared/src/lib/routing/shared.guard.spec.ts
+++ b/projects/aca-shared/src/lib/routing/shared.guard.spec.ts
@@ -22,29 +22,44 @@
* from Hyland Software. If not, see .
*/
-import { of } from 'rxjs';
+import { TestBed } from '@angular/core/testing';
+import { ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router';
+import { Store } from '@ngrx/store';
+import { Observable, of } from 'rxjs';
+import { isQuickShareEnabled } from '@alfresco/aca-shared/store';
import { AppSharedRuleGuard } from './shared.guard';
describe('AppSharedRuleGuard', () => {
- it('should allow activation if quick share is enabled', () => {
- const store: any = {
- select: () => of(true)
- };
- const guard = new AppSharedRuleGuard(store);
- const emittedSpy = jasmine.createSpy('emitted');
+ let state: RouterStateSnapshot;
+ const route: ActivatedRouteSnapshot = new ActivatedRouteSnapshot();
+ const storeSpy = jasmine.createSpyObj('Store', ['select']);
+ beforeEach(() => {
+ TestBed.configureTestingModule({
+ providers: [{ provide: Store, useValue: storeSpy }]
+ });
- guard.canActivate().subscribe(emittedSpy);
- expect(emittedSpy).toHaveBeenCalledWith(true);
+ state = { url: 'some-url' } as RouterStateSnapshot;
});
- it('should allow child activation if quick share is enabled', () => {
- const store: any = {
- select: () => of(true)
- };
- const guard = new AppSharedRuleGuard(store);
- const emittedSpy = jasmine.createSpy('emitted');
+ it('should allow activation if quick share is enabled', (done) => {
+ storeSpy.select.and.returnValue(of(true));
+ const guard = TestBed.runInInjectionContext(() => AppSharedRuleGuard(route, state)) as Observable;
- guard.canActivateChild().subscribe(emittedSpy);
- expect(emittedSpy).toHaveBeenCalledWith(true);
+ guard.subscribe((response) => {
+ expect(storeSpy.select).toHaveBeenCalledWith(isQuickShareEnabled);
+ expect(response).toBeTrue();
+ done();
+ });
+ });
+
+ it('should not allow activation if quick share is disabled', (done) => {
+ storeSpy.select.and.returnValue(of(false));
+ const guard = TestBed.runInInjectionContext(() => AppSharedRuleGuard(route, state)) as Observable;
+
+ guard.subscribe((response) => {
+ expect(storeSpy.select).toHaveBeenCalledWith(isQuickShareEnabled);
+ expect(response).toBeFalse();
+ done();
+ });
});
});
diff --git a/projects/aca-shared/src/lib/routing/shared.guard.ts b/projects/aca-shared/src/lib/routing/shared.guard.ts
index 735c1b1c50..37f2a89c5c 100644
--- a/projects/aca-shared/src/lib/routing/shared.guard.ts
+++ b/projects/aca-shared/src/lib/routing/shared.guard.ts
@@ -22,27 +22,13 @@
* from Hyland Software. If not, see .
*/
-import { Injectable } from '@angular/core';
-import { CanActivate } from '@angular/router';
+import { CanActivateFn } from '@angular/router';
+import { inject } from '@angular/core';
import { Observable } from 'rxjs';
import { Store } from '@ngrx/store';
import { AppStore, isQuickShareEnabled } from '@alfresco/aca-shared/store';
-@Injectable({
- providedIn: 'root'
-})
-export class AppSharedRuleGuard implements CanActivate {
- isQuickShareEnabled$: Observable;
-
- constructor(store: Store) {
- this.isQuickShareEnabled$ = store.select(isQuickShareEnabled);
- }
-
- canActivate(): Observable {
- return this.isQuickShareEnabled$;
- }
-
- canActivateChild(): Observable {
- return this.canActivate();
- }
-}
+export const AppSharedRuleGuard: CanActivateFn = (): Observable => {
+ const store = inject(Store);
+ return store.select(isQuickShareEnabled);
+};