Skip to content

Commit 1514f40

Browse files
authored
test: qbo mapping (#998)
* test: QBO complete export log * lint fix * test: qbo skipped export log component * rem failing assertions * updated tests and fixtures * fixed breaking tests * lint fixes * pr comments * test: qbo mapping * fixed assertions * lint fixes * fix merge conflicts * lint fixes * lint fixes
1 parent 6a5c4ad commit 1514f40

File tree

2 files changed

+327
-8
lines changed

2 files changed

+327
-8
lines changed
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,141 @@
1-
import { ComponentFixture, TestBed } from '@angular/core/testing';
2-
1+
/* eslint-disable max-lines */
2+
/* eslint-disable dot-notation */
3+
import { ComponentFixture, TestBed, fakeAsync, tick } from '@angular/core/testing';
4+
import { Router } from '@angular/router';
5+
import { of, throwError } from 'rxjs';
36
import { QboMappingComponent } from './qbo-mapping.component';
7+
import { MappingService } from 'src/app/core/services/common/mapping.service';
8+
import { brandingConfig, brandingFeatureConfig } from 'src/app/branding/branding-config';
9+
import { FyleField } from 'src/app/core/models/enum/enum.model';
10+
import { mockMappingSettings } from '../../qbo.fixture';
11+
import { MappingSettingResponse } from 'src/app/core/models/db/mapping-setting.model';
12+
import { SnakeCaseToSpaceCasePipe } from 'src/app/shared/pipes/snake-case-to-space-case.pipe';
13+
import { SentenceCasePipe } from 'src/app/shared/pipes/sentence-case.pipe';
14+
import { TitleCasePipe } from '@angular/common';
415

5-
xdescribe('QboMappingComponent', () => {
16+
describe('QboMappingComponent', () => {
617
let component: QboMappingComponent;
718
let fixture: ComponentFixture<QboMappingComponent>;
19+
let mappingServiceSpy: jasmine.SpyObj<MappingService>;
20+
let routerSpy: jasmine.SpyObj<Router>;
821

922
beforeEach(async () => {
23+
mappingServiceSpy = jasmine.createSpyObj('MappingService', ['getMappingSettings']);
24+
routerSpy = jasmine.createSpyObj('Router', ['navigateByUrl']);
25+
1026
await TestBed.configureTestingModule({
11-
declarations: [ QboMappingComponent ]
12-
})
13-
.compileComponents();
27+
declarations: [
28+
QboMappingComponent,
29+
SnakeCaseToSpaceCasePipe,
30+
SentenceCasePipe
31+
],
32+
imports: [
33+
TitleCasePipe
34+
],
35+
providers: [
36+
{ provide: MappingService, useValue: mappingServiceSpy },
37+
{ provide: Router, useValue: routerSpy }
38+
]
39+
}).compileComponents();
1440

1541
fixture = TestBed.createComponent(QboMappingComponent);
1642
component = fixture.componentInstance;
17-
fixture.detectChanges();
1843
});
1944

2045
it('should create', () => {
2146
expect(component).toBeTruthy();
2247
});
23-
});
48+
49+
it('should setup page correctly with additional mapping pages', fakeAsync(() => {
50+
const extendedMockMappingSettings = {
51+
...mockMappingSettings,
52+
results: [
53+
...mockMappingSettings.results,
54+
{ source_field: FyleField.CATEGORY },
55+
{ source_field: FyleField.VENDOR }
56+
]
57+
};
58+
59+
mappingServiceSpy.getMappingSettings.and.returnValue(of(extendedMockMappingSettings as MappingSettingResponse));
60+
61+
component.ngOnInit();
62+
tick();
63+
64+
expect(component.mappingPages.length).toBe(3);
65+
expect(component.mappingPages[0].label).toBe('Employee');
66+
expect(component.mappingPages[1].label).toBe('Category');
67+
expect(component.mappingPages[2].label).toBe('Vendor');
68+
expect(component.isLoading).toBeFalse();
69+
expect(routerSpy.navigateByUrl).toHaveBeenCalledWith(component.mappingPages[0].routerLink);
70+
}));
71+
72+
it('should handle empty mapping settings response', fakeAsync(() => {
73+
mappingServiceSpy.getMappingSettings.and.returnValue(of({ results: [] } as unknown as MappingSettingResponse));
74+
75+
component.ngOnInit();
76+
tick();
77+
78+
expect(component.mappingPages.length).toBe(2);
79+
expect(component.isLoading).toBeFalse();
80+
expect(routerSpy.navigateByUrl).toHaveBeenCalledWith(component.mappingPages[0].routerLink);
81+
}));
82+
83+
it('should remove employee mapping page if feature flag is off', fakeAsync(() => {
84+
const originalFeatureFlag = brandingFeatureConfig.featureFlags.mapEmployees;
85+
brandingFeatureConfig.featureFlags.mapEmployees = false;
86+
87+
mappingServiceSpy.getMappingSettings.and.returnValue(of(mockMappingSettings as unknown as MappingSettingResponse));
88+
89+
component.ngOnInit();
90+
tick();
91+
92+
expect(component.mappingPages.length).toBe(1);
93+
expect(component.mappingPages[0].label).toBe('Category');
94+
95+
brandingFeatureConfig.featureFlags.mapEmployees = originalFeatureFlag;
96+
}));
97+
98+
it('should use SentenceCase for CO branding', fakeAsync(() => {
99+
const originalBrandId = brandingConfig.brandId;
100+
brandingConfig.brandId = 'co';
101+
102+
const extendedMockMappingSettings = {
103+
...mockMappingSettings,
104+
results: [
105+
...mockMappingSettings.results,
106+
{ source_field: FyleField.VENDOR }
107+
]
108+
};
109+
110+
mappingServiceSpy.getMappingSettings.and.returnValue(of(extendedMockMappingSettings as MappingSettingResponse));
111+
112+
component.ngOnInit();
113+
tick();
114+
115+
expect(component.mappingPages[2].label).toBe('Vendor');
116+
117+
brandingConfig.brandId = originalBrandId;
118+
}));
119+
120+
it('should use TitleCase for non-CO branding', fakeAsync(() => {
121+
const originalBrandId = brandingConfig.brandId;
122+
brandingConfig.brandId = 'fyle';
123+
124+
const extendedMockMappingSettings = {
125+
...mockMappingSettings,
126+
results: [
127+
...mockMappingSettings.results,
128+
{ source_field: FyleField.VENDOR }
129+
]
130+
};
131+
132+
mappingServiceSpy.getMappingSettings.and.returnValue(of(extendedMockMappingSettings as MappingSettingResponse));
133+
134+
component.ngOnInit();
135+
tick();
136+
137+
expect(component.mappingPages[2].label).toBe('Vendor');
138+
139+
brandingConfig.brandId = originalBrandId;
140+
}));
141+
});

src/app/integrations/qbo/qbo.fixture.ts

+201
Original file line numberDiff line numberDiff line change
@@ -2241,4 +2241,205 @@ export const mockUserProfile = {
22412241
org_name: 'Test Org'
22422242
};
22432243

2244+
// Fixtures for Mapping Pages
2245+
export const mockGeneralSettingsForMapping = {
2246+
"id": 684,
2247+
"reimbursable_expenses_object": "JOURNAL ENTRY",
2248+
"corporate_credit_card_expenses_object": "BILL",
2249+
"employee_field_mapping": "VENDOR",
2250+
"map_merchant_to_vendor": true,
2251+
"import_categories": true,
2252+
"import_items": false,
2253+
"import_projects": false,
2254+
"import_tax_codes": false,
2255+
"change_accounting_period": false,
2256+
"charts_of_accounts": [
2257+
"Expense"
2258+
],
2259+
"memo_structure": [
2260+
"employee_email",
2261+
"purpose",
2262+
"category",
2263+
"spent_on",
2264+
"report_number",
2265+
"expense_link"
2266+
],
2267+
"auto_map_employees": "NAME",
2268+
"auto_create_destination_entity": false,
2269+
"auto_create_merchants_as_vendors": false,
2270+
"sync_fyle_to_qbo_payments": false,
2271+
"sync_qbo_to_fyle_payments": true,
2272+
"is_simplify_report_closure_enabled": true,
2273+
"category_sync_version": "v2",
2274+
"je_single_credit_line": false,
2275+
"map_fyle_cards_qbo_account": false,
2276+
"skip_cards_mapping": false,
2277+
"import_vendors_as_merchants": false,
2278+
"is_multi_currency_allowed": false,
2279+
"is_tax_override_enabled": true,
2280+
"name_in_journal_entry": "EMPLOYEE",
2281+
"import_code_fields": [],
2282+
"created_at": "2024-08-22T08:50:29.978051Z",
2283+
"updated_at": "2024-09-24T18:28:10.411535Z",
2284+
"workspace": 512
2285+
};
2286+
2287+
export const mockMappingSettings = {
2288+
"count": 1,
2289+
"next": null,
2290+
"previous": null,
2291+
"results": [
2292+
{
2293+
"id": 3006,
2294+
"source_field": "CATEGORY",
2295+
"destination_field": "ACCOUNT",
2296+
"import_to_fyle": false,
2297+
"is_custom": false,
2298+
"source_placeholder": null,
2299+
"created_at": "2024-08-22T08:50:50.425404Z",
2300+
"updated_at": "2024-08-28T07:50:45.557168Z",
2301+
"expense_field": null,
2302+
"workspace": 512
2303+
}
2304+
]
2305+
};
2306+
2307+
export const paginatedDestAttribsForMapping = {
2308+
"count": 3,
2309+
"next": "http://quickbooks-api.staging-integrations:8000/api/workspaces/512/mappings/paginated_destination_attributes/?active=true&attribute_type=VENDOR&limit=100&offset=100",
2310+
"previous": null,
2311+
"results": [
2312+
{
2313+
"id": 253195,
2314+
"attribute_type": "VENDOR",
2315+
"display_name": "vendor",
2316+
"value": "1",
2317+
"destination_id": "215",
2318+
"auto_created": false,
2319+
"active": true,
2320+
"detail": {
2321+
"email": null,
2322+
"currency": "USD"
2323+
},
2324+
"code": null,
2325+
"created_at": "2024-08-22T06:44:16.926440Z",
2326+
"updated_at": "2024-08-22T06:44:16.926468Z",
2327+
"workspace": 512
2328+
},
2329+
{
2330+
"id": 253198,
2331+
"attribute_type": "VENDOR",
2332+
"display_name": "vendor",
2333+
"value": "Abhishek 2",
2334+
"destination_id": "146",
2335+
"auto_created": false,
2336+
"active": true,
2337+
"detail": {
2338+
"email": null,
2339+
"currency": "USD"
2340+
},
2341+
"code": null,
2342+
"created_at": "2024-08-22T06:44:16.926600Z",
2343+
"updated_at": "2024-08-22T06:44:16.926609Z",
2344+
"workspace": 512
2345+
},
2346+
{
2347+
"id": 253199,
2348+
"attribute_type": "VENDOR",
2349+
"display_name": "vendor",
2350+
"value": "Abhishek ji",
2351+
"destination_id": "167",
2352+
"auto_created": false,
2353+
"active": true,
2354+
"detail": {
2355+
"email": null,
2356+
"currency": "USD"
2357+
},
2358+
"code": null,
2359+
"created_at": "2024-08-22T06:44:16.926648Z",
2360+
"updated_at": "2024-08-22T06:44:16.926654Z",
2361+
"workspace": 512
2362+
}
2363+
]
2364+
};
2365+
2366+
export const mockemployeeAttributes = {
2367+
"count": 3,
2368+
"next": null,
2369+
"previous": null,
2370+
"results": [
2371+
{
2372+
"id": 1456114,
2373+
"employeemapping": [],
2374+
"attribute_type": "EMPLOYEE",
2375+
"display_name": "Employee",
2376+
"value": "[email protected]",
2377+
"source_id": "ouNnLODE2MhX",
2378+
"auto_mapped": false,
2379+
"auto_created": false,
2380+
"active": true,
2381+
"detail": {
2382+
"user_id": "usAwZNxzZENS",
2383+
"location": null,
2384+
"full_name": "Ashley Adams",
2385+
"department": "Human Resources",
2386+
"department_id": "deptMLvcJapilU",
2387+
"employee_code": "5",
2388+
"department_code": null
2389+
},
2390+
"created_at": "2024-08-22T06:42:43.482374Z",
2391+
"updated_at": "2024-08-22T06:42:43.482383Z",
2392+
"workspace": 512
2393+
},
2394+
{
2395+
"id": 1456123,
2396+
"employeemapping": [],
2397+
"attribute_type": "EMPLOYEE",
2398+
"display_name": "Employee",
2399+
"value": "[email protected]",
2400+
"source_id": "ouh8MSWBpWJI",
2401+
"auto_mapped": false,
2402+
"auto_created": false,
2403+
"active": true,
2404+
"detail": {
2405+
"user_id": "usA8hk3BOIX7",
2406+
"location": null,
2407+
"full_name": "Aaron Eckerly",
2408+
"department": "Customer Success",
2409+
"department_id": "dept6rVZn3smSh",
2410+
"employee_code": "35",
2411+
"department_code": null
2412+
},
2413+
"created_at": "2024-08-22T06:42:43.482800Z",
2414+
"updated_at": "2024-08-22T06:42:43.482808Z",
2415+
"workspace": 512
2416+
},
2417+
{
2418+
"id": 1456122,
2419+
"employeemapping": [],
2420+
"attribute_type": "EMPLOYEE",
2421+
"display_name": "Employee",
2422+
"value": "[email protected]",
2423+
"source_id": "ouTBfIlGoZCL",
2424+
"auto_mapped": false,
2425+
"auto_created": false,
2426+
"active": true,
2427+
"detail": {
2428+
"user_id": "usGdQoFQWiEs",
2429+
"location": null,
2430+
"full_name": "Abhishek Singh",
2431+
"department": "Human Resources",
2432+
"department_id": "deptMLvcJapilU",
2433+
"employee_code": "112",
2434+
"department_code": null
2435+
},
2436+
"created_at": "2024-08-22T06:42:43.482753Z",
2437+
"updated_at": "2024-08-22T06:42:43.482762Z",
2438+
"workspace": 512
2439+
}
2440+
]
2441+
};
2442+
2443+
export const mockMappingStats = {"all_attributes_count": 105, "unmapped_attributes_count": 92};
2444+
22442445
export const mockPageSize = { limit: 10, offset: 0 };

0 commit comments

Comments
 (0)