@@ -14,9 +14,11 @@ import { EmployeeFieldMapping, ExpenseGroupingFieldOption, ExportDateType, FyleF
14
14
import { ExportSettingOptionSearch , ExportSettingModel } from 'src/app/core/models/common/export-settings.model' ;
15
15
import { IntacctDestinationAttribute , PaginatedintacctDestinationAttribute } from 'src/app/core/models/intacct/db/destination-attribute.model' ;
16
16
import { SharedModule } from 'src/app/shared/shared.module' ;
17
- import { brandingConfig } from 'src/app/branding/branding-config' ;
17
+ import { brandingConfig , brandingContent } from 'src/app/branding/branding-config' ;
18
18
import { BrandingConfiguration } from 'src/app/core/models/branding/branding-configuration.model' ;
19
- import { ExportSettingModel as IntacctExportSettingModel } from 'src/app/core/models/intacct/intacct-configuration/export-settings.model' ;
19
+ import { ExportSettingGet , ExportSettingModel as IntacctExportSettingModel } from 'src/app/core/models/intacct/intacct-configuration/export-settings.model' ;
20
+ import { TitleCasePipe } from '@angular/common' ;
21
+
20
22
21
23
describe ( 'IntacctExportSettingsComponent' , ( ) => {
22
24
let component : IntacctExportSettingsComponent ;
@@ -171,16 +173,329 @@ describe('IntacctExportSettingsComponent', () => {
171
173
} ) ;
172
174
} ) ;
173
175
174
- it ( 'should handle refresh dimensions' , ( ) => {
175
- component . refreshDimensions ( true ) ;
176
- expect ( mappingService . refreshSageIntacctDimensions ) . toHaveBeenCalled ( ) ;
177
- expect ( mappingService . refreshFyleDimensions ) . toHaveBeenCalled ( ) ;
178
- expect ( toastService . displayToastMessage ) . toHaveBeenCalledWith ( ToastSeverity . SUCCESS , 'Syncing data dimensions from Sage Intacct' ) ;
176
+ describe ( 'Utility Functions' , ( ) => {
177
+ it ( 'should handle refresh dimensions' , ( ) => {
178
+ component . refreshDimensions ( true ) ;
179
+ expect ( mappingService . refreshSageIntacctDimensions ) . toHaveBeenCalled ( ) ;
180
+ expect ( mappingService . refreshFyleDimensions ) . toHaveBeenCalled ( ) ;
181
+ expect ( toastService . displayToastMessage ) . toHaveBeenCalledWith ( ToastSeverity . SUCCESS , 'Syncing data dimensions from Sage Intacct' ) ;
182
+ } ) ;
183
+
184
+ it ( 'should navigate to previous step' , ( ) => {
185
+ component . navigateToPreviousStep ( ) ;
186
+ expect ( router . navigate ) . toHaveBeenCalledWith ( [ '/integrations/intacct/onboarding/connector' ] ) ;
187
+ } ) ;
188
+
189
+ it ( 'should return the correct employee field mapping' , ( ) => {
190
+ fixture . detectChanges ( ) ;
191
+
192
+ expect (
193
+ component . getEmployeeFieldMapping ( FyleField . VENDOR , IntacctReimbursableExpensesObject . BILL )
194
+ ) . toBe ( 'Vendor' ) ;
195
+
196
+ expect ( component . getEmployeeFieldMapping ( null , IntacctReimbursableExpensesObject . JOURNAL_ENTRY ) )
197
+ . toBe ( new TitleCasePipe ( ) . transform ( component . exportSettingsForm . get ( 'employeeFieldMapping' ) ?. value ) ) ;
198
+
199
+ expect ( component . getEmployeeFieldMapping ( null , IntacctReimbursableExpensesObject . BILL ) )
200
+ . toBe ( 'Vendor' ) ;
201
+ } ) ;
202
+
203
+ it ( 'should get the correct export type' , ( ) => {
204
+ expect ( component . getExportType ( IntacctReimbursableExpensesObject . JOURNAL_ENTRY ) ) . toBe ( 'Journal_entry' ) ;
205
+ expect ( component . getExportType ( IntacctReimbursableExpensesObject . BILL ) ) . toBe ( 'Bill' ) ;
206
+ expect ( component . getExportType ( IntacctReimbursableExpensesObject . EXPENSE_REPORT ) ) . toBe ( 'Expense_report' ) ;
207
+ expect ( component . getExportType ( null ) ) . toBe ( 'export' ) ;
208
+ } ) ;
209
+ } ) ;
210
+
211
+ describe ( 'Watchers' , ( ) => {
212
+ beforeEach ( ( ) => {
213
+ fixture . detectChanges ( ) ;
214
+ } ) ;
215
+
216
+ describe ( 'Reimbursable Expense Toggle Watcher' , ( ) => {
217
+ it ( 'should enable fields on enabling reimbursable expenses' , fakeAsync ( ( ) => {
218
+ component . exportSettingsForm . get ( 'reimbursableExpense' ) ?. setValue ( true ) ;
219
+ tick ( ) ;
220
+
221
+ expect ( component . exportSettingsForm . get ( 'reimbursableExportType' ) ?. hasValidator ( Validators . required ) ) . toBeTrue ( ) ;
222
+ expect ( component . exportSettingsForm . get ( 'reimbursableExportGroup' ) ?. hasValidator ( Validators . required ) ) . toBeTrue ( ) ;
223
+ expect ( component . exportSettingsForm . get ( 'reimbursableExportDate' ) ?. hasValidator ( Validators . required ) ) . toBeTrue ( ) ;
224
+ } ) ) ;
225
+
226
+ it ( 'should disable fields on disabling reimbursable expenses' , fakeAsync ( ( ) => {
227
+ component . exportSettingsForm . get ( 'reimbursableExpense' ) ?. setValue ( false ) ;
228
+ tick ( ) ;
229
+
230
+ expect ( component . exportSettingsForm . get ( 'reimbursableExportType' ) ?. hasValidator ( Validators . required ) ) . toBeFalse ( ) ;
231
+ expect ( component . exportSettingsForm . get ( 'reimbursableExportGroup' ) ?. hasValidator ( Validators . required ) ) . toBeFalse ( ) ;
232
+ expect ( component . exportSettingsForm . get ( 'reimbursableExportDate' ) ?. hasValidator ( Validators . required ) ) . toBeFalse ( ) ;
233
+ expect ( component . exportSettingsForm . get ( 'reimbursableExportType' ) ?. value ) . toBeNull ( ) ;
234
+ } ) ) ;
235
+ } ) ;
236
+
237
+ describe ( 'Reimbursable Export Type Watchers' , ( ) => {
238
+
239
+ it ( 'should handle reimbursableExportType being changed to Journal Entry' , fakeAsync ( ( ) => {
240
+ component . exportSettingsForm . get ( 'reimbursableExportType' ) ?. setValue ( IntacctReimbursableExpensesObject . JOURNAL_ENTRY ) ;
241
+ tick ( ) ;
242
+
243
+ expect ( component . exportSettingsForm . get ( 'glAccount' ) ?. hasValidator ( Validators . required ) ) . toBeTrue ( ) ;
244
+ expect ( component . exportSettingsForm . get ( 'employeeFieldMapping' ) ?. enabled ) . toBeTrue ( ) ;
245
+ } ) ) ;
246
+
247
+ it ( 'should handle reimbursableExportType being changed to Expense Report' , fakeAsync ( ( ) => {
248
+ component . exportSettingsForm . get ( 'reimbursableExportType' ) ?. setValue ( IntacctReimbursableExpensesObject . EXPENSE_REPORT ) ;
249
+ tick ( ) ;
250
+
251
+ expect ( component . exportSettingsForm . get ( 'employeeFieldMapping' ) ?. value ) . toBe ( FyleField . EMPLOYEE ) ;
252
+ expect ( component . exportSettingsForm . get ( 'employeeFieldMapping' ) ?. disabled ) . toBeTrue ( ) ;
253
+ } ) ) ;
254
+
255
+ it ( 'should handle reimbursableExportType being changed to Bill' , fakeAsync ( ( ) => {
256
+ component . exportSettingsForm . get ( 'reimbursableExportType' ) ?. setValue ( IntacctReimbursableExpensesObject . BILL ) ;
257
+ tick ( ) ;
258
+
259
+ expect ( component . exportSettingsForm . get ( 'employeeFieldMapping' ) ?. value ) . toBe ( FyleField . VENDOR ) ;
260
+ expect ( component . exportSettingsForm . get ( 'employeeFieldMapping' ) ?. disabled ) . toBeTrue ( ) ;
261
+ } ) ) ;
262
+ } ) ;
263
+
264
+ describe ( 'Credit Card Expense Toggle Watcher' , ( ) => {
265
+ it ( 'should enable fields on enabling CCC expenses' , fakeAsync ( ( ) => {
266
+ component . exportSettingsForm . get ( 'creditCardExpense' ) ?. setValue ( true ) ;
267
+ tick ( ) ;
268
+
269
+ expect ( component . exportSettingsForm . get ( 'cccExportType' ) ?. hasValidator ( Validators . required ) ) . toBeTrue ( ) ;
270
+ expect ( component . exportSettingsForm . get ( 'cccExportGroup' ) ?. hasValidator ( Validators . required ) ) . toBeTrue ( ) ;
271
+ expect ( component . exportSettingsForm . get ( 'cccExportDate' ) ?. hasValidator ( Validators . required ) ) . toBeTrue ( ) ;
272
+ } ) ) ;
273
+
274
+ it ( 'should disable fields on disabling CCC expenses' , fakeAsync ( ( ) => {
275
+ component . exportSettingsForm . get ( 'creditCardExpense' ) ?. setValue ( false ) ;
276
+ tick ( ) ;
277
+
278
+ expect ( component . exportSettingsForm . get ( 'cccExportType' ) ?. hasValidator ( Validators . required ) ) . toBeFalse ( ) ;
279
+ expect ( component . exportSettingsForm . get ( 'cccExportGroup' ) ?. hasValidator ( Validators . required ) ) . toBeFalse ( ) ;
280
+ expect ( component . exportSettingsForm . get ( 'cccExportDate' ) ?. hasValidator ( Validators . required ) ) . toBeFalse ( ) ;
281
+ expect ( component . exportSettingsForm . get ( 'cccExportType' ) ?. value ) . toBeNull ( ) ;
282
+ } ) ) ;
283
+ } ) ;
284
+
285
+ describe ( 'CCC Export Type Watchers' , ( ) => {
286
+ it ( 'should handle cccExportType being changed to Charge Card Transaction' , fakeAsync ( ( ) => {
287
+ component . exportSettingsForm . get ( 'cccExportType' ) ?. setValue ( IntacctCorporateCreditCardExpensesObject . CHARGE_CARD_TRANSACTION ) ;
288
+ tick ( ) ;
289
+
290
+ expect ( component . exportSettingsForm . get ( 'chargeCard' ) ?. hasValidator ( Validators . required ) ) . toBeTrue ( ) ;
291
+ expect ( component . exportSettingsForm . get ( 'cccExportGroup' ) ?. disabled ) . toBeTrue ( ) ;
292
+ expect ( component . exportSettingsForm . get ( 'cccExportGroup' ) ?. value ) . toBe ( ExpenseGroupingFieldOption . EXPENSE_ID ) ;
293
+ } ) ) ;
294
+
295
+ it ( 'should handle cccExportType being changed to Bill' , fakeAsync ( ( ) => {
296
+ component . exportSettingsForm . get ( 'cccExportType' ) ?. setValue ( IntacctCorporateCreditCardExpensesObject . BILL ) ;
297
+ tick ( ) ;
298
+
299
+ expect ( component . exportSettingsForm . get ( 'creditCardVendor' ) ?. hasValidator ( Validators . required ) ) . toBeTrue ( ) ;
300
+ } ) ) ;
301
+
302
+ it ( 'should handle cccExportType being changed to Expense Report' , fakeAsync ( ( ) => {
303
+ component . exportSettingsForm . get ( 'cccExportType' ) ?. setValue ( IntacctCorporateCreditCardExpensesObject . EXPENSE_REPORT ) ;
304
+ tick ( ) ;
305
+
306
+ expect ( component . exportSettingsForm . get ( 'employeeFieldMapping' ) ?. value ) . toBe ( EmployeeFieldMapping . EMPLOYEE ) ;
307
+ expect ( component . exportSettingsForm . get ( 'cccExpensePaymentType' ) ?. hasValidator ( Validators . required ) ) . toBeTrue ( ) ;
308
+ } ) ) ;
309
+
310
+ it ( 'should handle cccExportType being changed to Journal Entry' , fakeAsync ( ( ) => {
311
+ component . exportSettingsForm . get ( 'cccExportType' ) ?. setValue ( IntacctCorporateCreditCardExpensesObject . JOURNAL_ENTRY ) ;
312
+ tick ( ) ;
313
+
314
+ expect ( component . exportSettingsForm . get ( 'employeeFieldMapping' ) ?. enabled ) . toBeTrue ( ) ;
315
+ expect ( component . exportSettingsForm . get ( 'creditCard' ) ?. hasValidator ( Validators . required ) ) . toBeTrue ( ) ;
316
+ } ) ) ;
317
+ } ) ;
318
+
319
+ describe ( 'Custom Watchers' , ( ) => {
320
+ beforeEach ( ( ) => {
321
+ brandingConfig . brandId = 'fyle' ;
322
+ } ) ;
323
+
324
+ it ( 'should update reimbursable expense grouping date options when group changes' , fakeAsync ( ( ) => {
325
+ fixture . detectChanges ( ) ;
326
+ component . exportSettingsForm . get ( 'reimbursableExportGroup' ) ?. setValue ( ExpenseGroupingFieldOption . CLAIM_NUMBER ) ;
327
+ tick ( ) ;
328
+
329
+ expect ( component . reimbursableExpenseGroupingDateOptions ) . not . toContain ( {
330
+ label : 'Spend date' ,
331
+ value : ExportDateType . SPENT_AT
332
+ } ) ;
333
+ } ) ) ;
334
+
335
+ it ( 'should update CCC expense grouping date options when group changes' , fakeAsync ( ( ) => {
336
+ spyOn < IntacctExportSettingsComponent , any > ( component , 'setCCExpenseDateOptions' ) . and . callThrough ( ) ;
337
+ spyOn ( IntacctExportSettingModel , 'getExpenseGroupingDateOptions' ) . and . callThrough ( ) ;
338
+ spyOn ( ExportSettingModel , 'constructGroupingDateOptions' ) . and . callThrough ( ) ;
339
+
340
+ component . exportSettingsForm . get ( 'cccExportType' ) ?. setValue ( IntacctCorporateCreditCardExpensesObject . CHARGE_CARD_TRANSACTION ) ;
341
+ component . exportSettingsForm . get ( 'cccExportGroup' ) ?. setValue ( ExpenseGroupingFieldOption . CLAIM_NUMBER ) ;
342
+
343
+ tick ( ) ;
344
+
345
+ expect ( IntacctExportSettingModel . getExpenseGroupingDateOptions ) . toHaveBeenCalledWith ( ) ;
346
+ expect ( ExportSettingModel . constructGroupingDateOptions ) . toHaveBeenCalledWith (
347
+ ExpenseGroupingFieldOption . CLAIM_NUMBER ,
348
+ IntacctExportSettingModel . getExpenseGroupingDateOptions ( )
349
+ ) ;
350
+ expect ( component [ 'setCCExpenseDateOptions' ] ) . toHaveBeenCalled ( ) ;
351
+ } ) ) ;
352
+ } ) ;
353
+
354
+ describe ( 'Export Selection Validator' , ( ) => {
355
+ beforeEach ( ( ) => {
356
+ fixture . detectChanges ( ) ;
357
+ } ) ;
358
+
359
+ it ( 'should invalidate form when neither reimbursable nor credit card expense is selected' , ( ) => {
360
+ component . exportSettingsForm . get ( 'reimbursableExpense' ) ?. setValue ( false ) ;
361
+ component . exportSettingsForm . get ( 'creditCardExpense' ) ?. setValue ( false ) ;
362
+
363
+ expect ( component . exportSettingsForm . valid ) . toBeFalse ( ) ;
364
+ } ) ;
365
+
366
+ it ( 'should validate the form when at least one export type is selected' , ( ) => {
367
+ component . exportSettingsForm . get ( 'reimbursableExpense' ) ?. setValue ( true ) ;
368
+ component . exportSettingsForm . get ( 'creditCardExpense' ) ?. setValue ( false ) ;
369
+
370
+ expect ( component . exportSettingsForm . valid ) . toBeTrue ( ) ;
371
+ } ) ;
372
+ } ) ;
373
+
374
+ describe ( 'Destination Options Handling' , ( ) => {
375
+ beforeEach ( ( ) => {
376
+ fixture . detectChanges ( ) ;
377
+ } ) ;
378
+
379
+ it ( 'should handle option search for reimbursable expense payment type' , fakeAsync ( ( ) => {
380
+ const searchEvent = {
381
+ searchTerm : 'test' ,
382
+ destinationOptionKey : 'EXPENSE_PAYMENT_TYPE'
383
+ } as ExportSettingOptionSearch ;
384
+
385
+ mappingService . getPaginatedDestinationAttributes . and . returnValue (
386
+ of ( mockPaginatedDestinationAttributes . EXPENSE_PAYMENT_TYPE as unknown as PaginatedintacctDestinationAttribute )
387
+ ) ;
388
+
389
+ component . searchOptionsDropdown ( searchEvent ) ;
390
+ tick ( 1000 ) ;
391
+
392
+ expect ( mappingService . getPaginatedDestinationAttributes ) . toHaveBeenCalledWith ( 'EXPENSE_PAYMENT_TYPE' , 'test' ) ;
393
+
394
+ const isReimbursable = ( option : IntacctDestinationAttribute ) => (
395
+ option . detail ? option . detail . is_reimbursable : true
396
+ ) ;
397
+
398
+ expect ( component . destinationOptions . EXPENSE_PAYMENT_TYPE . every ( isReimbursable ) ) . toBeTrue ( ) ;
399
+ expect ( component . isOptionSearchInProgress ) . toBeFalse ( ) ;
400
+ } ) ) ;
401
+
402
+ it ( 'should handle option search for CCC expense payment type' , fakeAsync ( ( ) => {
403
+ const searchEvent = {
404
+ searchTerm : 'test' ,
405
+ destinationOptionKey : 'CCC_EXPENSE_PAYMENT_TYPE'
406
+ } ;
407
+
408
+ mappingService . getPaginatedDestinationAttributes . and . returnValue (
409
+ of ( mockPaginatedDestinationAttributes . EXPENSE_PAYMENT_TYPE as unknown as PaginatedintacctDestinationAttribute )
410
+ ) ;
411
+
412
+ component . searchOptionsDropdown ( searchEvent as ExportSettingOptionSearch ) ;
413
+ tick ( 1000 ) ;
414
+
415
+ expect ( mappingService . getPaginatedDestinationAttributes ) . toHaveBeenCalledWith ( 'EXPENSE_PAYMENT_TYPE' , 'test' ) ;
416
+ expect ( component . destinationOptions . CCC_EXPENSE_PAYMENT_TYPE . every ( option => (
417
+ option . detail ? ! option . detail . is_reimbursable : true
418
+ ) ) ) . toBeTrue ( ) ;
419
+ expect ( component . isOptionSearchInProgress ) . toBeFalse ( ) ;
420
+ } ) ) ;
421
+ } ) ;
422
+
423
+
424
+ } ) ;
425
+
426
+ describe ( 'C1 Specific Behavior' , ( ) => {
427
+ it ( 'should handle setup with c1 branding' , ( ) => {
428
+ brandingConfig . brandId = 'co' ;
429
+
430
+ fixture = TestBed . createComponent ( IntacctExportSettingsComponent ) ;
431
+ component = fixture . componentInstance ;
432
+ fixture . detectChanges ( ) ;
433
+
434
+ expect ( component . exportSettingsForm . get ( 'creditCardExpense' ) ?. value ) . toBeTrue ( ) ;
435
+ expect ( component . exportSettingsForm . get ( 'employeeFieldMapping' ) ?. value ) . toBe ( FyleField . VENDOR ) ;
436
+ expect ( component . isMultiLineOption ) . toBeFalse ( ) ;
437
+ } ) ;
438
+
439
+ afterAll ( ( ) => {
440
+ brandingConfig . brandId = 'fyle' ;
441
+ } ) ;
179
442
} ) ;
180
443
181
- it ( 'should navigate to previous step' , ( ) => {
182
- component . navigateToPreviousStep ( ) ;
183
- expect ( router . navigate ) . toHaveBeenCalledWith ( [ '/integrations/intacct/onboarding/connector' ] ) ;
444
+ describe ( 'Edge Cases' , ( ) => {
445
+ it ( 'should set the correct CCC expense grouping date options when CCC expense object is unset' , ( ) => {
446
+ component . exportSettings = {
447
+ configurations : {
448
+ corporate_credit_card_expenses_object : null
449
+ }
450
+ } as ExportSettingGet ;
451
+ spyOn < any > ( component , 'setCCExpenseDateOptions' ) ;
452
+
453
+ component [ 'setupCCCExpenseGroupingDateOptions' ] ( ) ;
454
+ expect ( component [ 'setCCExpenseDateOptions' ] ) . toHaveBeenCalledOnceWith ( IntacctCorporateCreditCardExpensesObject . CHARGE_CARD_TRANSACTION ) ;
455
+ } ) ;
456
+
457
+ it ( 'should default CCC expense grouping date options to reimbursable grouping date options for non-charge card transactions' , ( ) => {
458
+ fixture . detectChanges ( ) ;
459
+
460
+ component [ 'setCCExpenseDateOptions' ] ( IntacctCorporateCreditCardExpensesObject . BILL ) ;
461
+ expect ( component . cccExpenseGroupingDateOptions ) . toEqual ( component . reimbursableExpenseGroupingDateOptions ) ;
462
+ } ) ;
463
+
464
+ it ( 'should set the correct CCC expense grouping date options when grouping by report' , ( ) => {
465
+ fixture . detectChanges ( ) ;
466
+
467
+ component . exportSettingsForm . get ( 'cccExportType' ) ?. setValue ( IntacctCorporateCreditCardExpensesObject . CHARGE_CARD_TRANSACTION ) ;
468
+ component [ 'updateCCCGroupingDateOptions' ] ( ExpenseGroupingFieldOption . CLAIM_NUMBER ) ;
469
+
470
+ expect ( component . cccExpenseGroupingDateOptions ) . toEqual ( [
471
+ {
472
+ label : brandingContent . common . currentDate ,
473
+ value : ExportDateType . CURRENT_DATE
474
+ } ,
475
+ {
476
+ label : 'Last Spend Date' ,
477
+ value : ExportDateType . LAST_SPENT_AT
478
+ } ,
479
+ {
480
+ label : 'Approved Date' ,
481
+ value : ExportDateType . APPROVAL_DATE
482
+ } ,
483
+ {
484
+ label : 'Card Transaction Post date' ,
485
+ value : ExportDateType . POSTED_AT
486
+ }
487
+ ] ) ;
488
+ } ) ;
489
+
490
+ it ( 'should enable the employeeFieldMapping field when at least one export type is Journal Entry' , ( ) => {
491
+ fixture . detectChanges ( ) ;
492
+ component . exportSettings . configurations . reimbursable_expenses_object = IntacctReimbursableExpensesObject . JOURNAL_ENTRY ;
493
+ component . exportSettings . configurations . corporate_credit_card_expenses_object = IntacctCorporateCreditCardExpensesObject . CHARGE_CARD_TRANSACTION ;
494
+
495
+ component [ 'exportFieldsWatcher' ] ( ) ;
496
+
497
+ expect ( component . exportSettingsForm . get ( 'employeeFieldMapping' ) ?. enabled ) . toBeTrue ( ) ;
498
+ } ) ;
184
499
} ) ;
185
500
186
501
describe ( 'Watchers' , ( ) => {
0 commit comments