Skip to content

Commit 79f863c

Browse files
test: intacct export settings init, save, and misc functions (#1001)
* test: intacct export settings initialization * test: intacct export settings save functionality + misc tests
1 parent 79bede5 commit 79f863c

File tree

3 files changed

+445
-22
lines changed

3 files changed

+445
-22
lines changed

src/app/integrations/intacct/intacct-main/intacct-dashboard/intacct-dashboard.component.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import { SiExportSettingService } from 'src/app/core/services/si/si-configuratio
1010
import { MinimalUser } from 'src/app/core/models/db/user.model';
1111
import { of } from 'rxjs';
1212
import { AccountingExportSummary, AccountingExportSummaryModel } from 'src/app/core/models/db/accounting-export-summary.model';
13-
import { mockAccountingExportSummary, mockCompletedTasksWithFailures, mockConfiguration, mockErrors, mockExportableAccountingExportIds, mockExportSettingGet, mockExportSettings, mockTasksInProgress } from '../../intacct.fixture';
13+
import { mockAccountingExportSummary, mockCompletedTasksWithFailures, mockConfiguration, mockErrors, mockExportableAccountingExportIds, mockExportSettingGet, mockTasksInProgress } from '../../intacct.fixture';
1414
import { SharedModule } from 'src/app/shared/shared.module';
1515
import { Error } from 'src/app/core/models/db/error.model';
1616
import { AccountingErrorType, AppName, CCCImportState, IntacctCategoryDestination, ReimbursableImportState, TaskLogState } from 'src/app/core/models/enum/enum.model';
Lines changed: 166 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,181 @@
1-
import { ComponentFixture, TestBed } from '@angular/core/testing';
2-
1+
import { ComponentFixture, fakeAsync, TestBed, tick } from '@angular/core/testing';
2+
import { FormBuilder, ReactiveFormsModule } from '@angular/forms';
3+
import { provideRouter, Router, RouterModule } from '@angular/router';
4+
import { of, throwError } from 'rxjs';
35
import { IntacctExportSettingsComponent } from './intacct-export-settings.component';
6+
import { SiExportSettingService } from 'src/app/core/services/si/si-configuration/si-export-setting.service';
7+
import { SiMappingsService } from 'src/app/core/services/si/si-core/si-mappings.service';
8+
import { SiWorkspaceService } from 'src/app/core/services/si/si-core/si-workspace.service';
9+
import { IntegrationsToastService } from 'src/app/core/services/common/integrations-toast.service';
10+
import { TrackingService } from 'src/app/core/services/integration/tracking.service';
11+
import { mockExportSettings, mockPaginatedDestinationAttributes } from '../../intacct.fixture';
12+
import { IntacctOnboardingState, Page, ToastSeverity } from 'src/app/core/models/enum/enum.model';
13+
import { ExportSettingOptionSearch } from 'src/app/core/models/common/export-settings.model';
14+
import { IntacctDestinationAttribute, PaginatedintacctDestinationAttribute } from 'src/app/core/models/intacct/db/destination-attribute.model';
15+
import { SharedModule } from 'src/app/shared/shared.module';
416

5-
xdescribe('IntacctExportSettingsComponent', () => {
17+
describe('IntacctExportSettingsComponent', () => {
618
let component: IntacctExportSettingsComponent;
719
let fixture: ComponentFixture<IntacctExportSettingsComponent>;
20+
let exportSettingService: jasmine.SpyObj<SiExportSettingService>;
21+
let mappingService: jasmine.SpyObj<SiMappingsService>;
22+
let workspaceService: jasmine.SpyObj<SiWorkspaceService>;
23+
let toastService: jasmine.SpyObj<IntegrationsToastService>;
24+
let trackingService: jasmine.SpyObj<TrackingService>;
25+
let router: Router;
826

927
beforeEach(async () => {
28+
const exportSettingServiceSpy = jasmine.createSpyObj('SiExportSettingService', ['getExportSettings', 'postExportSettings']);
29+
const mappingServiceSpy = jasmine.createSpyObj('SiMappingsService', ['getPaginatedDestinationAttributes', 'refreshSageIntacctDimensions', 'refreshFyleDimensions']);
30+
const workspaceServiceSpy = jasmine.createSpyObj('SiWorkspaceService', ['getIntacctOnboardingState', 'setIntacctOnboardingState']);
31+
const toastServiceSpy = jasmine.createSpyObj('IntegrationsToastService', ['displayToastMessage']);
32+
const trackingServiceSpy = jasmine.createSpyObj('TrackingService', ['trackTimeSpent', 'integrationsOnboardingCompletion', 'intacctUpdateEvent']);
33+
1034
await TestBed.configureTestingModule({
11-
declarations: [ IntacctExportSettingsComponent ]
12-
})
13-
.compileComponents();
35+
declarations: [ IntacctExportSettingsComponent ],
36+
imports: [ SharedModule, ReactiveFormsModule, RouterModule.forRoot([]) ],
37+
providers: [
38+
FormBuilder,
39+
{ provide: SiExportSettingService, useValue: exportSettingServiceSpy },
40+
{ provide: SiMappingsService, useValue: mappingServiceSpy },
41+
{ provide: SiWorkspaceService, useValue: workspaceServiceSpy },
42+
{ provide: IntegrationsToastService, useValue: toastServiceSpy },
43+
{ provide: TrackingService, useValue: trackingServiceSpy },
44+
provideRouter([])
45+
]
46+
}).compileComponents();
47+
48+
exportSettingService = TestBed.inject(SiExportSettingService) as jasmine.SpyObj<SiExportSettingService>;
49+
mappingService = TestBed.inject(SiMappingsService) as jasmine.SpyObj<SiMappingsService>;
50+
workspaceService = TestBed.inject(SiWorkspaceService) as jasmine.SpyObj<SiWorkspaceService>;
51+
toastService = TestBed.inject(IntegrationsToastService) as jasmine.SpyObj<IntegrationsToastService>;
52+
trackingService = TestBed.inject(TrackingService) as jasmine.SpyObj<TrackingService>;
53+
router = TestBed.inject(Router);
54+
spyOn(router, 'navigate');
55+
56+
exportSettingService.getExportSettings.and.returnValue(of(mockExportSettings));
57+
mappingService.refreshSageIntacctDimensions.and.returnValue(of(null));
58+
mappingService.refreshFyleDimensions.and.returnValue(of(null));
59+
60+
const copy = structuredClone(mockPaginatedDestinationAttributes);
61+
mappingService.getPaginatedDestinationAttributes.and.returnValues(
62+
of(copy.ACCOUNT as unknown as PaginatedintacctDestinationAttribute),
63+
of(copy.EXPENSE_PAYMENT_TYPE as unknown as PaginatedintacctDestinationAttribute),
64+
of(copy.VENDOR as unknown as PaginatedintacctDestinationAttribute),
65+
of(copy.CHARGE_CARD_NUMBER as unknown as PaginatedintacctDestinationAttribute)
66+
);
1467

1568
fixture = TestBed.createComponent(IntacctExportSettingsComponent);
1669
component = fixture.componentInstance;
17-
fixture.detectChanges();
1870
});
1971

2072
it('should create', () => {
2173
expect(component).toBeTruthy();
2274
});
23-
});
75+
76+
describe('Initialization', () => {
77+
beforeEach(fakeAsync(() => {
78+
fixture.detectChanges();
79+
tick();
80+
}));
81+
82+
it('should initialize destination options correctly', () => {
83+
84+
expect(component.destinationOptions.ACCOUNT).toEqual(jasmine.arrayContaining(
85+
mockPaginatedDestinationAttributes.ACCOUNT.results
86+
) as unknown as IntacctDestinationAttribute[]);
87+
88+
expect(component.destinationOptions.EXPENSE_PAYMENT_TYPE).toEqual(jasmine.arrayContaining(
89+
(mockPaginatedDestinationAttributes.EXPENSE_PAYMENT_TYPE.results)
90+
.filter((attr) => attr.detail.is_reimbursable)
91+
) as unknown as IntacctDestinationAttribute[]);
92+
93+
expect(component.destinationOptions.CCC_EXPENSE_PAYMENT_TYPE).toEqual(jasmine.arrayContaining(
94+
(mockPaginatedDestinationAttributes.EXPENSE_PAYMENT_TYPE.results)
95+
.filter((attr) => !attr.detail.is_reimbursable)
96+
) as unknown as IntacctDestinationAttribute[]);
97+
98+
expect(component.destinationOptions.VENDOR).toEqual(jasmine.arrayContaining(
99+
mockPaginatedDestinationAttributes.VENDOR.results
100+
) as unknown as IntacctDestinationAttribute[]);
101+
102+
expect(component.destinationOptions.CHARGE_CARD).toEqual(jasmine.arrayContaining(
103+
mockPaginatedDestinationAttributes.CHARGE_CARD_NUMBER.results as unknown as IntacctDestinationAttribute[]
104+
) as unknown as IntacctDestinationAttribute[]);
105+
});
106+
107+
it('should add missing destination options', () => {
108+
109+
expect(component.destinationOptions.ACCOUNT).toContain({
110+
destination_id: mockExportSettings.general_mappings.default_gl_account.id,
111+
value: mockExportSettings.general_mappings.default_gl_account.name
112+
} as unknown as IntacctDestinationAttribute);
113+
114+
expect(component.destinationOptions.ACCOUNT).toContain({
115+
destination_id: mockExportSettings.general_mappings.default_credit_card.id,
116+
value: mockExportSettings.general_mappings.default_credit_card.name
117+
} as unknown as IntacctDestinationAttribute);
118+
119+
});
120+
121+
it('should fetch and store export settings', () => {
122+
expect(exportSettingService.getExportSettings).toHaveBeenCalled();
123+
expect(component.exportSettings).toEqual(mockExportSettings);
124+
expect(component.exportSettingsForm).toBeDefined();
125+
expect(component.isLoading).toBeFalse();
126+
});
127+
});
128+
129+
describe('Form Save', () => {
130+
it('should save export settings successfully during onboarding', fakeAsync(() => {
131+
workspaceService.getIntacctOnboardingState.and.returnValue(IntacctOnboardingState.EXPORT_SETTINGS);
132+
exportSettingService.postExportSettings.and.returnValue(of(mockExportSettings));
133+
spyOnProperty(router, 'url').and.returnValue('/integrations/intacct/onboarding/export_settings');
134+
135+
fixture.detectChanges();
136+
component.save();
137+
tick();
138+
139+
expect(exportSettingService.postExportSettings).toHaveBeenCalled();
140+
expect(toastService.displayToastMessage).toHaveBeenCalledWith(ToastSeverity.SUCCESS, 'Export settings saved successfully');
141+
expect(trackingService.integrationsOnboardingCompletion).toHaveBeenCalled();
142+
expect(workspaceService.setIntacctOnboardingState).toHaveBeenCalledWith(IntacctOnboardingState.IMPORT_SETTINGS);
143+
expect(router.navigate).toHaveBeenCalledWith(['/integrations/intacct/onboarding/import_settings']);
144+
}));
145+
146+
it('should save export settings successfully post onboarding', () => {
147+
workspaceService.getIntacctOnboardingState.and.returnValue(IntacctOnboardingState.COMPLETE);
148+
exportSettingService.postExportSettings.and.returnValue(of(mockExportSettings));
149+
150+
fixture.detectChanges();
151+
component.save();
152+
153+
expect(exportSettingService.postExportSettings).toHaveBeenCalled();
154+
expect(toastService.displayToastMessage).toHaveBeenCalledWith(ToastSeverity.SUCCESS, 'Export settings saved successfully');
155+
expect(trackingService.intacctUpdateEvent).toHaveBeenCalled();
156+
expect(router.navigate).not.toHaveBeenCalled();
157+
});
158+
159+
it('should handle save failure', () => {
160+
exportSettingService.postExportSettings.and.returnValue(throwError(() => new Error('API Error')));
161+
162+
fixture.detectChanges();
163+
component.save();
164+
165+
expect(toastService.displayToastMessage).toHaveBeenCalledWith(ToastSeverity.ERROR, 'Error saving export settings, please try again later');
166+
expect(component.saveInProgress).toBeFalse();
167+
});
168+
});
169+
170+
it('should handle refresh dimensions', () => {
171+
component.refreshDimensions(true);
172+
expect(mappingService.refreshSageIntacctDimensions).toHaveBeenCalled();
173+
expect(mappingService.refreshFyleDimensions).toHaveBeenCalled();
174+
expect(toastService.displayToastMessage).toHaveBeenCalledWith(ToastSeverity.SUCCESS, 'Syncing data dimensions from Sage Intacct');
175+
});
176+
177+
it('should navigate to previous step', () => {
178+
component.navigateToPreviousStep();
179+
expect(router.navigate).toHaveBeenCalledWith(['/integrations/intacct/onboarding/connector']);
180+
});
181+
});

0 commit comments

Comments
 (0)