diff --git a/apps/golden-sample-app/src/app/app.component.spec.ts b/apps/golden-sample-app/src/app/app.component.spec.ts index 992d56451..f8e6f07de 100644 --- a/apps/golden-sample-app/src/app/app.component.spec.ts +++ b/apps/golden-sample-app/src/app/app.component.spec.ts @@ -1,11 +1,13 @@ import { NO_ERRORS_SCHEMA } from '@angular/core'; import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { HttpClientTestingModule } from '@angular/common/http/testing'; import { RouterTestingModule } from '@angular/router/testing'; +import { ActivityMonitorService, AuthService } from '@backbase/identity-auth'; +import { LOCALES_LIST, LocalesService } from '@backbase/shared/util/app-core'; import { LayoutService } from '@backbase/ui-ang/layout'; import { OAuthService } from 'angular-oauth2-oidc'; import { of } from 'rxjs'; import { AppComponent } from './app.component'; -import { environment } from '../environments/environment'; describe('AppComponent', () => { let fixture: ComponentFixture; @@ -19,14 +21,34 @@ describe('AppComponent', () => { const mockLayoutService = { navigationExpanded$: of(true), }; + const mockActivityMonitorService = { + events: of({ type: 'start' }), + start: jest.fn(), + stop: jest.fn(), + }; + const mockAuthService = { + isAuthenticated$: of(true), + initLoginFlow: jest.fn(), + }; + const mockLocalesService = { + currentLocale: 'en', + setLocale: jest.fn(), + }; + const mockLocalesList = ['en', 'nl', 'es']; beforeEach(async () => { await TestBed.configureTestingModule({ - declarations: [AppComponent], - imports: [RouterTestingModule], + imports: [AppComponent, RouterTestingModule, HttpClientTestingModule], providers: [ { provide: LayoutService, useValue: mockLayoutService }, { provide: OAuthService, useValue: mockOAuthService }, + { + provide: ActivityMonitorService, + useValue: mockActivityMonitorService, + }, + { provide: AuthService, useValue: mockAuthService }, + { provide: LocalesService, useValue: mockLocalesService }, + { provide: LOCALES_LIST, useValue: mockLocalesList }, ], schemas: [NO_ERRORS_SCHEMA], }).compileComponents(); @@ -69,11 +91,4 @@ describe('AppComponent', () => { component.focusMainContainer(mockEvent as MouseEvent); expect(focus).toHaveBeenCalled(); }); - - describe('When data is mock', () => { - it('should set the isAuthenticated to true', () => { - environment.mockEnabled = true; - expect(component.isAuthenticated).toBe(true); - }); - }); }); diff --git a/apps/golden-sample-app/src/app/locale-selector/locale-selector.component.spec.ts b/apps/golden-sample-app/src/app/locale-selector/locale-selector.component.spec.ts index 9d749d6f5..b8a101ca8 100644 --- a/apps/golden-sample-app/src/app/locale-selector/locale-selector.component.spec.ts +++ b/apps/golden-sample-app/src/app/locale-selector/locale-selector.component.spec.ts @@ -1,21 +1,28 @@ import { LocaleSelectorComponent } from './locale-selector.component'; import { localesCatalog } from './locales-catalog'; -import { LocalesService } from '@backbase/shared/util/app-core'; +import { LocalesService, LOCALES_LIST } from '@backbase/shared/util/app-core'; +import { TestBed } from '@angular/core/testing'; describe('bb-locale-selector', () => { let component: LocaleSelectorComponent; const mockLocales = ['en', 'es']; - let mockLocalesService: Pick = - { - currentLocale: 'en', - setLocale: jest.fn(), - }; + const mockLocalesService: Pick< + LocalesService, + 'setLocale' | 'currentLocale' + > = { + currentLocale: 'en', + setLocale: jest.fn(), + }; function createComponent() { - component = new LocaleSelectorComponent( - mockLocalesService as LocalesService, - mockLocales - ); + TestBed.configureTestingModule({ + providers: [ + LocaleSelectorComponent, + { provide: LocalesService, useValue: mockLocalesService }, + { provide: LOCALES_LIST, useValue: mockLocales }, + ], + }); + component = TestBed.inject(LocaleSelectorComponent); } beforeEach(() => { @@ -28,11 +35,24 @@ describe('bb-locale-selector', () => { }); it(`should call ngOnInit and set current language to empty string`, () => { - mockLocalesService = { + // Reset the TestBed and create a new component with different mock + TestBed.resetTestingModule(); + const mockLocalesServiceWithInvalidLocale = { currentLocale: 'Nan', setLocale: jest.fn(), }; - createComponent(); + + TestBed.configureTestingModule({ + providers: [ + LocaleSelectorComponent, + { + provide: LocalesService, + useValue: mockLocalesServiceWithInvalidLocale, + }, + { provide: LOCALES_LIST, useValue: mockLocales }, + ], + }); + component = TestBed.inject(LocaleSelectorComponent); component.ngOnInit(); expect(component.language).toEqual(undefined); }); diff --git a/libs/ach-positive-pay-journey/internal/data-access/src/lib/services/ach-positive-pay-http/ach-positive-pay.http.service.spec.ts b/libs/ach-positive-pay-journey/internal/data-access/src/lib/services/ach-positive-pay-http/ach-positive-pay.http.service.spec.ts index fa8b46ab3..f37ba7edc 100644 --- a/libs/ach-positive-pay-journey/internal/data-access/src/lib/services/ach-positive-pay-http/ach-positive-pay.http.service.spec.ts +++ b/libs/ach-positive-pay-journey/internal/data-access/src/lib/services/ach-positive-pay-http/ach-positive-pay.http.service.spec.ts @@ -1,6 +1,7 @@ import { HttpClient } from '@angular/common/http'; import { AchRule } from '../../models/ach-rule'; import { AchPositivePayHttpService } from './ach-positive-pay.http.service'; +import { TestBed } from '@angular/core/testing'; describe('AchPositivePayJourneyService', () => { let service: AchPositivePayHttpService; @@ -10,7 +11,13 @@ describe('AchPositivePayJourneyService', () => { }; beforeEach(() => { - service = new AchPositivePayHttpService(mockHttpClient as HttpClient); + TestBed.configureTestingModule({ + providers: [ + AchPositivePayHttpService, + { provide: HttpClient, useValue: mockHttpClient }, + ], + }); + service = TestBed.inject(AchPositivePayHttpService); }); it('should be created and make a get', () => { diff --git a/libs/ach-positive-pay-journey/internal/feature/src/lib/components/ach-positive-pay-journey/ach-positive-pay-journey.component.spec.ts b/libs/ach-positive-pay-journey/internal/feature/src/lib/components/ach-positive-pay-journey/ach-positive-pay-journey.component.spec.ts index c98d7b9ca..fcf409182 100644 --- a/libs/ach-positive-pay-journey/internal/feature/src/lib/components/ach-positive-pay-journey/ach-positive-pay-journey.component.spec.ts +++ b/libs/ach-positive-pay-journey/internal/feature/src/lib/components/ach-positive-pay-journey/ach-positive-pay-journey.component.spec.ts @@ -1,5 +1,6 @@ import { ActivatedRoute, Router } from '@angular/router'; import { AchPositivePayJourneyComponent } from './ach-positive-pay-journey.component'; +import { TestBed } from '@angular/core/testing'; describe('AchPositivePayJourneyComponent', () => { let component: AchPositivePayJourneyComponent; @@ -9,10 +10,14 @@ describe('AchPositivePayJourneyComponent', () => { const mockActivatedRoute = new ActivatedRoute(); beforeEach(() => { - component = new AchPositivePayJourneyComponent( - mockRouter as Router, - mockActivatedRoute - ); + TestBed.configureTestingModule({ + providers: [ + AchPositivePayJourneyComponent, + { provide: Router, useValue: mockRouter }, + { provide: ActivatedRoute, useValue: mockActivatedRoute }, + ], + }); + component = TestBed.inject(AchPositivePayJourneyComponent); }); it('should create', () => { diff --git a/libs/ach-positive-pay-journey/internal/feature/src/lib/components/ach-positive-pay-new-rule/ach-positive-pay-new-rule.component.spec.ts b/libs/ach-positive-pay-journey/internal/feature/src/lib/components/ach-positive-pay-new-rule/ach-positive-pay-new-rule.component.spec.ts index cf9189261..994b6ca44 100644 --- a/libs/ach-positive-pay-journey/internal/feature/src/lib/components/ach-positive-pay-new-rule/ach-positive-pay-new-rule.component.spec.ts +++ b/libs/ach-positive-pay-journey/internal/feature/src/lib/components/ach-positive-pay-new-rule/ach-positive-pay-new-rule.component.spec.ts @@ -5,39 +5,48 @@ import { of, throwError } from 'rxjs'; import { AchPositivePayHttpService } from '@backbase/ach-positive-pay-journey/internal/data-access'; import { AchPositivePayNewRuleComponent } from './ach-positive-pay-new-rule.component'; import { ProductSummaryItem } from '@backbase/arrangement-manager-http-ang'; +import { TestBed } from '@angular/core/testing'; describe('AchPositivePayNewRuleComponent', () => { let component: AchPositivePayNewRuleComponent; - const mockRouter: Pick = { - navigate: jest.fn(), - }; - const mockActivatedRoute = new ActivatedRoute(); - let mockFormBuilder: Pick = { - group: jest.fn(), - }; - const mockAchPositivePayService: Pick< + let mockRouter: Pick; + let mockActivatedRoute: ActivatedRoute; + let mockFormBuilder: FormBuilder; + let mockAchPositivePayService: Pick< AchPositivePayHttpService, 'accounts$' | 'submitAchRule' - > = { - accounts$: of(), - submitAchRule: jest.fn(), - }; - const mockNotificationService: Pick = - { + >; + let mockNotificationService: Pick; + + beforeEach(() => { + mockRouter = { + navigate: jest.fn(), + }; + mockActivatedRoute = new ActivatedRoute(); + mockFormBuilder = new FormBuilder(); + jest.spyOn(mockFormBuilder, 'group'); + mockAchPositivePayService = { + accounts$: of(), + submitAchRule: jest.fn(), + }; + mockNotificationService = { showNotification: jest.fn(), }; - const createComponent = () => { - component = new AchPositivePayNewRuleComponent( - mockRouter as Router, - mockActivatedRoute, - mockFormBuilder as FormBuilder, - mockAchPositivePayService as AchPositivePayHttpService, - mockNotificationService as NotificationService - ); - }; - beforeEach(() => { - createComponent(); + TestBed.configureTestingModule({ + providers: [ + AchPositivePayNewRuleComponent, + { provide: Router, useValue: mockRouter }, + { provide: ActivatedRoute, useValue: mockActivatedRoute }, + { provide: FormBuilder, useValue: mockFormBuilder }, + { + provide: AchPositivePayHttpService, + useValue: mockAchPositivePayService, + }, + { provide: NotificationService, useValue: mockNotificationService }, + ], + }); + component = TestBed.inject(AchPositivePayNewRuleComponent); }); it('should create', () => { @@ -73,8 +82,6 @@ describe('AchPositivePayNewRuleComponent', () => { legalEntityIds: ['ids'], debitCards: [{ unmaskableAttributes: ['BBAN'] }], }; - mockFormBuilder = new FormBuilder(); - createComponent(); component.ngOnInit(); component.onSelectAccountId(mockAccount); expect(component.achRuleForm.get('arrangement')?.value).toEqual( @@ -92,8 +99,6 @@ describe('AchPositivePayNewRuleComponent', () => { }); it('should subscribe to positive pay service success', () => { mockAchPositivePayService.submitAchRule = jest.fn(() => of('stream')); - mockFormBuilder = new FormBuilder(); - createComponent(); component.ngOnInit(); component.loading = false; component.submitRule(); @@ -106,8 +111,6 @@ describe('AchPositivePayNewRuleComponent', () => { return { message: 'error' }; }) ); - mockFormBuilder = new FormBuilder(); - createComponent(); component.ngOnInit(); component.loading = false; component.submitRule(); diff --git a/libs/journey-bundles/custom-payment/src/lib/components/initiator/initiator.service.spec.ts b/libs/journey-bundles/custom-payment/src/lib/components/initiator/initiator.service.spec.ts index f37fc0772..460e2e15a 100644 --- a/libs/journey-bundles/custom-payment/src/lib/components/initiator/initiator.service.spec.ts +++ b/libs/journey-bundles/custom-payment/src/lib/components/initiator/initiator.service.spec.ts @@ -2,6 +2,7 @@ import { ProductSummaryHttpService } from '@backbase/arrangement-manager-http-an import { of } from 'rxjs'; import { AccountSelectorItems } from './initiator.model'; import { InitiatorService } from './initiator.service'; +import { TestBed } from '@angular/core/testing'; describe('InitiatorService', () => { let service: InitiatorService; @@ -18,7 +19,16 @@ describe('InitiatorService', () => { } as unknown as ProductSummaryHttpService; beforeEach(() => { - service = new InitiatorService(mockProductSummaryService); + TestBed.configureTestingModule({ + providers: [ + InitiatorService, + { + provide: ProductSummaryHttpService, + useValue: mockProductSummaryService, + }, + ], + }); + service = TestBed.inject(InitiatorService); }); it('should call product summary service to get arrangements', (done) => { diff --git a/libs/shared/feature/auth/src/lib/activity-monitor/container/activity-monitor.component.spec.ts b/libs/shared/feature/auth/src/lib/activity-monitor/container/activity-monitor.component.spec.ts index 5b692b4d0..506aa3725 100644 --- a/libs/shared/feature/auth/src/lib/activity-monitor/container/activity-monitor.component.spec.ts +++ b/libs/shared/feature/auth/src/lib/activity-monitor/container/activity-monitor.component.spec.ts @@ -12,6 +12,7 @@ import { OAuthService } from 'angular-oauth2-oidc'; import { ReplaySubject } from 'rxjs'; import { TestScheduler } from 'rxjs/testing'; import { ActivityMonitorComponent } from './activity-monitor.component'; +import { TestBed } from '@angular/core/testing'; type WidePropertyTypes = Partial>; const mock = (overrides?: WidePropertyTypes) => @@ -34,11 +35,15 @@ describe('ActivityMonitorComponent', () => { isAuthenticated$, initLoginFlow: jest.fn(), }); - const component = new ActivityMonitorComponent( - activityMonitorService, - oAuthService, - authService - ); + TestBed.configureTestingModule({ + providers: [ + ActivityMonitorComponent, + { provide: ActivityMonitorService, useValue: activityMonitorService }, + { provide: OAuthService, useValue: oAuthService }, + { provide: AuthService, useValue: authService }, + ], + }); + const component = TestBed.inject(ActivityMonitorComponent); const scheduler = new TestScheduler((a, e) => expect(a).toEqual(e)); return { diff --git a/libs/shared/feature/auth/src/lib/auth-events-handler/auth-events-handler.service.spec.ts b/libs/shared/feature/auth/src/lib/auth-events-handler/auth-events-handler.service.spec.ts index 2f81ee7d0..3a05a75cf 100644 --- a/libs/shared/feature/auth/src/lib/auth-events-handler/auth-events-handler.service.spec.ts +++ b/libs/shared/feature/auth/src/lib/auth-events-handler/auth-events-handler.service.spec.ts @@ -6,6 +6,7 @@ import { AuthEventsHandlerService } from './auth-events-handler.service'; import { AuthService } from '@backbase/identity-auth'; import { LocalesService } from '@backbase/shared/util/app-core'; import { TestScheduler } from 'rxjs/testing'; +import { TestBed } from '@angular/core/testing'; export type WidePropertyTypes = Partial>; export const mock = (overrides?: WidePropertyTypes) => @@ -28,11 +29,15 @@ describe('AuthEventsHandlerService', () => { setLocale: jest.fn(), currentLocale: 'en', }); - const service = new AuthEventsHandlerService( - oAuthService, - authService, - localeService - ); + TestBed.configureTestingModule({ + providers: [ + AuthEventsHandlerService, + { provide: OAuthService, useValue: oAuthService }, + { provide: AuthService, useValue: authService }, + { provide: LocalesService, useValue: localeService }, + ], + }); + const service = TestBed.inject(AuthEventsHandlerService); const scheduler = new TestScheduler((a, e) => expect(a).toEqual(e)); return { diff --git a/libs/shared/feature/auth/src/lib/guard/auth.guard.spec.ts b/libs/shared/feature/auth/src/lib/guard/auth.guard.spec.ts index 9c7ab0145..7bd98eed9 100644 --- a/libs/shared/feature/auth/src/lib/guard/auth.guard.spec.ts +++ b/libs/shared/feature/auth/src/lib/guard/auth.guard.spec.ts @@ -4,7 +4,7 @@ import { AuthService } from '@backbase/identity-auth'; import { ReplaySubject } from 'rxjs'; import { TestScheduler } from 'rxjs/testing'; import { AuthGuard } from './auth.guard'; -import { Environment } from '@backbase/shared/util/config'; +import { TestBed } from '@angular/core/testing'; export type WidePropertyTypes = Partial>; export const mock = (overrides?: WidePropertyTypes) => @@ -17,13 +17,10 @@ describe('AuthGuard', () => { isAuthenticated$: isAuthenticated$$.asObservable(), initLoginFlow: jest.fn(), }); - const environment: Environment = { - production: false, - apiRoot: '', - locales: [], - common: { designSlimMode: false }, - }; - const guard = new AuthGuard(authService, environment); + TestBed.configureTestingModule({ + providers: [AuthGuard, { provide: AuthService, useValue: authService }], + }); + const guard = TestBed.inject(AuthGuard); const scheduler = new TestScheduler((a, e) => expect(a).toEqual(e)); return { guard, authService, isAuthenticated$$, scheduler }; diff --git a/libs/shared/feature/auth/src/lib/interceptor/auth.interceptor.spec.ts b/libs/shared/feature/auth/src/lib/interceptor/auth.interceptor.spec.ts index 6b75067e5..6e7dd302f 100644 --- a/libs/shared/feature/auth/src/lib/interceptor/auth.interceptor.spec.ts +++ b/libs/shared/feature/auth/src/lib/interceptor/auth.interceptor.spec.ts @@ -12,7 +12,7 @@ import { share } from 'rxjs'; import { TestScheduler } from 'rxjs/testing'; import { AuthInterceptor } from './auth.interceptor'; import * as utils from '../utils/auth.utils'; - +import { TestBed } from '@angular/core/testing'; export type WidePropertyTypes = Partial>; export const mock = (overrides?: WidePropertyTypes) => ({ ...overrides } as jest.Mocked); @@ -25,7 +25,13 @@ describe('Auth Interceptor', () => { const authUtils = { isInvalidToken401: jest.spyOn(utils, 'isInvalidToken401'), }; - const interceptor = new AuthInterceptor(oAuthService); + TestBed.configureTestingModule({ + providers: [ + AuthInterceptor, + { provide: OAuthService, useValue: oAuthService }, + ], + }); + const interceptor = TestBed.inject(AuthInterceptor); const next = mock({ handle: jest.fn(), }); diff --git a/libs/shared/feature/communication/src/lib/journey-communication.service.spec.ts b/libs/shared/feature/communication/src/lib/journey-communication.service.spec.ts index 2af19a3b5..f502da3d3 100644 --- a/libs/shared/feature/communication/src/lib/journey-communication.service.spec.ts +++ b/libs/shared/feature/communication/src/lib/journey-communication.service.spec.ts @@ -2,6 +2,7 @@ import { Router } from '@angular/router'; // eslint-disable-next-line @nx/enforce-module-boundaries import { Transfer } from '@backbase/transfer-journey'; import { JourneyCommunicationService } from './journey-communication.service'; +import { TestBed } from '@angular/core/testing'; describe('JourneyCommunicationService', () => { let service: JourneyCommunicationService; @@ -11,7 +12,13 @@ describe('JourneyCommunicationService', () => { const mockAmount = 42; beforeEach(() => { - service = new JourneyCommunicationService(mockRouter as Router); + TestBed.configureTestingModule({ + providers: [ + JourneyCommunicationService, + { provide: Router, useValue: mockRouter }, + ], + }); + service = TestBed.inject(JourneyCommunicationService); service.makeTransfer({ toAccount: mocktoAccount, amount: mockAmount, diff --git a/libs/shared/feature/user-context/src/lib/shared-user-context.guard.spec.ts b/libs/shared/feature/user-context/src/lib/shared-user-context.guard.spec.ts index a7f50b275..27b25da04 100644 --- a/libs/shared/feature/user-context/src/lib/shared-user-context.guard.spec.ts +++ b/libs/shared/feature/user-context/src/lib/shared-user-context.guard.spec.ts @@ -1,5 +1,6 @@ /* eslint-disable @typescript-eslint/consistent-type-assertions */ /* eslint-disable @typescript-eslint/no-explicit-any */ +import { TestBed } from '@angular/core/testing'; import { SharedUserContextGuard } from './shared-user-context.guard'; import { ActivatedRouteSnapshot, @@ -38,11 +39,17 @@ describe('UserContextGuard', () => { mockServiceAgreementHttpService.getServiceAgreementContext.mockReturnValue( validationRequestMarbles ? cold(validationRequestMarbles) : of({}) ); - - return new SharedUserContextGuard( - mockRouter, - mockServiceAgreementHttpService - ); + TestBed.configureTestingModule({ + providers: [ + SharedUserContextGuard, + { provide: Router, useValue: mockRouter }, + { + provide: ServiceAgreementsHttpService, + useValue: mockServiceAgreementHttpService, + }, + ], + }); + return TestBed.inject(SharedUserContextGuard); } beforeEach(() => { diff --git a/libs/shared/feature/user-context/src/lib/shared-user-context.interceptor.spec.ts b/libs/shared/feature/user-context/src/lib/shared-user-context.interceptor.spec.ts index c7896553d..e7eccc943 100644 --- a/libs/shared/feature/user-context/src/lib/shared-user-context.interceptor.spec.ts +++ b/libs/shared/feature/user-context/src/lib/shared-user-context.interceptor.spec.ts @@ -1,30 +1,36 @@ import { HttpHandler, HttpRequest } from '@angular/common/http'; import { EMPTY } from 'rxjs'; -import { MemoryStorage } from 'angular-oauth2-oidc'; /* eslint-disable @typescript-eslint/no-explicit-any */ import { SharedUserContextInterceptor } from './shared-user-context.interceptor'; import { SharedUserContextService } from './shared-user-context.service'; -import { Environment } from '@backbase/shared/util/config'; +import { TestBed } from '@angular/core/testing'; +import { API_ROOT } from '@backbase/foundation-ang/core'; describe('UserContextInterceptor', () => { + beforeEach(() => { + TestBed.resetTestingModule(); + }); + function setupInterceptor( { apiRoot }: { apiRoot: string } = { apiRoot: '/whatever' } ) { - const environment: Environment = { - apiRoot, - production: false, - locales: [], - common: { designSlimMode: false }, - }; - const userContextService = new SharedUserContextService( - new MemoryStorage() - ); + let serviceAgreementId: string | null = null; + const userContextService = { + setServiceAgreementId: jest.fn((id: string) => { + serviceAgreementId = id; + }), + getServiceAgreementId: jest.fn(() => serviceAgreementId), + } as unknown as jest.Mocked; - const interceptor = new SharedUserContextInterceptor( - userContextService, - environment - ); + TestBed.configureTestingModule({ + providers: [ + SharedUserContextInterceptor, + { provide: SharedUserContextService, useValue: userContextService }, + { provide: API_ROOT, useValue: apiRoot }, + ], + }); + const interceptor = TestBed.inject(SharedUserContextInterceptor); const nextHandler = jest.mocked({ handle: jest.fn(), diff --git a/libs/shared/feature/user-context/src/lib/shared-user-context.interceptor.ts b/libs/shared/feature/user-context/src/lib/shared-user-context.interceptor.ts index 73c63ebf6..199461f78 100644 --- a/libs/shared/feature/user-context/src/lib/shared-user-context.interceptor.ts +++ b/libs/shared/feature/user-context/src/lib/shared-user-context.interceptor.ts @@ -26,10 +26,19 @@ export class SharedUserContextInterceptor implements HttpInterceptor { next: HttpHandler ): Observable> { const context = this.#userContextService.getServiceAgreementId(); - if (context && req.url.startsWith(this.#apiRoot)) { + if (context && this.#shouldAddHeader(req.url)) { const headers = req.headers.set('X-USER-CONTEXT', context); req = req.clone({ headers }); } return next.handle(req); } + + #shouldAddHeader(url: string): boolean { + // If API root ends with slash, check if URL starts with API root + if (this.#apiRoot.endsWith('/')) { + return url.startsWith(this.#apiRoot); + } + // If API root doesn't end with slash, check if URL starts with API root followed by slash + return url.startsWith(this.#apiRoot + '/'); + } } diff --git a/libs/shared/feature/user-context/src/lib/shared-user-context.service.spec.ts b/libs/shared/feature/user-context/src/lib/shared-user-context.service.spec.ts index 63954c48d..d39dafb47 100644 --- a/libs/shared/feature/user-context/src/lib/shared-user-context.service.spec.ts +++ b/libs/shared/feature/user-context/src/lib/shared-user-context.service.spec.ts @@ -1,8 +1,10 @@ +import { TestBed } from '@angular/core/testing'; import { USER_CONTEXT_KEY, SharedUserContextService, + UserContextStorage, } from './shared-user-context.service'; -import { MemoryStorage } from 'angular-oauth2-oidc'; +import { MemoryStorage, OAuthStorage } from 'angular-oauth2-oidc'; describe('UserContextService', () => { beforeEach(() => { @@ -13,10 +15,14 @@ describe('UserContextService', () => { function configureService() { const userContextStore = new MemoryStorage(); const oAuthStore = new MemoryStorage(); - const service = new SharedUserContextService( - userContextStore, - oAuthStore - ); + TestBed.configureTestingModule({ + providers: [ + SharedUserContextService, + { provide: UserContextStorage, useValue: userContextStore }, + { provide: OAuthStorage, useValue: oAuthStore }, + ], + }); + const service = TestBed.inject(SharedUserContextService); return { userContextStore, oAuthStore, service }; } @@ -65,55 +71,63 @@ describe('UserContextService', () => { }); describe('when no explicit UserContextStorage is configured and an OAuthStorage is configured', () => { - function configureService() { + function configureServiceNoUserContextStorage() { const oAuthStore = new MemoryStorage(); - const service = new SharedUserContextService(undefined, oAuthStore); + TestBed.configureTestingModule({ + providers: [ + SharedUserContextService, + { provide: OAuthStorage, useValue: oAuthStore }, + ], + }); + const service = TestBed.inject(SharedUserContextService); return { oAuthStore, service }; } - it('should return null when no service agreement ID has been set', () => { - const { service } = configureService(); + const { service } = configureServiceNoUserContextStorage(); expect(service.getServiceAgreementId()).toBeUndefined(); }); it('should store the SAID in the OAuthStorage', () => { - const { oAuthStore, service } = configureService(); + const { oAuthStore, service } = configureServiceNoUserContextStorage(); service.setServiceAgreementId('cafed00d'); expect(oAuthStore.getItem(USER_CONTEXT_KEY)).toStrictEqual('cafed00d'); }); it('should retrieve the stored value from the OAuthStorage', () => { - const { oAuthStore, service } = configureService(); + const { oAuthStore, service } = configureServiceNoUserContextStorage(); oAuthStore.setItem(USER_CONTEXT_KEY, 'cafed00d'); expect(service.getServiceAgreementId()).toStrictEqual('cafed00d'); }); it('should not store the SAID in the SessionStorage', () => { - const { service } = configureService(); + const { service } = configureServiceNoUserContextStorage(); service.setServiceAgreementId('feedface'); expect(sessionStorage.getItem(USER_CONTEXT_KEY)).toBeNull(); }); it('should not retrieve the stored value from the SessionStorage', () => { - const { service } = configureService(); + const { service } = configureServiceNoUserContextStorage(); sessionStorage.setItem(USER_CONTEXT_KEY, 'deadbeef'); expect(service.getServiceAgreementId()).toBeUndefined(); }); }); describe('when no explicit UserContextStorage or OAuthStorage are configured', () => { - function configureService() { - const service = new SharedUserContextService(undefined, undefined); + function configureServiceNoOAuthStorageNoUserContextStorage() { + TestBed.configureTestingModule({ + providers: [SharedUserContextService], + }); + const service = TestBed.inject(SharedUserContextService); return { service }; } it('should return null when no service agreement ID has been set', () => { - const { service } = configureService(); + const { service } = configureServiceNoOAuthStorageNoUserContextStorage(); expect(service.getServiceAgreementId()).toBeUndefined(); }); it('should store the SAID in the SessionStorage', () => { - const { service } = configureService(); + const { service } = configureServiceNoOAuthStorageNoUserContextStorage(); service.setServiceAgreementId('deadbeef'); expect(sessionStorage.getItem(USER_CONTEXT_KEY)).toStrictEqual( 'deadbeef' @@ -121,7 +135,7 @@ describe('UserContextService', () => { }); it('should retrieve the stored value from the SessionStorage', () => { - const { service } = configureService(); + const { service } = configureServiceNoOAuthStorageNoUserContextStorage(); sessionStorage.setItem(USER_CONTEXT_KEY, 'deadbeef'); expect(service.getServiceAgreementId()).toStrictEqual('deadbeef'); }); diff --git a/libs/shared/util/app-core/src/lib/locales.service.spec.ts b/libs/shared/util/app-core/src/lib/locales.service.spec.ts index 16818d0a9..4264f6167 100644 --- a/libs/shared/util/app-core/src/lib/locales.service.spec.ts +++ b/libs/shared/util/app-core/src/lib/locales.service.spec.ts @@ -1,5 +1,7 @@ -import { LocationStrategy } from '@angular/common'; +import { DOCUMENT, LocationStrategy } from '@angular/common'; import { LocalesService } from './locales.service'; +import { TestBed } from '@angular/core/testing'; +import { LOCALE_ID } from '@angular/core'; describe('LocalesService', () => { let service: LocalesService; @@ -22,12 +24,15 @@ describe('LocalesService', () => { href: '/test-app/en/some/path', } as Location, }; - - service = new LocalesService( - locationStrategy, - mockLocale, - document as Document - ); + TestBed.configureTestingModule({ + providers: [ + LocalesService, + { provide: LocationStrategy, useValue: locationStrategy }, + { provide: LOCALE_ID, useValue: mockLocale }, + { provide: DOCUMENT, useValue: document as Document }, + ], + }); + service = TestBed.inject(LocalesService); }); describe('currentLocale', () => { diff --git a/libs/transactions-journey/internal/data-access/src/lib/services/arrangements/arrangements.service.spec.ts b/libs/transactions-journey/internal/data-access/src/lib/services/arrangements/arrangements.service.spec.ts index 9b41deb1a..4ffecf184 100644 --- a/libs/transactions-journey/internal/data-access/src/lib/services/arrangements/arrangements.service.spec.ts +++ b/libs/transactions-journey/internal/data-access/src/lib/services/arrangements/arrangements.service.spec.ts @@ -1,6 +1,7 @@ import { ProductSummaryHttpService } from '@backbase/arrangement-manager-http-ang'; import { of } from 'rxjs'; import { ArrangementsService } from './arrangements.service'; +import { TestBed } from '@angular/core/testing'; describe('ArrangementsService', () => { let service: ArrangementsService; @@ -17,7 +18,16 @@ describe('ArrangementsService', () => { } as unknown as ProductSummaryHttpService; beforeEach(() => { - service = new ArrangementsService(mockProductSummaryService); + TestBed.configureTestingModule({ + providers: [ + ArrangementsService, + { + provide: ProductSummaryHttpService, + useValue: mockProductSummaryService, + }, + ], + }); + service = TestBed.inject(ArrangementsService); }); it('should call product summary service to get arrangements', (done) => { diff --git a/libs/transactions-journey/internal/data-access/src/lib/services/transactions-http/transactions.http.service.spec.ts b/libs/transactions-journey/internal/data-access/src/lib/services/transactions-http/transactions.http.service.spec.ts index 924b2814a..365537005 100644 --- a/libs/transactions-journey/internal/data-access/src/lib/services/transactions-http/transactions.http.service.spec.ts +++ b/libs/transactions-journey/internal/data-access/src/lib/services/transactions-http/transactions.http.service.spec.ts @@ -6,6 +6,7 @@ import { of } from 'rxjs'; import { ArrangementsService } from '../arrangements/arrangements.service'; import { TransactionsJourneyConfiguration } from '../transactions-journey-config/transactions-journey-config.service'; import { TransactionsHttpService } from './transactions.http.service'; +import { TestBed } from '@angular/core/testing'; describe('TransactionsHttpService', () => { let service: TransactionsHttpService; @@ -24,12 +25,21 @@ describe('TransactionsHttpService', () => { } as ArrangementsService; beforeEach(() => { - service = new TransactionsHttpService( - mockConfigurationService, - mockTransactionsClientHttpService, - mockArrangementsService - ); - + TestBed.configureTestingModule({ + providers: [ + TransactionsHttpService, + { + provide: TransactionsJourneyConfiguration, + useValue: mockConfigurationService, + }, + { + provide: TransactionClientHttpService, + useValue: mockTransactionsClientHttpService, + }, + { provide: ArrangementsService, useValue: mockArrangementsService }, + ], + }); + service = TestBed.inject(TransactionsHttpService); jest.spyOn(mockTransactionsClientHttpService, 'getTransactionsWithPost'); }); diff --git a/libs/transactions-journey/internal/data-access/src/lib/services/transactions-route-title-resolver/transactions-route-title-resolver.service.spec.ts b/libs/transactions-journey/internal/data-access/src/lib/services/transactions-route-title-resolver/transactions-route-title-resolver.service.spec.ts index 74fa1dbdc..35fa8ca0b 100644 --- a/libs/transactions-journey/internal/data-access/src/lib/services/transactions-route-title-resolver/transactions-route-title-resolver.service.spec.ts +++ b/libs/transactions-journey/internal/data-access/src/lib/services/transactions-route-title-resolver/transactions-route-title-resolver.service.spec.ts @@ -1,16 +1,24 @@ /* eslint-disable @typescript-eslint/no-explicit-any */ +import { TestBed } from '@angular/core/testing'; import { TransactionsJourneyConfiguration } from '../transactions-journey-config/transactions-journey-config.service'; import { TransactionsRouteTitleResolverService } from './transactions-route-title-resolver.service'; describe('MakeTransferRouteTitleResolverService', () => { - function createInstance(config: Partial) { - return new TransactionsRouteTitleResolverService( - config as TransactionsJourneyConfiguration - ); + function setup(config: Partial) { + TestBed.configureTestingModule({ + providers: [ + TransactionsRouteTitleResolverService, + { + provide: TransactionsJourneyConfiguration, + useValue: config, + }, + ], + }); + return TestBed.inject(TransactionsRouteTitleResolverService); } it('should resolve route with the title data if the `slimMode` configuration is set as false', () => { - const service = createInstance({ slimMode: false }); + const service = setup({ slimMode: false }); const result = service.resolve({ data: { title: 'hello', @@ -21,7 +29,7 @@ describe('MakeTransferRouteTitleResolverService', () => { }); it('should resolve route without the title data if the `slimMode` configuration is set as true', () => { - const service = createInstance({ slimMode: true }); + const service = setup({ slimMode: true }); const result = service.resolve({ data: { title: 'hello', diff --git a/libs/transfer-journey/internal/data-access/src/lib/services/make-transfer-journey-state/make-transfer-journey-state.service.spec.ts b/libs/transfer-journey/internal/data-access/src/lib/services/make-transfer-journey-state/make-transfer-journey-state.service.spec.ts index d0a3948e6..fbcc0f6ed 100644 --- a/libs/transfer-journey/internal/data-access/src/lib/services/make-transfer-journey-state/make-transfer-journey-state.service.spec.ts +++ b/libs/transfer-journey/internal/data-access/src/lib/services/make-transfer-journey-state/make-transfer-journey-state.service.spec.ts @@ -2,6 +2,7 @@ import { of } from 'rxjs'; import { Transfer } from '@backbase/transfer-journey/internal/shared-data'; import { MakeTransferAccountHttpService } from '../make-transfer-accounts/make-transfer-accounts.http.service'; import { MakeTransferJourneyState } from './make-transfer-journey-state.service'; +import { TestBed } from '@angular/core/testing'; describe('MakeTransferJourneyState', () => { let service: MakeTransferJourneyState; @@ -22,9 +23,13 @@ describe('MakeTransferJourneyState', () => { getAccounts: jest.fn().mockReturnValue(of([])), makeTransfer: jest.fn(), }; - service = new MakeTransferJourneyState( - accountsMock as MakeTransferAccountHttpService - ); + TestBed.configureTestingModule({ + providers: [ + MakeTransferJourneyState, + { provide: MakeTransferAccountHttpService, useValue: accountsMock }, + ], + }); + service = TestBed.inject(MakeTransferJourneyState); }); it('should allow share an object through an observable', (done) => { diff --git a/libs/transfer-journey/internal/data-access/src/lib/services/make-transfer-permissions/make-transfer-permissions.service.spec.ts b/libs/transfer-journey/internal/data-access/src/lib/services/make-transfer-permissions/make-transfer-permissions.service.spec.ts index 924d153e1..62bbfb006 100644 --- a/libs/transfer-journey/internal/data-access/src/lib/services/make-transfer-permissions/make-transfer-permissions.service.spec.ts +++ b/libs/transfer-journey/internal/data-access/src/lib/services/make-transfer-permissions/make-transfer-permissions.service.spec.ts @@ -1,5 +1,6 @@ import { ConditionsService } from '@backbase/foundation-ang/entitlements'; import { MakeTransferPermissionsService } from './make-transfer-permissions.service'; +import { TestBed } from '@angular/core/testing'; describe('MakeTransferPermissionsService', () => { let service: MakeTransferPermissionsService; @@ -8,9 +9,13 @@ describe('MakeTransferPermissionsService', () => { resolveEntitlements: jest.fn(() => Promise.resolve(true)), }; beforeEach(() => { - service = new MakeTransferPermissionsService( - mockConditionsService as ConditionsService - ); + TestBed.configureTestingModule({ + providers: [ + MakeTransferPermissionsService, + { provide: ConditionsService, useValue: mockConditionsService }, + ], + }); + service = TestBed.inject(MakeTransferPermissionsService); }); it('should evaluate a permission in the entitlements resolver', (done) => { diff --git a/libs/transfer-journey/internal/feature/src/lib/components/make-transfer-success-view/make-transfer-success-view.component.spec.ts b/libs/transfer-journey/internal/feature/src/lib/components/make-transfer-success-view/make-transfer-success-view.component.spec.ts index fc92feabe..a345d0b7f 100644 --- a/libs/transfer-journey/internal/feature/src/lib/components/make-transfer-success-view/make-transfer-success-view.component.spec.ts +++ b/libs/transfer-journey/internal/feature/src/lib/components/make-transfer-success-view/make-transfer-success-view.component.spec.ts @@ -6,6 +6,7 @@ import { import { of } from 'rxjs'; import { MakeTransferJourneyState } from '@backbase/transfer-journey/internal/data-access'; import { MakeTransferSuccessViewComponent } from './make-transfer-success-view.component'; +import { TestBed } from '@angular/core/testing'; describe('MakeTransferSuccessViewComponent', () => { let component: MakeTransferSuccessViewComponent; @@ -26,11 +27,15 @@ describe('MakeTransferSuccessViewComponent', () => { mockTransferState = { transfer$: of(), }; - component = new MakeTransferSuccessViewComponent( - mockTransferState as MakeTransferJourneyState, - mockActivatedRoute as ActivatedRoute, - mockRouter as Router - ); + TestBed.configureTestingModule({ + providers: [ + MakeTransferSuccessViewComponent, + { provide: MakeTransferJourneyState, useValue: mockTransferState }, + { provide: ActivatedRoute, useValue: mockActivatedRoute }, + { provide: Router, useValue: mockRouter }, + ], + }); + component = TestBed.inject(MakeTransferSuccessViewComponent); }); it('should create', () => { diff --git a/libs/transfer-journey/internal/feature/src/lib/components/make-transfer-summary-view/make-transfer-summary-view.component.spec.ts b/libs/transfer-journey/internal/feature/src/lib/components/make-transfer-summary-view/make-transfer-summary-view.component.spec.ts index 6b8572a3e..4e3cd7c9e 100644 --- a/libs/transfer-journey/internal/feature/src/lib/components/make-transfer-summary-view/make-transfer-summary-view.component.spec.ts +++ b/libs/transfer-journey/internal/feature/src/lib/components/make-transfer-summary-view/make-transfer-summary-view.component.spec.ts @@ -10,14 +10,14 @@ import { TransferOperationStatus, } from '@backbase/transfer-journey/internal/data-access'; import { MakeTransferSummaryViewComponent } from './make-transfer-summary-view.component'; +import { TestBed } from '@angular/core/testing'; describe('MakeTransferSymmaryViewComponent', () => { let component: MakeTransferSummaryViewComponent; - let mockCommunicationService: - | Pick - | undefined = { - makeTransfer: jest.fn(), - }; + let mockCommunicationService: Pick< + MakeTransferCommunicationService, + 'makeTransfer' + >; const transferMock = { fromAccount: 'somAccount', toAccount: 'somAccount', @@ -36,7 +36,8 @@ describe('MakeTransferSymmaryViewComponent', () => { snapshot: snapshot as ActivatedRouteSnapshot, }; let mockRouter: Pick; - const createComponent = () => { + + const createComponent = (withCommunicationService = true) => { mockTransferState = { transfer$: of(transferMock), vm$: of({ @@ -51,15 +52,33 @@ describe('MakeTransferSymmaryViewComponent', () => { mockRouter = { navigate: jest.fn(), }; - component = new MakeTransferSummaryViewComponent( - mockTransferState as MakeTransferJourneyState, - mockActivatedRoute as ActivatedRoute, - mockRouter as Router, - mockCommunicationService as MakeTransferCommunicationService - ); + mockCommunicationService = { + makeTransfer: jest.fn(), + }; + + const providers: any[] = [ + { provide: MakeTransferJourneyState, useValue: mockTransferState }, + { provide: ActivatedRoute, useValue: mockActivatedRoute }, + { provide: Router, useValue: mockRouter }, + ]; + + if (withCommunicationService) { + providers.push({ + provide: MakeTransferCommunicationService, + useValue: mockCommunicationService, + }); + } + + TestBed.configureTestingModule({ + imports: [MakeTransferSummaryViewComponent], + providers, + }); + const fixture = TestBed.createComponent(MakeTransferSummaryViewComponent); + component = fixture.componentInstance; }; beforeEach(() => { + TestBed.resetTestingModule(); createComponent(); }); @@ -68,8 +87,9 @@ describe('MakeTransferSymmaryViewComponent', () => { }); describe('submit', () => { - it('should create', () => { - expect(component).toBeTruthy(); + it('should call makeTransfer on the transfer store', () => { + component.submit(); + expect(mockTransferState.makeTransfer).toHaveBeenCalled(); }); }); @@ -82,17 +102,30 @@ describe('MakeTransferSymmaryViewComponent', () => { }); }); - describe('submit', () => { - it('should emit a submit event', () => { - mockCommunicationService = undefined; - createComponent(); - component.submit(); - expect(mockTransferState.makeTransfer).toHaveBeenCalled(); + describe('with external communication service', () => { + beforeEach(() => { + TestBed.resetTestingModule(); + createComponent(true); + }); + + it('should call external communication service when transfer is successful', () => { + // The component subscribes to vm$ and automatically triggers navigation/communication + // when transferState is SUCCESSFUL, which is already set in our mock + expect(mockCommunicationService.makeTransfer).toHaveBeenCalledWith( + transferMock + ); + }); + }); + + describe('without external communication service', () => { + beforeEach(() => { + TestBed.resetTestingModule(); + createComponent(false); }); - it('should navigate', () => { - mockCommunicationService = undefined; - createComponent(); + it('should navigate to success page when transfer is successful', () => { + // The component subscribes to vm$ and automatically triggers navigation + // when transferState is SUCCESSFUL, which is already set in our mock expect(mockRouter.navigate).toHaveBeenCalledWith( ['../make-transfer-success'], { diff --git a/libs/transfer-journey/internal/feature/src/lib/components/make-transfer-view/make-transfer-view.component.spec.ts b/libs/transfer-journey/internal/feature/src/lib/components/make-transfer-view/make-transfer-view.component.spec.ts index 3c530d950..61637f313 100644 --- a/libs/transfer-journey/internal/feature/src/lib/components/make-transfer-view/make-transfer-view.component.spec.ts +++ b/libs/transfer-journey/internal/feature/src/lib/components/make-transfer-view/make-transfer-view.component.spec.ts @@ -11,6 +11,7 @@ import { MakeTransferPermissionsService, } from '@backbase/transfer-journey/internal/data-access'; import { MakeTransferViewComponent } from './make-transfer-view.component'; +import { TestBed } from '@angular/core/testing'; describe('MakeTransferViewComponent', () => { let component: MakeTransferViewComponent; @@ -53,13 +54,17 @@ describe('MakeTransferViewComponent', () => { }; beforeEach(() => { - component = new MakeTransferViewComponent( - mockActivatedRoute as ActivatedRoute, - mockRouter as Router, - mockTransferState as MakeTransferJourneyState, - mockPermissions as MakeTransferPermissionsService, - mockConfig as MakeTransferJourneyConfiguration - ); + TestBed.configureTestingModule({ + providers: [ + MakeTransferViewComponent, + { provide: ActivatedRoute, useValue: mockActivatedRoute }, + { provide: Router, useValue: mockRouter }, + { provide: MakeTransferJourneyState, useValue: mockTransferState }, + { provide: MakeTransferPermissionsService, useValue: mockPermissions }, + { provide: MakeTransferJourneyConfiguration, useValue: mockConfig }, + ], + }); + component = TestBed.inject(MakeTransferViewComponent); }); it('should create', () => { diff --git a/libs/transfer-journey/internal/ui/src/lib/components/make-transfer-form/make-transfer-form.component.spec.ts b/libs/transfer-journey/internal/ui/src/lib/components/make-transfer-form/make-transfer-form.component.spec.ts index fc3b31dca..82ba1c1ea 100644 --- a/libs/transfer-journey/internal/ui/src/lib/components/make-transfer-form/make-transfer-form.component.spec.ts +++ b/libs/transfer-journey/internal/ui/src/lib/components/make-transfer-form/make-transfer-form.component.spec.ts @@ -20,7 +20,9 @@ describe('MakeTransferFormComponent', () => { route = TestBed.inject(ActivatedRoute); }); beforeEach(() => { - component = new MakeTransferFormComponent(formBuilder, route); + component = TestBed.createComponent( + MakeTransferFormComponent + ).componentInstance; }); it('should create', () => {