Skip to content

Commit 9aa2b08

Browse files
test: unit test the intacct mapping page (#983)
* test: unit test intacct mapping component * test: unit test intacct mapping base component
1 parent a057dec commit 9aa2b08

File tree

3 files changed

+491
-17
lines changed

3 files changed

+491
-17
lines changed
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,134 @@
1-
import { ComponentFixture, TestBed } from '@angular/core/testing';
2-
1+
/* eslint-disable dot-notation */
2+
import { ComponentFixture, fakeAsync, TestBed, tick } from '@angular/core/testing';
3+
import { ActivatedRoute } from '@angular/router';
4+
import { of, throwError } from 'rxjs';
35
import { IntacctBaseMappingComponent } from './intacct-base-mapping.component';
6+
import { MappingService } from 'src/app/core/services/common/mapping.service';
7+
import { WorkspaceService } from 'src/app/core/services/common/workspace.service';
8+
import { IntegrationsToastService } from 'src/app/core/services/common/integrations-toast.service';
9+
import { FyleField, IntacctCategoryDestination, IntacctCorporateCreditCardExpensesObject, IntacctReimbursableExpensesObject, ToastSeverity } from 'src/app/core/models/enum/enum.model';
10+
import { mockConfigurationResponse, mockMappingSettingsResponse, mockDestinationAttributesResponse } from '../../../intacct.fixture';
11+
import { MappingSettingResponse } from 'src/app/core/models/intacct/db/mapping-setting.model';
12+
import { DestinationAttribute, PaginatedDestinationAttribute } from 'src/app/core/models/db/destination-attribute.model';
13+
import { SharedModule } from 'src/app/shared/shared.module';
14+
415

5-
xdescribe('IntacctBaseMappingComponent', () => {
16+
describe('IntacctBaseMappingComponent', () => {
617
let component: IntacctBaseMappingComponent;
718
let fixture: ComponentFixture<IntacctBaseMappingComponent>;
19+
let routeSpy: jasmine.SpyObj<ActivatedRoute>;
20+
let mappingServiceSpy: jasmine.SpyObj<MappingService>;
21+
let workspaceServiceSpy: jasmine.SpyObj<WorkspaceService>;
22+
let toastServiceSpy: jasmine.SpyObj<IntegrationsToastService>;
823

924
beforeEach(async () => {
25+
routeSpy = jasmine.createSpyObj('ActivatedRoute', [], {
26+
params: of({ source_field: 'employee' }),
27+
snapshot: { params: { source_field: 'employee' } }
28+
});
29+
mappingServiceSpy = jasmine.createSpyObj('MappingService', ['getMappingSettings', 'getPaginatedDestinationAttributes', 'triggerAutoMapEmployees']);
30+
workspaceServiceSpy = jasmine.createSpyObj('WorkspaceService', ['getConfiguration']);
31+
toastServiceSpy = jasmine.createSpyObj('IntegrationsToastService', ['displayToastMessage']);
32+
1033
await TestBed.configureTestingModule({
11-
declarations: [ IntacctBaseMappingComponent ]
12-
})
13-
.compileComponents();
34+
declarations: [IntacctBaseMappingComponent],
35+
providers: [
36+
{ provide: ActivatedRoute, useValue: routeSpy },
37+
{ provide: MappingService, useValue: mappingServiceSpy },
38+
{ provide: WorkspaceService, useValue: workspaceServiceSpy },
39+
{ provide: IntegrationsToastService, useValue: toastServiceSpy }
40+
]
41+
}).compileComponents();
1442

1543
fixture = TestBed.createComponent(IntacctBaseMappingComponent);
1644
component = fixture.componentInstance;
17-
fixture.detectChanges();
1845
});
1946

2047
it('should create', () => {
2148
expect(component).toBeTruthy();
2249
});
23-
});
50+
51+
it('should initialize correctly', fakeAsync(() => {
52+
workspaceServiceSpy.getConfiguration.and.returnValue(of(mockConfigurationResponse));
53+
mappingServiceSpy.getMappingSettings.and.returnValue(of(mockMappingSettingsResponse as MappingSettingResponse));
54+
mappingServiceSpy.getPaginatedDestinationAttributes.and.returnValue(of(mockDestinationAttributesResponse as PaginatedDestinationAttribute));
55+
56+
fixture.detectChanges();
57+
tick();
58+
59+
expect(component.isLoading).toBeFalse();
60+
expect(component.sourceField).toBe(FyleField.EMPLOYEE);
61+
expect(component.destinationField).toBe('EMPLOYEE');
62+
expect(component.destinationOptions).toEqual(mockDestinationAttributesResponse.results as DestinationAttribute[]);
63+
expect(component.showAutoMapEmployee).toBeTrue();
64+
}));
65+
66+
it('should handle category mapping', fakeAsync(() => {
67+
routeSpy.params = of({ source_field: 'category' });
68+
routeSpy.snapshot.params.source_field = 'category';
69+
70+
workspaceServiceSpy.getConfiguration.and.returnValue(of(mockConfigurationResponse));
71+
mappingServiceSpy.getMappingSettings.and.returnValue(of(mockMappingSettingsResponse as MappingSettingResponse));
72+
mappingServiceSpy.getPaginatedDestinationAttributes.and.returnValue(of(mockDestinationAttributesResponse as PaginatedDestinationAttribute));
73+
74+
fixture.detectChanges();
75+
tick();
76+
77+
expect(component.sourceField).toBe('CATEGORY');
78+
expect(component.destinationField).toBe(IntacctCategoryDestination.ACCOUNT);
79+
}));
80+
81+
it('should trigger auto map employees', () => {
82+
mappingServiceSpy.triggerAutoMapEmployees.and.returnValue(of(null));
83+
component.triggerAutoMapEmployees();
84+
85+
expect(component.isLoading).toBeFalse();
86+
expect(toastServiceSpy.displayToastMessage).toHaveBeenCalledWith(ToastSeverity.INFO, 'Auto mapping of employees may take few minutes');
87+
});
88+
89+
it('should handle error when triggering auto map employees', () => {
90+
mappingServiceSpy.triggerAutoMapEmployees.and.returnValue(throwError(() => new Error('Error')));
91+
component.triggerAutoMapEmployees();
92+
93+
expect(component.isLoading).toBeFalse();
94+
expect(toastServiceSpy.displayToastMessage).toHaveBeenCalledWith(ToastSeverity.ERROR, 'Something went wrong, please try again');
95+
});
96+
97+
describe('getDestinationField', () => {
98+
it('should return employee field mapping when source field is EMPLOYEE', () => {
99+
component.sourceField = FyleField.EMPLOYEE;
100+
const intacctConfiguration = { employee_field_mapping: 'EMPLOYEE' } as any;
101+
const mappingSettings = [] as any;
102+
103+
const result = component['getDestinationField'](intacctConfiguration, mappingSettings);
104+
expect(result).toBe('EMPLOYEE');
105+
});
106+
107+
it('should return EXPENSE_TYPE when source field is CATEGORY and reimbursable_expenses_object is EXPENSE_REPORT', () => {
108+
component.sourceField = FyleField.CATEGORY;
109+
const intacctConfiguration = { reimbursable_expenses_object: IntacctReimbursableExpensesObject.EXPENSE_REPORT } as any;
110+
const mappingSettings = [] as any;
111+
112+
const result = component['getDestinationField'](intacctConfiguration, mappingSettings);
113+
expect(result).toBe(IntacctCategoryDestination.EXPENSE_TYPE);
114+
});
115+
116+
it('should return EXPENSE_TYPE when source field is CATEGORY and corporate_credit_card_expenses_object is EXPENSE_REPORT', () => {
117+
component.sourceField = FyleField.CATEGORY;
118+
const intacctConfiguration = { corporate_credit_card_expenses_object: IntacctCorporateCreditCardExpensesObject.EXPENSE_REPORT } as any;
119+
const mappingSettings = [] as any;
120+
121+
const result = component['getDestinationField'](intacctConfiguration, mappingSettings);
122+
expect(result).toBe(IntacctCategoryDestination.EXPENSE_TYPE);
123+
});
124+
125+
it('should return ACCOUNT when source field is CATEGORY and neither expenses_object is EXPENSE_REPORT', () => {
126+
component.sourceField = FyleField.CATEGORY;
127+
const intacctConfiguration = { reimbursable_expenses_object: 'OTHER', corporate_credit_card_expenses_object: 'OTHER' } as any;
128+
const mappingSettings = [] as any;
129+
130+
const result = component['getDestinationField'](intacctConfiguration, mappingSettings);
131+
expect(result).toBe(IntacctCategoryDestination.ACCOUNT);
132+
});
133+
});
134+
});
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,77 @@
11
import { ComponentFixture, TestBed } from '@angular/core/testing';
2-
2+
import { provideRouter, Router, RouterModule } from '@angular/router';
3+
import { of } from 'rxjs';
34
import { IntacctMappingComponent } from './intacct-mapping.component';
5+
import { SiMappingsService } from 'src/app/core/services/si/si-core/si-mappings.service';
6+
import { brandingConfig, brandingFeatureConfig } from 'src/app/branding/branding-config';
7+
import { mockMappingSettingsResponse, mockMappingSettingsWithCustomFieldResponse } from '../../intacct.fixture';
8+
import { MappingSettingResponse } from 'src/app/core/models/intacct/db/mapping-setting.model';
9+
import { SharedModule } from 'src/app/shared/shared.module';
410

5-
xdescribe('IntacctMappingComponent', () => {
11+
describe('IntacctMappingComponent', () => {
612
let component: IntacctMappingComponent;
13+
let router: Router;
714
let fixture: ComponentFixture<IntacctMappingComponent>;
15+
let mappingServiceSpy: jasmine.SpyObj<SiMappingsService>;
816

917
beforeEach(async () => {
18+
mappingServiceSpy = jasmine.createSpyObj('SiMappingsService', ['getMappingSettings']);
19+
1020
await TestBed.configureTestingModule({
11-
declarations: [ IntacctMappingComponent ]
12-
})
13-
.compileComponents();
21+
imports: [SharedModule, RouterModule.forRoot([])],
22+
declarations: [ IntacctMappingComponent ],
23+
providers: [
24+
provideRouter([]),
25+
{ provide: SiMappingsService, useValue: mappingServiceSpy }
26+
]
27+
}).compileComponents();
28+
29+
mappingServiceSpy.getMappingSettings.and.returnValue(of(mockMappingSettingsResponse as MappingSettingResponse));
30+
brandingConfig.brandId = 'fyle';
31+
brandingFeatureConfig.featureFlags.mapEmployees = true;
32+
33+
router = TestBed.inject(Router);
34+
spyOn(router, 'navigateByUrl');
1435

1536
fixture = TestBed.createComponent(IntacctMappingComponent);
1637
component = fixture.componentInstance;
17-
fixture.detectChanges();
1838
});
1939

2040
it('should create', () => {
2141
expect(component).toBeTruthy();
2242
});
23-
});
43+
44+
it('should initialize correctly', () => {
45+
fixture.detectChanges();
46+
47+
expect(component.isLoading).toBeFalse();
48+
expect(component.mappingPages.length).toBe(3);
49+
expect(component.activeModule).toEqual(component.mappingPages[0]);
50+
expect(router.navigateByUrl).toHaveBeenCalledWith('/integrations/intacct/main/mapping/employee');
51+
});
52+
53+
it('should handle custom mapping fields', () => {
54+
mappingServiceSpy.getMappingSettings.and.returnValue(of(mockMappingSettingsWithCustomFieldResponse as MappingSettingResponse));
55+
fixture.detectChanges();
56+
57+
expect(component.mappingPages.length).toBe(4);
58+
expect(component.mappingPages[3].label).toBe('Sample Custom Field');
59+
expect(component.mappingPages[3].routerLink).toBe('/integrations/intacct/main/mapping/sample_custom_field');
60+
});
61+
62+
it('should not include employee mapping when the feature is disabled', () => {
63+
brandingFeatureConfig.featureFlags.mapEmployees = false;
64+
fixture.detectChanges();
65+
66+
expect(component.mappingPages.length).toBe(2);
67+
expect(component.mappingPages[0].label).not.toBe('Employee');
68+
});
69+
70+
it('should handle different branding configurations', () => {
71+
mappingServiceSpy.getMappingSettings.and.returnValue(of(mockMappingSettingsWithCustomFieldResponse as MappingSettingResponse));
72+
brandingConfig.brandId = 'co';
73+
fixture.detectChanges();
74+
75+
expect(component.mappingPages[3].label).toBe('Sample custom field');
76+
});
77+
});

0 commit comments

Comments
 (0)