diff --git a/lib/core/src/lib/about/about-server-settings/about-server-settings.component.spec.ts b/lib/core/src/lib/about/about-server-settings/about-server-settings.component.spec.ts index 84ae944843..596d70e098 100644 --- a/lib/core/src/lib/about/about-server-settings/about-server-settings.component.spec.ts +++ b/lib/core/src/lib/about/about-server-settings/about-server-settings.component.spec.ts @@ -18,7 +18,7 @@ import { ComponentFixture, TestBed } from '@angular/core/testing'; import { AboutServerSettingsComponent } from './about-server-settings.component'; import { AppConfigService } from '../../app-config/app-config.service'; -import { AppConfigServiceMock } from '../../common'; +import { provideAppConfigTesting } from '@alfresco/adf-core'; const aboutGithubDetails = { url: 'https://github.com/componany/repository/commits/', @@ -36,7 +36,7 @@ describe('AboutServerSettingsComponent', () => { beforeEach(() => { TestBed.configureTestingModule({ - providers: [{ provide: AppConfigService, useClass: AppConfigServiceMock }] + providers: [provideAppConfigTesting()] }); fixture = TestBed.createComponent(AboutServerSettingsComponent); component = fixture.componentInstance; diff --git a/lib/core/src/lib/auth/guard/auth-guard.service.spec.ts b/lib/core/src/lib/auth/guard/auth-guard.service.spec.ts index a413dd167a..6a536335c9 100644 --- a/lib/core/src/lib/auth/guard/auth-guard.service.spec.ts +++ b/lib/core/src/lib/auth/guard/auth-guard.service.spec.ts @@ -26,8 +26,7 @@ import { BasicAlfrescoAuthService } from '../basic-auth/basic-alfresco-auth.serv import { RedirectAuthService } from '../oidc/redirect-auth.service'; import { EMPTY, of } from 'rxjs'; import { MatDialogModule } from '@angular/material/dialog'; -import { RouterTestingModule } from '@angular/router/testing'; -import { NoopAuthModule } from '../../testing'; +import { provideCoreAuthTesting } from '../../testing/'; describe('AuthGuardService', () => { let state: RouterStateSnapshot; @@ -42,9 +41,9 @@ describe('AuthGuardService', () => { beforeEach(() => { TestBed.configureTestingModule({ - imports: [MatDialogModule, RouterTestingModule, NoopAuthModule], + imports: [MatDialogModule], providers: [ - AppConfigService, + provideCoreAuthTesting(), { provide: RedirectAuthService, useValue: { onLogin: EMPTY, onTokenReceived: of(), init: () => {} } }, { provide: OidcAuthenticationService, diff --git a/lib/core/src/lib/auth/oidc/auth.module.ts b/lib/core/src/lib/auth/oidc/auth.module.ts index 8df4087a3e..9d767c60ad 100644 --- a/lib/core/src/lib/auth/oidc/auth.module.ts +++ b/lib/core/src/lib/auth/oidc/auth.module.ts @@ -15,34 +15,25 @@ * limitations under the License. */ -import { inject, ModuleWithProviders, NgModule, InjectionToken, provideAppInitializer } from '@angular/core'; -import { AUTH_CONFIG, OAuthModule, OAuthStorage } from 'angular-oauth2-oidc'; +import { inject, ModuleWithProviders, NgModule, InjectionToken, provideAppInitializer, EnvironmentProviders, Provider } from '@angular/core'; +import { AUTH_CONFIG, OAuthStorage, provideOAuthClient } from 'angular-oauth2-oidc'; import { AuthenticationService } from '../services/authentication.service'; import { AuthModuleConfig, AUTH_MODULE_CONFIG } from './auth-config'; import { authConfigFactory, AuthConfigService } from './auth-config.service'; -import { AuthRoutingModule } from './auth-routing.module'; import { AuthService } from './auth.service'; import { RedirectAuthService } from './redirect-auth.service'; -import { AuthenticationConfirmationComponent } from './view/authentication-confirmation/authentication-confirmation.component'; -import { HTTP_INTERCEPTORS } from '@angular/common/http'; +import { HTTP_INTERCEPTORS, provideHttpClient, withInterceptorsFromDi, withXsrfConfiguration } from '@angular/common/http'; import { TokenInterceptor } from './token.interceptor'; import { StorageService } from '../../common/services/storage.service'; +import { provideRouter } from '@angular/router'; +import { AUTH_ROUTES } from './auth.routes'; +import { Authentication, AuthenticationInterceptor } from '@alfresco/adf-core/auth'; export const JWT_STORAGE_SERVICE = new InjectionToken('JWT_STORAGE_SERVICE', { providedIn: 'root', factory: () => inject(StorageService) }); -/** - * Create a Login Factory function - * - * @param redirectService auth redirect service - * @returns a factory function - */ -export function loginFactory(redirectService: RedirectAuthService): () => Promise { - return () => redirectService.init(); -} - /** * @returns current instance of OAuthStorage */ @@ -50,11 +41,20 @@ export function oauthStorageFactory(): OAuthStorage { return inject(JWT_STORAGE_SERVICE); } -@NgModule({ - imports: [AuthRoutingModule, OAuthModule.forRoot(), AuthenticationConfirmationComponent], - providers: [ +/** + * Provides core authentication api + * + * @param config Optional configuration parameters + * @returns Angular providers + */ +export function provideCoreAuth(config: AuthModuleConfig = { useHash: false }): (Provider | EnvironmentProviders)[] { + config.preventClearHashAfterLogin = config.preventClearHashAfterLogin ?? true; + return [ + provideHttpClient(withInterceptorsFromDi(), withXsrfConfiguration({ cookieName: 'CSRF-TOKEN', headerName: 'X-CSRF-TOKEN' })), + provideOAuthClient(), + provideRouter(AUTH_ROUTES), { provide: OAuthStorage, useFactory: oauthStorageFactory }, - { provide: AuthenticationService }, + AuthenticationService, { provide: AUTH_CONFIG, useFactory: authConfigFactory, @@ -63,17 +63,22 @@ export function oauthStorageFactory(): OAuthStorage { RedirectAuthService, { provide: AuthService, useExisting: RedirectAuthService }, provideAppInitializer(() => { - const initializerFn = loginFactory(inject(RedirectAuthService)); - return initializerFn(); + const redirectService = inject(RedirectAuthService); + return redirectService.init(); }), - { - provide: HTTP_INTERCEPTORS, - useClass: TokenInterceptor, - multi: true - } - ] + { provide: HTTP_INTERCEPTORS, useClass: TokenInterceptor, multi: true }, + { provide: HTTP_INTERCEPTORS, useClass: AuthenticationInterceptor, multi: true }, + { provide: AUTH_MODULE_CONFIG, useValue: config }, + { provide: Authentication, useClass: AuthenticationService } + ]; +} + +/** @deprecated use `provideCoreAuth()` provider api instead */ +@NgModule({ + providers: [...provideCoreAuth()] }) export class AuthModule { + /* @deprecated use `provideCoreAuth()` provider api instead */ static forRoot(config: AuthModuleConfig = { useHash: false }): ModuleWithProviders { config.preventClearHashAfterLogin = config.preventClearHashAfterLogin ?? true; return { diff --git a/lib/core/src/lib/auth/oidc/auth-routing.module.ts b/lib/core/src/lib/auth/oidc/auth.routes.ts similarity index 71% rename from lib/core/src/lib/auth/oidc/auth-routing.module.ts rename to lib/core/src/lib/auth/oidc/auth.routes.ts index b4cd7938e5..662a816d90 100644 --- a/lib/core/src/lib/auth/oidc/auth-routing.module.ts +++ b/lib/core/src/lib/auth/oidc/auth.routes.ts @@ -15,14 +15,10 @@ * limitations under the License. */ -import { NgModule } from '@angular/core'; -import { provideRouter, Routes } from '@angular/router'; +import { Routes } from '@angular/router'; import { AuthenticationConfirmationComponent } from './view/authentication-confirmation/authentication-confirmation.component'; import { OidcAuthGuard } from './oidc-auth.guard'; -const routes: Routes = [{ path: 'view/authentication-confirmation', component: AuthenticationConfirmationComponent, canActivate: [OidcAuthGuard] }]; - -@NgModule({ - providers: [provideRouter(routes)] -}) -export class AuthRoutingModule {} +export const AUTH_ROUTES: Routes = [ + { path: 'view/authentication-confirmation', component: AuthenticationConfirmationComponent, canActivate: [OidcAuthGuard] } +]; diff --git a/lib/core/src/lib/auth/oidc/public-api.ts b/lib/core/src/lib/auth/oidc/public-api.ts index 908ae6a364..eab4c251c4 100644 --- a/lib/core/src/lib/auth/oidc/public-api.ts +++ b/lib/core/src/lib/auth/oidc/public-api.ts @@ -15,7 +15,6 @@ * limitations under the License. */ -export * from './auth-routing.module'; export * from './auth.module'; export * from './auth.service'; export * from './oidc-auth.guard'; diff --git a/lib/core/src/lib/auth/services/authentication.service.spec.ts b/lib/core/src/lib/auth/services/authentication.service.spec.ts index 1a04df2428..d4cd488aaa 100644 --- a/lib/core/src/lib/auth/services/authentication.service.spec.ts +++ b/lib/core/src/lib/auth/services/authentication.service.spec.ts @@ -20,8 +20,8 @@ import { AuthenticationService } from './authentication.service'; import { CookieService } from '../../common/services/cookie.service'; import { AppConfigService } from '../../app-config/app-config.service'; import { BasicAlfrescoAuthService } from '../basic-auth/basic-alfresco-auth.service'; -import { AuthModule } from '../oidc/auth.module'; -import { HttpHeaders, provideHttpClient } from '@angular/common/http'; +import { provideCoreAuth } from '../oidc/auth.module'; +import { HttpHeaders } from '@angular/common/http'; import { CookieServiceMock } from '../../mock'; import { AppConfigServiceMock } from '../../common'; import { OidcAuthenticationService } from '../oidc/oidc-authentication.service'; @@ -44,8 +44,8 @@ describe('AuthenticationService', () => { beforeEach(() => { TestBed.configureTestingModule({ - imports: [AuthModule.forRoot({ useHash: true })], providers: [ + provideCoreAuth({ useHash: true }), { provide: CookieService, useClass: CookieServiceMock @@ -53,8 +53,7 @@ describe('AuthenticationService', () => { { provide: AppConfigService, useClass: AppConfigServiceMock - }, - provideHttpClient() + } ] }); diff --git a/lib/core/src/lib/auth/services/user-access.service.spec.ts b/lib/core/src/lib/auth/services/user-access.service.spec.ts index 6fa88f1fdd..3c752c5cba 100644 --- a/lib/core/src/lib/auth/services/user-access.service.spec.ts +++ b/lib/core/src/lib/auth/services/user-access.service.spec.ts @@ -20,7 +20,7 @@ import { UserAccessService } from './user-access.service'; import { JwtHelperService } from './jwt-helper.service'; import { AppConfigService } from '../../app-config'; import { HttpClientTestingModule } from '@angular/common/http/testing'; -import { AuthModule, JWT_STORAGE_SERVICE } from '../oidc/auth.module'; +import { JWT_STORAGE_SERVICE, provideCoreAuth } from '../oidc/auth.module'; import { StorageService } from '../../common/services/storage.service'; describe('UserAccessService', () => { @@ -30,8 +30,8 @@ describe('UserAccessService', () => { beforeEach(() => { TestBed.configureTestingModule({ - imports: [HttpClientTestingModule, AuthModule.forRoot({ useHash: true })], - providers: [{ provide: JWT_STORAGE_SERVICE, useClass: StorageService }, UserAccessService] + imports: [HttpClientTestingModule], + providers: [provideCoreAuth({ useHash: true }), { provide: JWT_STORAGE_SERVICE, useClass: StorageService }] }); userAccessService = TestBed.inject(UserAccessService); jwtHelperService = TestBed.inject(JwtHelperService); diff --git a/lib/core/src/lib/common/services/storage.service.spec.ts b/lib/core/src/lib/common/services/storage.service.spec.ts index 3538208742..86fd50ffdb 100644 --- a/lib/core/src/lib/common/services/storage.service.spec.ts +++ b/lib/core/src/lib/common/services/storage.service.spec.ts @@ -18,7 +18,7 @@ import { TestBed } from '@angular/core/testing'; import { AppConfigService } from '../../app-config/app-config.service'; import { StorageService } from '../../common/services/storage.service'; -import { NoopAuthModule } from '@alfresco/adf-core'; +import { provideCoreAuthTesting } from '@alfresco/adf-core'; describe('StorageService', () => { let storage: StorageService; @@ -29,7 +29,7 @@ describe('StorageService', () => { describe('with local storage and prefix', () => { beforeEach(async () => { TestBed.configureTestingModule({ - imports: [NoopAuthModule] + providers: [provideCoreAuthTesting()] }); appConfig = TestBed.inject(AppConfigService); storage = TestBed.inject(StorageService); @@ -78,7 +78,7 @@ describe('StorageService', () => { describe('without local storage and prefix', () => { beforeEach(async () => { TestBed.configureTestingModule({ - imports: [NoopAuthModule] + providers: [provideCoreAuthTesting()] }); appConfig = TestBed.inject(AppConfigService); @@ -122,7 +122,7 @@ describe('StorageService', () => { }); TestBed.configureTestingModule({ - imports: [NoopAuthModule] + providers: [provideCoreAuthTesting()] }); appConfig = TestBed.inject(AppConfigService); storage = TestBed.inject(StorageService); diff --git a/lib/core/src/lib/core.module.ts b/lib/core/src/lib/core.module.ts index 331bc6683c..47d6291133 100644 --- a/lib/core/src/lib/core.module.ts +++ b/lib/core/src/lib/core.module.ts @@ -39,10 +39,7 @@ import { CORE_DIRECTIVES } from './directives/directive.module'; import { CORE_PIPES } from './pipes/pipe.module'; import { TranslateLoaderService } from './translation/translate-loader.service'; import { SEARCH_TEXT_INPUT_DIRECTIVES } from './search-text/search-text-input.module'; -import { AuthenticationInterceptor, Authentication } from '@alfresco/adf-core/auth'; -import { HTTP_INTERCEPTORS, HttpClient, provideHttpClient, withXsrfConfiguration, withInterceptorsFromDi } from '@angular/common/http'; -import { AuthenticationService } from './auth/services/authentication.service'; -import { MAT_SNACK_BAR_DEFAULT_OPTIONS } from '@angular/material/snack-bar'; +import { HttpClient } from '@angular/common/http'; import { AppConfigPipe } from './app-config'; import { IconComponent } from './icon'; import { SortingPickerComponent } from './sorting-picker'; @@ -50,9 +47,19 @@ import { DynamicChipListComponent } from './dynamic-chip-list'; import { IdentityUserInfoComponent } from './identity-user-info'; import { UnsavedChangesDialogComponent } from './dialogs'; import { MaterialModule } from './material.module'; -import { DecimalRenderMiddlewareService, FORM_FIELD_MODEL_RENDER_MIDDLEWARE } from './form'; import { provideAppConfig } from './app-config/provide-app-config'; +/** + * @deprecated this module is deprecated and will be removed + * Use the following combination instead: + * ```typescript + * providers: [ + * provideI18N(...), + * provideAppConfig(), + * provideCoreAuth(...) + * ] + * ``` + */ @NgModule({ imports: [ ...ABOUT_DIRECTIVES, @@ -129,21 +136,7 @@ export class CoreModule { }, defaultLanguage: 'en' }), - provideAppConfig(), - provideHttpClient(withInterceptorsFromDi(), withXsrfConfiguration({ cookieName: 'CSRF-TOKEN', headerName: 'X-CSRF-TOKEN' })), - { provide: HTTP_INTERCEPTORS, useClass: AuthenticationInterceptor, multi: true }, - { provide: Authentication, useClass: AuthenticationService }, - { - provide: MAT_SNACK_BAR_DEFAULT_OPTIONS, - useValue: { - duration: 10000 - } - }, - { - provide: FORM_FIELD_MODEL_RENDER_MIDDLEWARE, - useClass: DecimalRenderMiddlewareService, - multi: true - } + provideAppConfig() ] }; } diff --git a/lib/core/src/lib/dialogs/unsaved-changes-dialog/unsaved-changes.guard.spec.ts b/lib/core/src/lib/dialogs/unsaved-changes-dialog/unsaved-changes.guard.spec.ts index d343ac659c..23dc52fc2e 100644 --- a/lib/core/src/lib/dialogs/unsaved-changes-dialog/unsaved-changes.guard.spec.ts +++ b/lib/core/src/lib/dialogs/unsaved-changes-dialog/unsaved-changes.guard.spec.ts @@ -20,7 +20,9 @@ import { MatDialog, MatDialogModule, MatDialogRef } from '@angular/material/dial import { Observable, Subject } from 'rxjs'; import { UnsavedChangesDialogComponent } from './unsaved-changes-dialog.component'; import { UnsavedChangesGuard } from './unsaved-changes.guard'; -import { AuthenticationService, AuthGuardService, NoopAuthModule } from '@alfresco/adf-core'; +import { AuthenticationService } from '../../auth/services/authentication.service'; +import { AuthGuardService } from '../../auth/guard/auth-guard.service'; +import { provideCoreAuthTesting } from '../../testing'; describe('UnsavedChangesGuard', () => { let guard: UnsavedChangesGuard; @@ -39,8 +41,9 @@ describe('UnsavedChangesGuard', () => { beforeEach(() => { TestBed.configureTestingModule({ - imports: [MatDialogModule, NoopAuthModule], + imports: [MatDialogModule], providers: [ + provideCoreAuthTesting(), { provide: AuthenticationService, useValue: { diff --git a/lib/core/src/lib/directives/logout.directive.spec.ts b/lib/core/src/lib/directives/logout.directive.spec.ts index b6a534a195..3449e12ebe 100644 --- a/lib/core/src/lib/directives/logout.directive.spec.ts +++ b/lib/core/src/lib/directives/logout.directive.spec.ts @@ -22,7 +22,7 @@ import { of, throwError } from 'rxjs'; import { AuthenticationService } from '../auth/services/authentication.service'; import { AppConfigService } from '../app-config/app-config.service'; import { LogoutDirective } from './logout.directive'; -import { NoopAuthModule } from '../testing/noop-auth.module'; +import { provideCoreAuthTesting } from '../testing/noop-auth.module'; import { UnitTestingUtils } from '../testing/unit-testing-utils'; describe('LogoutDirective', () => { @@ -45,7 +45,8 @@ describe('LogoutDirective', () => { beforeEach(() => { TestBed.configureTestingModule({ - imports: [NoopAuthModule, TestComponent] + imports: [TestComponent], + providers: [provideCoreAuthTesting()] }); router = TestBed.inject(Router); authService = TestBed.inject(AuthenticationService); @@ -118,7 +119,8 @@ describe('LogoutDirective', () => { beforeEach(() => { TestBed.configureTestingModule({ - imports: [NoopAuthModule, TestComponent] + imports: [TestComponent], + providers: [provideCoreAuthTesting()] }); router = TestBed.inject(Router); authService = TestBed.inject(AuthenticationService); @@ -156,7 +158,8 @@ describe('LogoutDirective', () => { beforeEach(() => { TestBed.configureTestingModule({ - imports: [NoopAuthModule, TestComponent] + imports: [TestComponent], + providers: [provideCoreAuthTesting()] }); router = TestBed.inject(Router); authService = TestBed.inject(AuthenticationService); diff --git a/lib/core/src/lib/form/components/form-renderer.component.ts b/lib/core/src/lib/form/components/form-renderer.component.ts index 07c653a164..944ec39507 100644 --- a/lib/core/src/lib/form/components/form-renderer.component.ts +++ b/lib/core/src/lib/form/components/form-renderer.component.ts @@ -29,6 +29,7 @@ import { FORM_FIELD_MODEL_RENDER_MIDDLEWARE, FormFieldModelRenderMiddleware } fr import { ContainerModel, FormFieldModel, FormModel, TabModel } from './widgets'; import { HeaderWidgetComponent } from './widgets/header/header.widget'; import { FormSectionComponent } from './form-section/form-section.component'; +import { DecimalRenderMiddlewareService } from './middlewares/decimal-middleware.service'; @Component({ selector: 'adf-form-renderer', @@ -39,6 +40,11 @@ import { FormSectionComponent } from './form-section/form-section.component'; provide: FormRulesManager, useFactory: formRulesManagerFactory, deps: [Injector] + }, + { + provide: FORM_FIELD_MODEL_RENDER_MIDDLEWARE, + useClass: DecimalRenderMiddlewareService, + multi: true } ], imports: [ diff --git a/lib/core/src/lib/login/components/login-dialog-panel/login-dialog-panel.component.spec.ts b/lib/core/src/lib/login/components/login-dialog-panel/login-dialog-panel.component.spec.ts index d0ac796dc4..aa2e493dbf 100644 --- a/lib/core/src/lib/login/components/login-dialog-panel/login-dialog-panel.component.spec.ts +++ b/lib/core/src/lib/login/components/login-dialog-panel/login-dialog-panel.component.spec.ts @@ -18,10 +18,9 @@ import { ComponentFixture, TestBed } from '@angular/core/testing'; import { of } from 'rxjs'; import { OidcAuthenticationService } from '../../../auth/oidc/oidc-authentication.service'; -import { UnitTestingUtils } from '../../../testing/unit-testing-utils'; import { LoginDialogPanelComponent } from './login-dialog-panel.component'; import { BasicAlfrescoAuthService } from '../../../auth/basic-auth/basic-alfresco-auth.service'; -import { NoopAuthModule } from '@alfresco/adf-core'; +import { provideCoreAuthTesting, UnitTestingUtils } from '../../../testing'; describe('LoginDialogPanelComponent', () => { let component: LoginDialogPanelComponent; @@ -33,8 +32,8 @@ describe('LoginDialogPanelComponent', () => { beforeEach(async () => { TestBed.configureTestingModule({ - imports: [NoopAuthModule, LoginDialogPanelComponent], - providers: [{ provide: OidcAuthenticationService, useValue: {} }] + imports: [LoginDialogPanelComponent], + providers: [provideCoreAuthTesting(), { provide: OidcAuthenticationService, useValue: {} }] }); fixture = TestBed.createComponent(LoginDialogPanelComponent); basicAlfrescoAuthService = TestBed.inject(BasicAlfrescoAuthService); diff --git a/lib/core/src/lib/login/components/login/login.component.spec.ts b/lib/core/src/lib/login/components/login/login.component.spec.ts index c12db67a6e..1ab8a7bf05 100644 --- a/lib/core/src/lib/login/components/login/login.component.spec.ts +++ b/lib/core/src/lib/login/components/login/login.component.spec.ts @@ -25,13 +25,11 @@ import { AuthenticationService } from '../../../auth/services/authentication.ser import { UserPreferencesService } from '../../../common/services/user-preferences.service'; import { AppConfigService } from '../../../app-config/app-config.service'; import { BasicAlfrescoAuthService } from '../../../auth/basic-auth/basic-alfresco-auth.service'; -import { UnitTestingUtils } from '../../../testing/unit-testing-utils'; import { LoginSuccessEvent } from '../../models/login-success.event'; import { LoginErrorEvent } from '../../models/login-error.event'; import { provideHttpClientTesting } from '@angular/common/http/testing'; -import { NoopAuthModule } from '../../../testing/noop-auth.module'; +import { provideCoreAuthTesting, NoopTranslationService, UnitTestingUtils } from '../../../testing'; import { TranslationService } from '../../../translation/translation.service'; -import { NoopTranslationService } from '../../../testing/noop-translate.module'; describe('LoginComponent', () => { let component: LoginComponent; @@ -61,8 +59,9 @@ describe('LoginComponent', () => { beforeEach(fakeAsync(() => { TestBed.configureTestingModule({ - imports: [NoopAuthModule, LoginComponent], + imports: [LoginComponent], providers: [ + provideCoreAuthTesting(), provideHttpClientTesting(), { provide: TranslationService, useClass: NoopTranslationService }, { diff --git a/lib/core/src/lib/login/directives/login-footer.directive.spec.ts b/lib/core/src/lib/login/directives/login-footer.directive.spec.ts index 7497227635..f043f44769 100644 --- a/lib/core/src/lib/login/directives/login-footer.directive.spec.ts +++ b/lib/core/src/lib/login/directives/login-footer.directive.spec.ts @@ -15,9 +15,11 @@ * limitations under the License. */ -import { LoginComponent, LoginFooterDirective, NoopAuthModule } from '@alfresco/adf-core'; import { ComponentFixture, TestBed } from '@angular/core/testing'; import { OidcAuthenticationService } from '../../auth/oidc/oidc-authentication.service'; +import { LoginComponent } from '../components/login/login.component'; +import { LoginFooterDirective } from './login-footer.directive'; +import { provideCoreAuthTesting } from '../../testing'; describe('LoginFooterDirective', () => { let fixture: ComponentFixture; @@ -26,8 +28,9 @@ describe('LoginFooterDirective', () => { beforeEach(() => { TestBed.configureTestingModule({ - imports: [NoopAuthModule, LoginComponent], + imports: [LoginComponent], providers: [ + provideCoreAuthTesting(), { provide: OidcAuthenticationService, useValue: {} diff --git a/lib/core/src/lib/login/directives/login-header.directive.spec.ts b/lib/core/src/lib/login/directives/login-header.directive.spec.ts index 6407a0035c..607a17e1c2 100644 --- a/lib/core/src/lib/login/directives/login-header.directive.spec.ts +++ b/lib/core/src/lib/login/directives/login-header.directive.spec.ts @@ -15,9 +15,11 @@ * limitations under the License. */ -import { LoginComponent, LoginHeaderDirective, NoopAuthModule } from '@alfresco/adf-core'; import { ComponentFixture, TestBed } from '@angular/core/testing'; import { OidcAuthenticationService } from '../../auth/oidc/oidc-authentication.service'; +import { LoginComponent } from '../components/login/login.component'; +import { LoginHeaderDirective } from './login-header.directive'; +import { provideCoreAuthTesting } from '../../testing'; describe('LoginHeaderDirective', () => { let fixture: ComponentFixture; @@ -26,8 +28,8 @@ describe('LoginHeaderDirective', () => { beforeEach(() => { TestBed.configureTestingModule({ - imports: [NoopAuthModule, LoginComponent], - providers: [{ provide: OidcAuthenticationService, useValue: {} }] + imports: [LoginComponent], + providers: [provideCoreAuthTesting(), { provide: OidcAuthenticationService, useValue: {} }] }); fixture = TestBed.createComponent(LoginComponent); component = fixture.componentInstance; diff --git a/lib/core/src/lib/notifications/components/notification-history.component.spec.ts b/lib/core/src/lib/notifications/components/notification-history.component.spec.ts index 32ac684049..0f7b18d501 100644 --- a/lib/core/src/lib/notifications/components/notification-history.component.spec.ts +++ b/lib/core/src/lib/notifications/components/notification-history.component.spec.ts @@ -22,7 +22,7 @@ import { NotificationService } from '../services/notification.service'; import { StorageService } from '../../common/services/storage.service'; import { NOTIFICATION_TYPE, NotificationModel } from '../models/notification.model'; import { UnitTestingUtils } from '../../testing/unit-testing-utils'; -import { NoopAuthModule } from '../../testing/noop-auth.module'; +import { provideCoreAuthTesting } from '../../testing/noop-auth.module'; import { MatIconTestingModule } from '@angular/material/icon/testing'; describe('Notification History Component', () => { @@ -41,7 +41,8 @@ describe('Notification History Component', () => { beforeEach(() => { TestBed.configureTestingModule({ - imports: [NoopAuthModule, NotificationHistoryComponent, MatIconTestingModule] + imports: [NotificationHistoryComponent, MatIconTestingModule], + providers: [provideCoreAuthTesting()] }); fixture = TestBed.createComponent(NotificationHistoryComponent); component = fixture.componentInstance; diff --git a/lib/core/src/lib/testing/app-config-testing.ts b/lib/core/src/lib/testing/app-config-testing.ts new file mode 100644 index 0000000000..59db0f0006 --- /dev/null +++ b/lib/core/src/lib/testing/app-config-testing.ts @@ -0,0 +1,46 @@ +/*! + * @license + * Copyright © 2005-2025 Hyland Software, Inc. and its affiliates. All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { EnvironmentProviders, inject, provideAppInitializer, Provider } from '@angular/core'; +import { AppConfigService, Status } from '../app-config'; + +/** + * Provides testing api for application config. + * + * @param config Custom application configuration data + * @returns Angular providers + */ +export function provideAppConfigTesting(config?: any): (Provider | EnvironmentProviders)[] { + config = config ?? { + application: { + name: 'Alfresco ADF Application', + storagePrefix: 'ADF_APP' + }, + ecmHost: 'http://{hostname}{:port}/ecm', + bpmHost: 'http://{hostname}{:port}/bpm', + logLevel: 'silent' + }; + + return [ + provideAppInitializer(() => { + const service = inject(AppConfigService); + service.config = config; + service.status = Status.LOADED; + return Promise.resolve(); + }) + ]; +} diff --git a/lib/core/src/lib/testing/core.testing.module.ts b/lib/core/src/lib/testing/core.testing.module.ts deleted file mode 100644 index 1c2ec6d92c..0000000000 --- a/lib/core/src/lib/testing/core.testing.module.ts +++ /dev/null @@ -1,28 +0,0 @@ -/*! - * @license - * Copyright © 2005-2025 Hyland Software, Inc. and its affiliates. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { NgModule } from '@angular/core'; -import { NoopAnimationsModule } from '@angular/platform-browser/animations'; -import { CoreModule } from '../core.module'; -import { NoopTranslateModule } from './noop-translate.module'; -import { NoopAuthModule } from './noop-auth.module'; - -/** @deprecated this module is deprecated and will be removed in the future */ -@NgModule({ - imports: [NoopAnimationsModule, CoreModule.forRoot(), NoopTranslateModule, NoopAuthModule] -}) -export class CoreTestingModule {} diff --git a/lib/core/src/lib/testing/index.ts b/lib/core/src/lib/testing/index.ts index 0689fd52cb..6734c55416 100644 --- a/lib/core/src/lib/testing/index.ts +++ b/lib/core/src/lib/testing/index.ts @@ -15,8 +15,8 @@ * limitations under the License. */ -export * from './core.testing.module'; export * from './core.story.module'; export * from './noop-translate.module'; export * from './noop-auth.module'; export * from './unit-testing-utils'; +export * from './app-config-testing'; diff --git a/lib/core/src/lib/testing/noop-auth.module.ts b/lib/core/src/lib/testing/noop-auth.module.ts index 79796e1ed7..ef93fafbd8 100644 --- a/lib/core/src/lib/testing/noop-auth.module.ts +++ b/lib/core/src/lib/testing/noop-auth.module.ts @@ -15,17 +15,13 @@ * limitations under the License. */ -import { Injectable, NgModule, inject, provideAppInitializer } from '@angular/core'; -import { AuthModule, JWT_STORAGE_SERVICE } from '../auth/oidc/auth.module'; +import { EnvironmentProviders, Injectable, NgModule, Provider } from '@angular/core'; +import { JWT_STORAGE_SERVICE, provideCoreAuth } from '../auth/oidc/auth.module'; import { RedirectAuthService } from '../auth/oidc/redirect-auth.service'; -import { HttpClientTestingModule } from '@angular/common/http/testing'; -import { RouterTestingModule } from '@angular/router/testing'; -import { AppConfigService, StoragePrefixFactory } from '../app-config'; +import { AppConfigService, provideAppConfig } from '../app-config'; import { AppConfigServiceMock, CookieService, StorageService } from '../common'; import { CookieServiceMock } from '../mock'; import { EMPTY, of } from 'rxjs'; -import { loadAppConfig } from '../app-config/app-config.loader'; -import { AdfHttpClient } from '@alfresco/adf-core/api'; @Injectable({ providedIn: 'root' }) export class NoopRedirectAuthService extends RedirectAuthService { @@ -37,22 +33,31 @@ export class NoopRedirectAuthService extends RedirectAuthService { } } -@NgModule({ - imports: [AuthModule.forRoot({ useHash: true }), HttpClientTestingModule, RouterTestingModule], - providers: [ +/** + * Provides testing api for Core Auth layer + * + * Example: + * ```typescript + * TestBed.configureTestingModule({ + * providers: [provideCoreAuthTesting()] + * }); + * ``` + * + * @returns list of Angular providers + */ +export function provideCoreAuthTesting(): (Provider | EnvironmentProviders)[] { + return [ + provideCoreAuth({ useHash: true }), { provide: AppConfigService, useClass: AppConfigServiceMock }, { provide: CookieService, useClass: CookieServiceMock }, { provide: RedirectAuthService, useClass: NoopRedirectAuthService }, - provideAppInitializer(() => { - const initializerFn = loadAppConfig( - inject(AppConfigService), - inject(StorageService), - inject(AdfHttpClient), - inject(StoragePrefixFactory) - ); - return initializerFn(); - }), + provideAppConfig(), { provide: JWT_STORAGE_SERVICE, useClass: StorageService } - ] + ]; +} + +/* @deprecated use `provideCoreAuthTesting()` instead */ +@NgModule({ + providers: [...provideCoreAuthTesting()] }) export class NoopAuthModule {} diff --git a/lib/core/src/lib/translation/provide-i18n.ts b/lib/core/src/lib/translation/provide-i18n.ts index 4b2075ccc1..5f03c9ff33 100644 --- a/lib/core/src/lib/translation/provide-i18n.ts +++ b/lib/core/src/lib/translation/provide-i18n.ts @@ -29,7 +29,7 @@ export interface ProvideI18NConfig { defaultLanguage?: string; /** * An array of assets to be used for i18n, where each asset is a tuple containing an identifier and a path. - * Example: [['en', '/assets/i18n/en.json'], ['fr', '/assets/i18n/fr.json']] + * Example: [['adf-core', 'assets/adf-core'], ['my-translations', 'assets/my-translations']] */ assets?: [string, string][]; } diff --git a/lib/core/src/lib/translation/translation.service.spec.ts b/lib/core/src/lib/translation/translation.service.spec.ts index 373955b7e5..587d8a9c1b 100644 --- a/lib/core/src/lib/translation/translation.service.spec.ts +++ b/lib/core/src/lib/translation/translation.service.spec.ts @@ -18,9 +18,8 @@ import { TestBed } from '@angular/core/testing'; import { TranslateLoader, TranslateModule } from '@ngx-translate/core'; import { TranslationService } from './translation.service'; -import { AppConfigService } from '../app-config/app-config.service'; -import { AppConfigServiceMock } from '../common/mock/app-config.service.mock'; import { of } from 'rxjs'; +import { provideAppConfigTesting } from '../testing'; describe('TranslationService', () => { let translationService: TranslationService; @@ -60,7 +59,7 @@ describe('TranslationService', () => { } }) ], - providers: [TranslationService, { provide: AppConfigService, useClass: AppConfigServiceMock }] + providers: [TranslationService, provideAppConfigTesting()] }); translationService = TestBed.inject(TranslationService); diff --git a/lib/core/src/lib/viewer/components/pdf-viewer/pdf-viewer.component.spec.ts b/lib/core/src/lib/viewer/components/pdf-viewer/pdf-viewer.component.spec.ts index 3f30d366ca..c993bc5c03 100644 --- a/lib/core/src/lib/viewer/components/pdf-viewer/pdf-viewer.component.spec.ts +++ b/lib/core/src/lib/viewer/components/pdf-viewer/pdf-viewer.component.spec.ts @@ -23,7 +23,7 @@ import { By } from '@angular/platform-browser'; import { of } from 'rxjs'; import { AppConfigService } from '../../../app-config'; import { EventMock } from '../../../mock'; -import { NoopAuthModule, UnitTestingUtils } from '../../../testing'; +import { UnitTestingUtils, provideCoreAuthTesting } from '../../../testing'; import { RenderingQueueServices } from '../../services/rendering-queue.services'; import { PdfThumbListComponent } from '../pdf-viewer-thumbnails/pdf-viewer-thumbnails.component'; import { PDFJS_MODULE, PDFJS_VIEWER_MODULE, PdfViewerComponent } from './pdf-viewer.component'; @@ -106,8 +106,9 @@ describe('Test PdfViewer component', () => { beforeEach(async () => { TestBed.configureTestingModule({ - imports: [NoopAuthModule, PdfViewerComponent], + imports: [PdfViewerComponent], providers: [ + provideCoreAuthTesting(), { provide: MatDialog, useValue: { @@ -326,7 +327,7 @@ describe('Test PdfViewer component', () => { () => ({ afterClosed: () => of('') - } as any) + }) as any ); spyOn(componentUrlTestPasswordComponent.pdfViewerComponent.close, 'emit'); @@ -355,8 +356,9 @@ describe('Test PdfViewer - Zoom customization', () => { beforeEach(() => { TestBed.configureTestingModule({ - imports: [NoopAuthModule, PdfViewerComponent], + imports: [PdfViewerComponent], providers: [ + provideCoreAuthTesting(), { provide: MatDialog, useValue: { @@ -428,8 +430,9 @@ describe('Test PdfViewer - User interaction', () => { }); TestBed.configureTestingModule({ - imports: [NoopAuthModule, PdfViewerComponent], + imports: [PdfViewerComponent], providers: [ + provideCoreAuthTesting(), { provide: MatDialog, useValue: {