From bc75c669d8c871ed9505f0267535614229c29f19 Mon Sep 17 00:00:00 2001 From: Viswas Haridas <37623357+JustARatherRidiculouslyLongUsername@users.noreply.github.com> Date: Fri, 20 Sep 2024 18:13:28 +0530 Subject: [PATCH] test: add unit tests for IntacctComponent (#969) * test: add unit tests for IntacctComponent * refactor: lint --- .../intacct/intacct.component.spec.ts | 168 +++++++++++++----- .../integrations/intacct/intacct.component.ts | 2 +- .../integrations/intacct/intacct.fixture.ts | 16 ++ 3 files changed, 144 insertions(+), 42 deletions(-) diff --git a/src/app/integrations/intacct/intacct.component.spec.ts b/src/app/integrations/intacct/intacct.component.spec.ts index dcde1c309..138779464 100644 --- a/src/app/integrations/intacct/intacct.component.spec.ts +++ b/src/app/integrations/intacct/intacct.component.spec.ts @@ -1,49 +1,135 @@ import { ComponentFixture, TestBed } from '@angular/core/testing'; -import { HttpClientModule } from '@angular/common/http'; -import { HttpClientTestingModule } from '@angular/common/http/testing'; -import { RouterTestingModule } from '@angular/router/testing'; -import { of, throwError } from 'rxjs'; +import { Router, NavigationEnd, RouterModule } from '@angular/router'; +import { of } from 'rxjs'; import { IntacctComponent } from './intacct.component'; -import { errorResponse, workspaceResponse } from './intacct.fixture'; +import { HelperService } from 'src/app/core/services/common/helper.service'; +import { StorageService } from 'src/app/core/services/common/storage.service'; +import { WindowService } from 'src/app/core/services/common/window.service'; +import { AppcuesService } from 'src/app/core/services/integration/appcues.service'; +import { UserService } from 'src/app/core/services/misc/user.service'; import { SiWorkspaceService } from 'src/app/core/services/si/si-core/si-workspace.service'; +import { AppName, AppUrl, IntacctOnboardingState } from 'src/app/core/models/enum/enum.model'; +import { mockUser, testOnboardingState, workspaceResponse } from './intacct.fixture'; +import { IntacctWorkspace } from 'src/app/core/models/intacct/db/workspaces.model'; -xdescribe('SiComponent', () => { +describe('IntacctComponent', () => { let component: IntacctComponent; let fixture: ComponentFixture; - let workspace: SiWorkspaceService; + let userServiceSpy: jasmine.SpyObj; + let workspaceServiceSpy: jasmine.SpyObj; + let helperServiceSpy: jasmine.SpyObj; + let storageServiceSpy: jasmine.SpyObj; + let routerSpy: jasmine.SpyObj; + let windowServiceMock: Partial; + let appcuesServiceSpy: jasmine.SpyObj; beforeEach(async () => { - const localStorageDump = { - email: 'anishkumar.s@fyle.in', - org_id: 'abcdefgh' - }; - localStorage.setItem('user', JSON.stringify(localStorageDump)); - const service1 = { - getWorkspace: () => of(workspaceResponse), - postWorkspace: () => of(workspaceResponse) - }; - await TestBed.configureTestingModule({ - imports: [RouterTestingModule, HttpClientModule, HttpClientTestingModule], - declarations: [ IntacctComponent ], - providers: [ - { provide: SiWorkspaceService, useValue: service1 } - ] - }) - .compileComponents(); - - fixture = TestBed.createComponent(IntacctComponent); - component = fixture.componentInstance; - workspace = TestBed.inject(SiWorkspaceService); - fixture.detectChanges(); -}); - -it('should create', () => { - expect(component).toBeTruthy(); -}); - -it('ngOnIng function check', async () => { - expect((component as any).getOrCreateWorkspace()).toBeUndefined(); - spyOn(workspace, 'getWorkspace').and.returnValue(of([])); - expect((component as any).getOrCreateWorkspace()).toBeUndefined(); -}); -}); + const userSpy = jasmine.createSpyObj('UserService', ['getUserProfile']); + const workspaceSpy = jasmine.createSpyObj('SiWorkspaceService', ['getWorkspace', 'postWorkspace', 'syncFyleDimensions', 'syncIntacctDimensions']); + const helperSpy = jasmine.createSpyObj('HelperService', ['setBaseApiURL']); + const storageSpy = jasmine.createSpyObj('StorageService', ['set']); + const routerSpyObj = jasmine.createSpyObj('Router', ['navigateByUrl', 'events']); + const appcuesSpy = jasmine.createSpyObj('AppcuesService', ['initialiseAppcues']); + + windowServiceMock = { + get nativeWindow() { + return { + location: { + pathname: '/integrations/intacct' + } + } as Window; + } + }; + + await TestBed.configureTestingModule({ + declarations: [ IntacctComponent ], + imports: [RouterModule], + providers: [ + { provide: HelperService, useValue: helperSpy }, + { provide: AppcuesService, useValue: appcuesSpy }, + { provide: Router, useValue: routerSpyObj }, + { provide: StorageService, useValue: storageSpy }, + { provide: UserService, useValue: userSpy }, + { provide: SiWorkspaceService, useValue: workspaceSpy }, + { provide: WindowService, useValue: windowServiceMock } + ] + }).compileComponents(); + + userServiceSpy = TestBed.inject(UserService) as jasmine.SpyObj; + workspaceServiceSpy = TestBed.inject(SiWorkspaceService) as jasmine.SpyObj; + helperServiceSpy = TestBed.inject(HelperService) as jasmine.SpyObj; + storageServiceSpy = TestBed.inject(StorageService) as jasmine.SpyObj; + routerSpy = TestBed.inject(Router) as jasmine.SpyObj; + (routerSpy.events as any) = of(new NavigationEnd(0, '', '')); + appcuesServiceSpy = TestBed.inject(AppcuesService) as jasmine.SpyObj; + + userServiceSpy.getUserProfile.and.returnValue(mockUser); + workspaceServiceSpy.getWorkspace.and.returnValue(of(workspaceResponse)); + workspaceServiceSpy.syncFyleDimensions.and.returnValue(of()); + workspaceServiceSpy.syncIntacctDimensions.and.returnValue(of()); + + fixture = TestBed.createComponent(IntacctComponent); + component = fixture.componentInstance; + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); + + it('should setup workspace and navigate when workspace exists', () => { + fixture.detectChanges(); + + expect(helperServiceSpy.setBaseApiURL).toHaveBeenCalledWith(AppUrl.INTACCT); + expect(workspaceServiceSpy.getWorkspace).toHaveBeenCalledWith('mock org id'); + expect(storageServiceSpy.set).toHaveBeenCalledWith('workspaceId', 1); + expect(storageServiceSpy.set).toHaveBeenCalledWith('onboarding-state', IntacctOnboardingState.CONNECTION); + expect(workspaceServiceSpy.syncFyleDimensions).toHaveBeenCalled(); + expect(workspaceServiceSpy.syncIntacctDimensions).toHaveBeenCalled(); + expect(routerSpy.navigateByUrl).toHaveBeenCalledWith('/integrations/intacct/onboarding/landing'); + }); + + it('should create a new workspace if none exists', () => { + workspaceServiceSpy.getWorkspace.and.returnValue(of([])); + workspaceServiceSpy.postWorkspace.and.returnValue(of(workspaceResponse[0])); + + fixture.detectChanges(); + + expect(workspaceServiceSpy.postWorkspace).toHaveBeenCalled(); + expect(storageServiceSpy.set).toHaveBeenCalledWith('workspaceId', 1); + expect(storageServiceSpy.set).toHaveBeenCalledWith('onboarding-state', IntacctOnboardingState.CONNECTION); + expect(routerSpy.navigateByUrl).toHaveBeenCalledWith('/integrations/intacct/onboarding/landing'); + }); + + it('should navigate to correct route based on onboarding state', () => { + Object.entries(testOnboardingState).forEach(([state, route ]) => { + routerSpy.navigateByUrl.calls.reset(); + const testWorkspace: IntacctWorkspace = { ...workspaceResponse[0], onboarding_state: state as IntacctOnboardingState }; + workspaceServiceSpy.getWorkspace.and.returnValue(of([testWorkspace])); + + fixture.detectChanges(); + + expect(routerSpy.navigateByUrl).toHaveBeenCalledWith(route); + + fixture = TestBed.createComponent(IntacctComponent); + component = fixture.componentInstance; + }); + }); + + it('should not navigate if pathname is not /integrations/intacct', () => { + component.windowReference.location.pathname = '/some/other/path'; + fixture.detectChanges(); + + expect(routerSpy.navigateByUrl).not.toHaveBeenCalled(); + }); + + it('should initialise Appcues', () => { + (window as any).Appcues = { + page: jasmine.createSpy('Appcues.page') + }; + + fixture.detectChanges(); + + expect(appcuesServiceSpy.initialiseAppcues).toHaveBeenCalled(); + expect((window as any).Appcues.page).toHaveBeenCalled(); + }); +}); \ No newline at end of file diff --git a/src/app/integrations/intacct/intacct.component.ts b/src/app/integrations/intacct/intacct.component.ts index f1a8cd62b..fb2ff7c7c 100644 --- a/src/app/integrations/intacct/intacct.component.ts +++ b/src/app/integrations/intacct/intacct.component.ts @@ -66,7 +66,7 @@ export class IntacctComponent implements OnInit { private getOrCreateWorkspace(): void { this.helperService.setBaseApiURL(AppUrl.INTACCT); this.workspaceService.getWorkspace(this.user.org_id).subscribe((workspaces) => { - if (workspaces.length) { + if (workspaces.length && workspaces.length > 0) { this.setupWorkspace(workspaces[0]); } else { this.workspaceService.postWorkspace().subscribe((workspaces: IntacctWorkspace) => { diff --git a/src/app/integrations/intacct/intacct.fixture.ts b/src/app/integrations/intacct/intacct.fixture.ts index 6154313cc..07a0d8d15 100644 --- a/src/app/integrations/intacct/intacct.fixture.ts +++ b/src/app/integrations/intacct/intacct.fixture.ts @@ -1,3 +1,5 @@ +import { minimalUser } from "src/app/core/interceptor/jwt.fixture"; +import { MinimalUser } from "src/app/core/models/db/user.model"; import { IntacctOnboardingState } from "src/app/core/models/enum/enum.model"; import { IntacctWorkspace } from "src/app/core/models/intacct/db/workspaces.model"; @@ -25,4 +27,18 @@ export const workspaceResponse: IntacctWorkspace[] = [{ is_expired: true, company_name: 'Halo MasterChief' } +}; + +export const mockUser: MinimalUser = { + ...minimalUser, + org_id: 'mock org id' +}; + +export const testOnboardingState: {[k in IntacctOnboardingState]: string} = { + [IntacctOnboardingState.CONNECTION]: '/integrations/intacct/onboarding/landing', + [IntacctOnboardingState.LOCATION_ENTITY]: '/integrations/intacct/onboarding/connector', + [IntacctOnboardingState.EXPORT_SETTINGS]: '/integrations/intacct/onboarding/export_settings', + [IntacctOnboardingState.IMPORT_SETTINGS]: '/integrations/intacct/onboarding/import_settings', + [IntacctOnboardingState.ADVANCED_CONFIGURATION]: '/integrations/intacct/onboarding/advanced_settings', + [IntacctOnboardingState.COMPLETE]: '/integrations/intacct/main/dashboard' }; \ No newline at end of file