1- import { ComponentFixture , TestBed } from '@angular/core/testing' ;
1+ import { ComponentFixture , fakeAsync , TestBed , tick } from '@angular/core/testing' ;
2+ import { AbstractControl , FormArray , FormBuilder , ReactiveFormsModule , Validators } from '@angular/forms' ;
3+ import { provideRouter , Router , RouterModule } from '@angular/router' ;
4+ import { of , throwError } from 'rxjs' ;
25
36import { IntacctImportSettingsComponent } from './intacct-import-settings.component' ;
7+ import { SiImportSettingService } from 'src/app/core/services/si/si-configuration/si-import-setting.service' ;
8+ import { SiMappingsService } from 'src/app/core/services/si/si-core/si-mappings.service' ;
9+ import { IntacctConnectorService } from 'src/app/core/services/si/si-core/intacct-connector.service' ;
10+ import { OrgService } from 'src/app/core/services/org/org.service' ;
11+ import { TrackingService } from 'src/app/core/services/integration/tracking.service' ;
12+ import { IntegrationsToastService } from 'src/app/core/services/common/integrations-toast.service' ;
13+ import { StorageService } from 'src/app/core/services/common/storage.service' ;
14+ import { SiWorkspaceService } from 'src/app/core/services/si/si-core/si-workspace.service' ;
15+ import { HelperService } from 'src/app/core/services/common/helper.service' ;
416
5- xdescribe ( 'IntacctImportSettingsComponent' , ( ) => {
17+ import { configuration , costCodeFieldValue , costTypeFieldValue , fyleFields , groupedDestinationAttributes , importSettings , importSettingsWithProject , intacctImportCodeConfig , locationEntityMapping , sageIntacctFields , sageIntacctFieldsSortedByPriority , settingsWithDependentFields } from '../../intacct.fixture' ;
18+ import { IntacctCategoryDestination , IntacctOnboardingState , ToastSeverity } from 'src/app/core/models/enum/enum.model' ;
19+ import { SharedModule } from 'src/app/shared/shared.module' ;
20+ import { Org } from 'src/app/core/models/org/org.model' ;
21+ import { HttpClientTestingModule } from '@angular/common/http/testing' ;
22+ import { LocationEntityMapping } from 'src/app/core/models/intacct/db/location-entity-mapping.model' ;
23+ import { IntacctSharedModule } from '../intacct-shared.module' ;
24+ import { ExpenseField } from 'src/app/core/models/intacct/db/expense-field.model' ;
25+ import { ImportSettingGet } from 'src/app/core/models/intacct/intacct-configuration/import-settings.model' ;
26+ import { IntacctConfiguration } from 'src/app/core/models/db/configuration.model' ;
27+
28+ describe ( 'IntacctImportSettingsComponent' , ( ) => {
629 let component : IntacctImportSettingsComponent ;
730 let fixture : ComponentFixture < IntacctImportSettingsComponent > ;
31+ let siImportSettingService : jasmine . SpyObj < SiImportSettingService > ;
32+ let siMappingsService : jasmine . SpyObj < SiMappingsService > ;
33+ let intacctConnectorService : jasmine . SpyObj < IntacctConnectorService > ;
34+ let orgService : jasmine . SpyObj < OrgService > ;
35+ let trackingService : jasmine . SpyObj < TrackingService > ;
36+ let toastService : jasmine . SpyObj < IntegrationsToastService > ;
37+ let storageService : jasmine . SpyObj < StorageService > ;
38+ let siWorkspaceService : jasmine . SpyObj < SiWorkspaceService > ;
39+ let router : Router ;
840
941 beforeEach ( async ( ) => {
42+ const siImportSettingServiceSpy = jasmine . createSpyObj ( 'SiImportSettingService' , [ 'getImportSettings' , 'postImportSettings' , 'getImportCodeFieldConfig' ] ) ;
43+ const siMappingsServiceSpy = jasmine . createSpyObj ( 'SiMappingsService' , [ 'getSageIntacctFields' , 'getFyleFields' , 'getGroupedDestinationAttributes' , 'getConfiguration' , 'refreshSageIntacctDimensions' , 'refreshFyleDimensions' ] ) ;
44+ const intacctConnectorServiceSpy = jasmine . createSpyObj ( 'IntacctConnectorService' , [ 'getLocationEntityMapping' ] ) ;
45+ const orgServiceSpy = jasmine . createSpyObj ( 'OrgService' , [ 'getCachedOrg' ] ) ;
46+ const trackingServiceSpy = jasmine . createSpyObj ( 'TrackingService' , [ 'integrationsOnboardingCompletion' , 'intacctUpdateEvent' , 'trackTimeSpent' ] ) ;
47+ const toastServiceSpy = jasmine . createSpyObj ( 'IntegrationsToastService' , [ 'displayToastMessage' ] ) ;
48+ const storageServiceSpy = jasmine . createSpyObj ( 'StorageService' , [ 'get' ] ) ;
49+ const siWorkspaceServiceSpy = jasmine . createSpyObj ( 'SiWorkspaceService' , [ 'getIntacctOnboardingState' , 'setIntacctOnboardingState' ] ) ;
50+
1051 await TestBed . configureTestingModule ( {
11- declarations : [ IntacctImportSettingsComponent ]
52+ declarations : [ IntacctImportSettingsComponent ] ,
53+ imports : [ SharedModule , IntacctSharedModule , ReactiveFormsModule , RouterModule . forRoot ( [ ] ) , HttpClientTestingModule ] ,
54+ providers : [
55+ FormBuilder ,
56+ { provide : SiImportSettingService , useValue : siImportSettingServiceSpy } ,
57+ { provide : SiMappingsService , useValue : siMappingsServiceSpy } ,
58+ { provide : IntacctConnectorService , useValue : intacctConnectorServiceSpy } ,
59+ { provide : OrgService , useValue : orgServiceSpy } ,
60+ { provide : TrackingService , useValue : trackingServiceSpy } ,
61+ { provide : IntegrationsToastService , useValue : toastServiceSpy } ,
62+ { provide : StorageService , useValue : storageServiceSpy } ,
63+ { provide : SiWorkspaceService , useValue : siWorkspaceServiceSpy } ,
64+ provideRouter ( [ ] )
65+ ]
1266 } )
13- . compileComponents ( ) ;
67+ . compileComponents ( ) ;
68+
69+ siImportSettingService = TestBed . inject ( SiImportSettingService ) as jasmine . SpyObj < SiImportSettingService > ;
70+ siMappingsService = TestBed . inject ( SiMappingsService ) as jasmine . SpyObj < SiMappingsService > ;
71+ intacctConnectorService = TestBed . inject ( IntacctConnectorService ) as jasmine . SpyObj < IntacctConnectorService > ;
72+ orgService = TestBed . inject ( OrgService ) as jasmine . SpyObj < OrgService > ;
73+ trackingService = TestBed . inject ( TrackingService ) as jasmine . SpyObj < TrackingService > ;
74+ toastService = TestBed . inject ( IntegrationsToastService ) as jasmine . SpyObj < IntegrationsToastService > ;
75+ storageService = TestBed . inject ( StorageService ) as jasmine . SpyObj < StorageService > ;
76+ siWorkspaceService = TestBed . inject ( SiWorkspaceService ) as jasmine . SpyObj < SiWorkspaceService > ;
77+ router = TestBed . inject ( Router ) ;
78+
79+ spyOn ( router , 'navigate' ) ;
80+ spyOnProperty ( router , 'url' ) . and . returnValue ( '/onboarding' ) ;
81+ siImportSettingService . getImportSettings . and . returnValue ( of ( importSettings ) ) ;
82+ siImportSettingService . getImportCodeFieldConfig . and . returnValue ( of ( intacctImportCodeConfig ) ) ;
83+ siMappingsService . getSageIntacctFields . and . returnValue ( of ( sageIntacctFields ) ) ;
84+ siMappingsService . getFyleFields . and . returnValue ( of ( fyleFields ) ) ;
85+ siMappingsService . getGroupedDestinationAttributes . and . returnValue ( of ( groupedDestinationAttributes ) ) ;
86+ siMappingsService . getConfiguration . and . returnValue ( of ( configuration ) ) ;
87+ intacctConnectorService . getLocationEntityMapping . and . returnValue ( of ( locationEntityMapping ) ) ;
88+ orgService . getCachedOrg . and . returnValue ( { created_at : new Date ( ) } as Org ) ;
89+ siWorkspaceService . getIntacctOnboardingState . and . returnValue ( IntacctOnboardingState . IMPORT_SETTINGS ) ;
90+ storageService . get . and . returnValue ( 366 ) ;
1491
1592 fixture = TestBed . createComponent ( IntacctImportSettingsComponent ) ;
1693 component = fixture . componentInstance ;
17- fixture . detectChanges ( ) ;
94+
1895 } ) ;
1996
2097 it ( 'should create' , ( ) => {
2198 expect ( component ) . toBeTruthy ( ) ;
2299 } ) ;
23- } ) ;
100+
101+ describe ( 'Form Initialization' , ( ) => {
102+ beforeEach ( ( ) => {
103+ component . ngOnInit ( ) ;
104+ fixture . detectChanges ( ) ;
105+ } ) ;
106+
107+ it ( 'should set initial loading state' , ( ) => {
108+ expect ( component . isLoading ) . toBeFalsy ( ) ;
109+ } ) ;
110+
111+ it ( 'should fetch and set all required data' , ( ) => {
112+ expect ( siMappingsService . getSageIntacctFields ) . toHaveBeenCalled ( ) ;
113+ expect ( siMappingsService . getFyleFields ) . toHaveBeenCalled ( ) ;
114+ expect ( siMappingsService . getGroupedDestinationAttributes ) . toHaveBeenCalledWith ( [ 'TAX_DETAIL' ] ) ;
115+ expect ( siImportSettingService . getImportSettings ) . toHaveBeenCalled ( ) ;
116+ expect ( siMappingsService . getConfiguration ) . toHaveBeenCalled ( ) ;
117+ expect ( intacctConnectorService . getLocationEntityMapping ) . toHaveBeenCalled ( ) ;
118+ expect ( siImportSettingService . getImportCodeFieldConfig ) . toHaveBeenCalled ( ) ;
119+ } ) ;
120+
121+ it ( 'should correctly transform and set sageIntacctFields' , ( ) => {
122+ expect ( component . sageIntacctFields ) . toEqual ( sageIntacctFieldsSortedByPriority ) ;
123+ } ) ;
124+
125+ it ( 'should set Fyle fields with custom field option' , ( ) => {
126+ expect ( component . fyleFields ) . toEqual ( fyleFields as ExpenseField [ ] ) ;
127+ } ) ;
128+
129+ it ( 'should set intacctCategoryDestination based on configuration' , ( ) => {
130+ expect ( component . intacctCategoryDestination ) . toEqual ( IntacctCategoryDestination . GL_ACCOUNT ) ;
131+
132+ const updatedConfig = { ...configuration , reimbursable_expenses_object : 'EXPENSE_REPORT' } ;
133+ siMappingsService . getConfiguration . and . returnValue ( of ( updatedConfig as IntacctConfiguration ) ) ;
134+
135+ component . ngOnInit ( ) ;
136+ fixture . detectChanges ( ) ;
137+
138+ expect ( component . intacctCategoryDestination ) . toEqual ( IntacctCategoryDestination . EXPENSE_TYPE ) ;
139+ } ) ;
140+
141+ describe ( 'Form Group Initialization' , ( ) => {
142+ it ( 'should initialize the form with correct controls' , ( ) => {
143+ expect ( component . importSettingsForm . get ( 'importVendorAsMerchant' ) ) . toBeTruthy ( ) ;
144+ expect ( component . importSettingsForm . get ( 'importCategories' ) ) . toBeTruthy ( ) ;
145+ expect ( component . importSettingsForm . get ( 'importTaxCodes' ) ) . toBeTruthy ( ) ;
146+ expect ( component . importSettingsForm . get ( 'costCodes' ) ) . toBeTruthy ( ) ;
147+ expect ( component . importSettingsForm . get ( 'dependentFieldImportToggle' ) ) . toBeTruthy ( ) ;
148+ expect ( component . importSettingsForm . get ( 'workspaceId' ) ) . toBeTruthy ( ) ;
149+ expect ( component . importSettingsForm . get ( 'costTypes' ) ) . toBeTruthy ( ) ;
150+ expect ( component . importSettingsForm . get ( 'isDependentImportEnabled' ) ) . toBeTruthy ( ) ;
151+ expect ( component . importSettingsForm . get ( 'sageIntacctTaxCodes' ) ) . toBeTruthy ( ) ;
152+ expect ( component . importSettingsForm . get ( 'expenseFields' ) ) . toBeTruthy ( ) ;
153+ expect ( component . importSettingsForm . get ( 'searchOption' ) ) . toBeTruthy ( ) ;
154+ expect ( component . importSettingsForm . get ( 'importCodeField' ) ) . toBeTruthy ( ) ;
155+ expect ( component . importSettingsForm . get ( 'importCodeFields' ) ) . toBeTruthy ( ) ;
156+ } ) ;
157+
158+ it ( 'should initialize form with correct values' , ( ) => {
159+ expect ( component . importSettingsForm . get ( 'importVendorAsMerchant' ) ?. value ) . toEqual ( importSettings . configurations . import_vendors_as_merchants || null || null ) ;
160+ expect ( component . importSettingsForm . get ( 'importCategories' ) ?. value ) . toEqual ( importSettings . configurations . import_categories || null ) ;
161+ expect ( component . importSettingsForm . get ( 'importTaxCodes' ) ?. value ) . toEqual ( importSettings . configurations . import_tax_codes || null ) ;
162+ expect ( component . importSettingsForm . get ( 'workspaceId' ) ?. value ) . toEqual ( 366 ) ;
163+ expect ( component . importSettingsForm . get ( 'isDependentImportEnabled' ) ?. value ) . toBeFalsy ( ) ;
164+ expect ( component . importSettingsForm . get ( 'searchOption' ) ?. value ) . toEqual ( '' ) ;
165+ expect ( component . importSettingsForm . get ( 'importCodeField' ) ?. value ) . toEqual ( importSettings . configurations . import_code_fields ) ;
166+ } ) ;
167+
168+ it ( 'should initialize expenseFields FormArray correctly' , ( ) => {
169+ const expenseFieldsArray = component . importSettingsForm . get ( 'expenseFields' ) as FormArray ;
170+ expect ( expenseFieldsArray . length ) . toBeGreaterThan ( 0 ) ;
171+
172+ const testForFields = ( control : AbstractControl < any , any > ) => {
173+ expect ( control . get ( 'source_field' ) ) . toBeTruthy ( ) ;
174+ expect ( control . get ( 'destination_field' ) ) . toBeTruthy ( ) ;
175+ expect ( control . get ( 'import_to_fyle' ) ) . toBeTruthy ( ) ;
176+ expect ( control . get ( 'is_custom' ) ) . toBeTruthy ( ) ;
177+ expect ( control . get ( 'source_placeholder' ) ) . toBeTruthy ( ) ;
178+ } ;
179+ expenseFieldsArray . controls . forEach ( testForFields ) ;
180+ } ) ;
181+ } ) ;
182+
183+ describe ( 'Dependent Fields Setup' , ( ) => {
184+ it ( 'should handle dependent fields when project mapping exists' , fakeAsync ( ( ) => {
185+ siImportSettingService . getImportSettings . and . returnValue ( of ( importSettingsWithProject ) ) ;
186+
187+ fixture . detectChanges ( ) ;
188+ tick ( ) ;
189+
190+ expect ( component . costCodeFieldOption . length ) . toBe ( 1 ) ;
191+ expect ( component . costTypeFieldOption . length ) . toBe ( 1 ) ;
192+ } ) ) ;
193+
194+ it ( 'should handle dependent field settings' , ( ) => {
195+ siImportSettingService . getImportSettings . and . returnValue ( of ( settingsWithDependentFields ) ) ;
196+
197+ component . ngOnInit ( ) ;
198+ fixture . detectChanges ( ) ;
199+
200+ expect ( component . importSettingsForm . get ( 'isDependentImportEnabled' ) ?. value ) . toBeTrue ( ) ;
201+ expect ( component . importSettingsForm . get ( 'costCodes' ) ?. value ) . toEqual ( costCodeFieldValue ) ;
202+ expect ( component . importSettingsForm . get ( 'costTypes' ) ?. value ) . toEqual ( costTypeFieldValue ) ;
203+ } ) ;
204+ } ) ;
205+ } ) ;
206+ } ) ;
0 commit comments