@@ -22,13 +22,17 @@ import {
2222 sageIntacctFieldsSortedByPriorityForC1 ,
2323 importSettingsWithProjectMapping ,
2424 expenseFieldsExpectedForC1 ,
25- blankMapping
25+ blankMapping ,
26+ customFieldFormValue
2627} from '../../intacct.fixture' ;
2728import { IntacctConfiguration } from 'src/app/core/models/db/configuration.model' ;
2829import { ImportSettingGet , ImportSettingPost , ImportSettings } from 'src/app/core/models/intacct/intacct-configuration/import-settings.model' ;
2930import { SharedModule } from 'src/app/shared/shared.module' ;
3031import { HttpClientTestingModule } from '@angular/common/http/testing' ;
3132import { IntacctOnboardingState , IntacctUpdateEvent , Page , ProgressPhase , ToastSeverity , TrackingApp } from 'src/app/core/models/enum/enum.model' ;
33+ import { ExpenseField } from 'src/app/core/models/intacct/db/expense-field.model' ;
34+ import { MappingSourceField } from 'src/app/core/models/enum/enum.model' ;
35+ import { ConfigurationWarningOut } from 'src/app/core/models/misc/configuration-warning.model' ;
3236
3337describe ( 'IntacctC1ImportSettingsComponent' , ( ) => {
3438 let component : IntacctC1ImportSettingsComponent ;
@@ -65,8 +69,8 @@ describe('IntacctC1ImportSettingsComponent', () => {
6569 ] ) ;
6670
6771 await TestBed . configureTestingModule ( {
68- declarations : [ IntacctC1ImportSettingsComponent ] ,
69- imports : [ SharedModule , RouterModule . forRoot ( [ ] ) , HttpClientTestingModule , ReactiveFormsModule ] ,
72+ declarations : [ IntacctC1ImportSettingsComponent ] ,
73+ imports : [ SharedModule , RouterModule . forRoot ( [ ] ) , HttpClientTestingModule , ReactiveFormsModule ] ,
7074 providers : [
7175 FormBuilder ,
7276 { provide : SiMappingsService , useValue : mappingServiceSpy } ,
@@ -326,4 +330,164 @@ describe('IntacctC1ImportSettingsComponent', () => {
326330 } ) ;
327331 } ) ;
328332 } ) ;
333+
334+ describe ( 'Utility Functions' , ( ) => {
335+ beforeEach ( ( ) => {
336+ component . ngOnInit ( ) ;
337+ } ) ;
338+
339+ it ( 'expenseFieldsGetter should return FormArray' , ( ) => {
340+ expect ( component . expenseFieldsGetter ) . toBeInstanceOf ( FormArray ) ;
341+ } ) ;
342+
343+ it ( 'navigateToPreviousStep should navigate to export settings' , ( ) => {
344+ component . navigateToPreviousStep ( ) ;
345+ expect ( router . navigate ) . toHaveBeenCalledWith ( [ '/integrations/intacct/onboarding/export_settings' ] ) ;
346+ } ) ;
347+
348+ it ( 'refreshDimensions should call refresh methods and display toast' , ( ) => {
349+ mappingService . refreshSageIntacctDimensions . and . returnValue ( of ( { } ) ) ;
350+ mappingService . refreshFyleDimensions . and . returnValue ( of ( { } ) ) ;
351+
352+ component . refreshDimensions ( ) ;
353+
354+ expect ( mappingService . refreshSageIntacctDimensions ) . toHaveBeenCalled ( ) ;
355+ expect ( mappingService . refreshFyleDimensions ) . toHaveBeenCalled ( ) ;
356+ expect ( toastService . displayToastMessage ) . toHaveBeenCalledWith ( ToastSeverity . SUCCESS , 'Syncing data dimensions from Sage Intacct' ) ;
357+ } ) ;
358+
359+ it ( 'removeFilter should reset source_field and import_to_fyle' , ( ) => {
360+ const mockFormGroup = jasmine . createSpyObj ( 'FormGroup' , [ 'controls' ] ) ;
361+ mockFormGroup . controls = {
362+ source_field : jasmine . createSpyObj ( 'AbstractControl' , [ 'patchValue' ] ) ,
363+ import_to_fyle : jasmine . createSpyObj ( 'AbstractControl' , [ 'patchValue' ] )
364+ } ;
365+ component . removeFilter ( mockFormGroup ) ;
366+ expect ( mockFormGroup . controls . source_field . patchValue ) . toHaveBeenCalledWith ( '' ) ;
367+ expect ( mockFormGroup . controls . import_to_fyle . patchValue ) . toHaveBeenCalledWith ( false ) ;
368+ } ) ;
369+
370+ it ( 'hasDuplicateOption should return true for valid control' , ( ) => {
371+ const mockFormGroup = jasmine . createSpyObj ( 'FormGroup' , [ 'controls' ] ) ;
372+ mockFormGroup . controls = {
373+ testControl : { valid : true }
374+ } ;
375+ expect ( component . hasDuplicateOption ( mockFormGroup , 0 , 'testControl' ) ) . toBeTrue ( ) ;
376+ } ) ;
377+
378+ it ( 'showOrHideAddButton should return correct boolean' , ( ) => {
379+ component . sageIntacctFields = [ { attribute_type : 'TEST' } as ExpenseField ] ;
380+ ( component . importSettingsForm . get ( 'expenseFields' ) as FormArray ) . clear ( ) ;
381+
382+ expect ( component . showOrHideAddButton ( ) ) . toBeTrue ( ) ;
383+
384+ ( component . importSettingsForm . get ( 'expenseFields' ) as FormArray ) . push ( component [ 'createFormGroup' ] ( { } as any ) ) ;
385+
386+ expect ( component . showOrHideAddButton ( ) ) . toBeFalse ( ) ;
387+ } ) ;
388+
389+ it ( 'showPreviewDialog should set isDialogVisible' , ( ) => {
390+ component . showPreviewDialog ( true ) ;
391+ expect ( component . isDialogVisible ) . toBeTrue ( ) ;
392+ } ) ;
393+
394+ it ( 'showWarningForDependentFields should set showDependentFieldWarning' , ( ) => {
395+ component . showWarningForDependentFields ( ) ;
396+ expect ( component . showDependentFieldWarning ) . toBeTrue ( ) ;
397+ } ) ;
398+
399+ it ( 'acceptDependentFieldWarning should handle warning acceptance' , ( ) => {
400+ const mockExpenseField = component [ 'createFormGroup' ] ( { source_field : MappingSourceField . PROJECT } as any ) ;
401+ ( component . importSettingsForm . get ( 'expenseFields' ) as FormArray ) . push ( mockExpenseField ) ;
402+ component . acceptDependentFieldWarning ( { hasAccepted : false } as ConfigurationWarningOut ) ;
403+ expect ( component . showDependentFieldWarning ) . toBeFalse ( ) ;
404+ expect ( component . importSettingsForm . get ( 'isDependentImportEnabled' ) ?. value ) . toBeTrue ( ) ;
405+ expect ( component . importSettingsForm . get ( 'costCodes' ) ?. disabled ) . toBeTrue ( ) ;
406+ expect ( component . importSettingsForm . get ( 'costTypes' ) ?. disabled ) . toBeTrue ( ) ;
407+ } ) ;
408+
409+ it ( 'addExpenseField should add a new expense field' , ( ) => {
410+ const initialLength = ( component . importSettingsForm . get ( 'expenseFields' ) as FormArray ) . length ;
411+ component . addExpenseField ( ) ;
412+ expect ( ( component . importSettingsForm . get ( 'expenseFields' ) as FormArray ) . length ) . toBe ( initialLength + 1 ) ;
413+ } ) ;
414+
415+ it ( 'closeModel should reset customFieldForm and close dialog' , ( ) => {
416+ component . customFieldForm . patchValue ( { attribute_type : 'TEST' } ) ;
417+ component . showDialog = true ;
418+ component . closeModel ( ) ;
419+ expect ( component . customFieldForm . value ) . toEqual ( { attribute_type : null , display_name : null , source_placeholder : null } ) ;
420+ expect ( component . showDialog ) . toBeFalse ( ) ;
421+ } ) ;
422+
423+ it ( 'saveCustomField should call saveDependentCustomField when customFieldType is set' , ( ) => {
424+ spyOn ( component , 'saveDependentCustomField' ) ;
425+ component . customFieldType = 'TEST' ;
426+ component . saveCustomField ( ) ;
427+ expect ( component . saveDependentCustomField ) . toHaveBeenCalled ( ) ;
428+ } ) ;
429+
430+ it ( 'saveCustomField should call saveFyleExpenseField when customFieldType is not set' , ( ) => {
431+ spyOn ( component , 'saveFyleExpenseField' ) ;
432+ component . customFieldType = '' ;
433+ component . saveCustomField ( ) ;
434+ expect ( component . saveFyleExpenseField ) . toHaveBeenCalled ( ) ;
435+ } ) ;
436+
437+ describe ( 'saveDependentCustomField' , ( ) => {
438+ beforeEach ( ( ) => {
439+ component . customFieldForm . patchValue ( customFieldFormValue ) ;
440+ component . customFieldControl = component . importSettingsForm . get ( 'costCodes' ) as any ;
441+ } ) ;
442+
443+ it ( 'should update form for costCodes' , ( ) => {
444+ component . customFieldType = 'costCodes' ;
445+ component . saveDependentCustomField ( ) ;
446+ expect ( component . costCodeFieldOption [ component . costCodeFieldOption . length - 1 ] )
447+ . toEqual ( jasmine . objectContaining ( customFieldFormValue ) ) ;
448+ expect ( component . importSettingsForm . get ( 'costCodes' ) ?. value )
449+ . toEqual ( jasmine . objectContaining ( customFieldFormValue ) ) ;
450+ } ) ;
451+
452+ it ( 'should update form for non-costCodes' , ( ) => {
453+ component . customFieldType = 'costTypes' ;
454+ component . saveDependentCustomField ( ) ;
455+
456+ expect ( component . costCategoryOption [ component . costCodeFieldOption . length - 1 ] )
457+ . toEqual ( jasmine . objectContaining ( customFieldFormValue ) ) ;
458+ expect ( component . importSettingsForm . get ( 'costTypes' ) ?. value )
459+ . toEqual ( jasmine . objectContaining ( customFieldFormValue ) ) ;
460+ } ) ;
461+ } ) ;
462+
463+ it ( 'saveFyleExpenseField should update fyleFields and expenseFields' , ( ) => {
464+ component . customFieldForm . patchValue ( customFieldFormValue ) ;
465+
466+ const mockExpenseField = component [ 'createFormGroup' ] ( {
467+ destination_field : "CUSTOMER" ,
468+ import_to_fyle : false ,
469+ is_custom : false ,
470+ source_field : "" ,
471+ source_placeholder : null
472+ } ) ;
473+ component . customFieldControl = mockExpenseField ;
474+
475+ component . saveFyleExpenseField ( ) ;
476+
477+ const customerExpenseField = ( component . importSettingsForm . get ( 'expenseFields' ) as FormArray )
478+ . controls . filter ( field => (
479+ field . get ( 'destination_field' ) ?. value ===
480+ component . customFieldControl . get ( 'destination_field' ) ?. value
481+ ) ) [ 0 ] ;
482+
483+ expect ( customerExpenseField . value ) . toEqual ( jasmine . objectContaining ( {
484+ destination_field : "CUSTOMER" ,
485+ source_field : "TEST" ,
486+ source_placeholder : "TEST_PLACEHOLDER"
487+ } ) ) ;
488+ expect ( component . fyleFields [ component . fyleFields . length - 2 ] )
489+ . toEqual ( jasmine . objectContaining ( customFieldFormValue ) ) ;
490+ expect ( component . fyleFields [ component . fyleFields . length - 1 ] ) . toEqual ( component . customFieldOption [ 0 ] ) ;
491+ } ) ;
492+ } ) ;
329493} ) ;
0 commit comments