diff --git a/src/app/integrations/qbo/qbo-main/qbo-mapping/qbo-mapping.component.spec.ts b/src/app/integrations/qbo/qbo-main/qbo-mapping/qbo-mapping.component.spec.ts index a57a54364..ed4d973e6 100644 --- a/src/app/integrations/qbo/qbo-main/qbo-mapping/qbo-mapping.component.spec.ts +++ b/src/app/integrations/qbo/qbo-main/qbo-mapping/qbo-mapping.component.spec.ts @@ -1,23 +1,141 @@ -import { ComponentFixture, TestBed } from '@angular/core/testing'; - +/* eslint-disable max-lines */ +/* eslint-disable dot-notation */ +import { ComponentFixture, TestBed, fakeAsync, tick } from '@angular/core/testing'; +import { Router } from '@angular/router'; +import { of, throwError } from 'rxjs'; import { QboMappingComponent } from './qbo-mapping.component'; +import { MappingService } from 'src/app/core/services/common/mapping.service'; +import { brandingConfig, brandingFeatureConfig } from 'src/app/branding/branding-config'; +import { FyleField } from 'src/app/core/models/enum/enum.model'; +import { mockMappingSettings } from '../../qbo.fixture'; +import { MappingSettingResponse } from 'src/app/core/models/db/mapping-setting.model'; +import { SnakeCaseToSpaceCasePipe } from 'src/app/shared/pipes/snake-case-to-space-case.pipe'; +import { SentenceCasePipe } from 'src/app/shared/pipes/sentence-case.pipe'; +import { TitleCasePipe } from '@angular/common'; -xdescribe('QboMappingComponent', () => { +describe('QboMappingComponent', () => { let component: QboMappingComponent; let fixture: ComponentFixture; + let mappingServiceSpy: jasmine.SpyObj; + let routerSpy: jasmine.SpyObj; beforeEach(async () => { + mappingServiceSpy = jasmine.createSpyObj('MappingService', ['getMappingSettings']); + routerSpy = jasmine.createSpyObj('Router', ['navigateByUrl']); + await TestBed.configureTestingModule({ - declarations: [ QboMappingComponent ] - }) - .compileComponents(); + declarations: [ + QboMappingComponent, + SnakeCaseToSpaceCasePipe, + SentenceCasePipe + ], + imports: [ + TitleCasePipe + ], + providers: [ + { provide: MappingService, useValue: mappingServiceSpy }, + { provide: Router, useValue: routerSpy } + ] + }).compileComponents(); fixture = TestBed.createComponent(QboMappingComponent); component = fixture.componentInstance; - fixture.detectChanges(); }); it('should create', () => { expect(component).toBeTruthy(); }); -}); + + it('should setup page correctly with additional mapping pages', fakeAsync(() => { + const extendedMockMappingSettings = { + ...mockMappingSettings, + results: [ + ...mockMappingSettings.results, + { source_field: FyleField.CATEGORY }, + { source_field: FyleField.VENDOR } + ] + }; + + mappingServiceSpy.getMappingSettings.and.returnValue(of(extendedMockMappingSettings as MappingSettingResponse)); + + component.ngOnInit(); + tick(); + + expect(component.mappingPages.length).toBe(3); + expect(component.mappingPages[0].label).toBe('Employee'); + expect(component.mappingPages[1].label).toBe('Category'); + expect(component.mappingPages[2].label).toBe('Vendor'); + expect(component.isLoading).toBeFalse(); + expect(routerSpy.navigateByUrl).toHaveBeenCalledWith(component.mappingPages[0].routerLink); + })); + + it('should handle empty mapping settings response', fakeAsync(() => { + mappingServiceSpy.getMappingSettings.and.returnValue(of({ results: [] } as unknown as MappingSettingResponse)); + + component.ngOnInit(); + tick(); + + expect(component.mappingPages.length).toBe(2); + expect(component.isLoading).toBeFalse(); + expect(routerSpy.navigateByUrl).toHaveBeenCalledWith(component.mappingPages[0].routerLink); + })); + + it('should remove employee mapping page if feature flag is off', fakeAsync(() => { + const originalFeatureFlag = brandingFeatureConfig.featureFlags.mapEmployees; + brandingFeatureConfig.featureFlags.mapEmployees = false; + + mappingServiceSpy.getMappingSettings.and.returnValue(of(mockMappingSettings as unknown as MappingSettingResponse)); + + component.ngOnInit(); + tick(); + + expect(component.mappingPages.length).toBe(1); + expect(component.mappingPages[0].label).toBe('Category'); + + brandingFeatureConfig.featureFlags.mapEmployees = originalFeatureFlag; + })); + + it('should use SentenceCase for CO branding', fakeAsync(() => { + const originalBrandId = brandingConfig.brandId; + brandingConfig.brandId = 'co'; + + const extendedMockMappingSettings = { + ...mockMappingSettings, + results: [ + ...mockMappingSettings.results, + { source_field: FyleField.VENDOR } + ] + }; + + mappingServiceSpy.getMappingSettings.and.returnValue(of(extendedMockMappingSettings as MappingSettingResponse)); + + component.ngOnInit(); + tick(); + + expect(component.mappingPages[2].label).toBe('Vendor'); + + brandingConfig.brandId = originalBrandId; + })); + + it('should use TitleCase for non-CO branding', fakeAsync(() => { + const originalBrandId = brandingConfig.brandId; + brandingConfig.brandId = 'fyle'; + + const extendedMockMappingSettings = { + ...mockMappingSettings, + results: [ + ...mockMappingSettings.results, + { source_field: FyleField.VENDOR } + ] + }; + + mappingServiceSpy.getMappingSettings.and.returnValue(of(extendedMockMappingSettings as MappingSettingResponse)); + + component.ngOnInit(); + tick(); + + expect(component.mappingPages[2].label).toBe('Vendor'); + + brandingConfig.brandId = originalBrandId; + })); +}); \ No newline at end of file diff --git a/src/app/integrations/qbo/qbo.fixture.ts b/src/app/integrations/qbo/qbo.fixture.ts index 745c8f70e..b64990334 100644 --- a/src/app/integrations/qbo/qbo.fixture.ts +++ b/src/app/integrations/qbo/qbo.fixture.ts @@ -2241,4 +2241,205 @@ export const mockUserProfile = { org_name: 'Test Org' }; +// Fixtures for Mapping Pages +export const mockGeneralSettingsForMapping = { + "id": 684, + "reimbursable_expenses_object": "JOURNAL ENTRY", + "corporate_credit_card_expenses_object": "BILL", + "employee_field_mapping": "VENDOR", + "map_merchant_to_vendor": true, + "import_categories": true, + "import_items": false, + "import_projects": false, + "import_tax_codes": false, + "change_accounting_period": false, + "charts_of_accounts": [ + "Expense" + ], + "memo_structure": [ + "employee_email", + "purpose", + "category", + "spent_on", + "report_number", + "expense_link" + ], + "auto_map_employees": "NAME", + "auto_create_destination_entity": false, + "auto_create_merchants_as_vendors": false, + "sync_fyle_to_qbo_payments": false, + "sync_qbo_to_fyle_payments": true, + "is_simplify_report_closure_enabled": true, + "category_sync_version": "v2", + "je_single_credit_line": false, + "map_fyle_cards_qbo_account": false, + "skip_cards_mapping": false, + "import_vendors_as_merchants": false, + "is_multi_currency_allowed": false, + "is_tax_override_enabled": true, + "name_in_journal_entry": "EMPLOYEE", + "import_code_fields": [], + "created_at": "2024-08-22T08:50:29.978051Z", + "updated_at": "2024-09-24T18:28:10.411535Z", + "workspace": 512 +}; + +export const mockMappingSettings = { + "count": 1, + "next": null, + "previous": null, + "results": [ + { + "id": 3006, + "source_field": "CATEGORY", + "destination_field": "ACCOUNT", + "import_to_fyle": false, + "is_custom": false, + "source_placeholder": null, + "created_at": "2024-08-22T08:50:50.425404Z", + "updated_at": "2024-08-28T07:50:45.557168Z", + "expense_field": null, + "workspace": 512 + } + ] +}; + +export const paginatedDestAttribsForMapping = { + "count": 3, + "next": "http://quickbooks-api.staging-integrations:8000/api/workspaces/512/mappings/paginated_destination_attributes/?active=true&attribute_type=VENDOR&limit=100&offset=100", + "previous": null, + "results": [ + { + "id": 253195, + "attribute_type": "VENDOR", + "display_name": "vendor", + "value": "1", + "destination_id": "215", + "auto_created": false, + "active": true, + "detail": { + "email": null, + "currency": "USD" + }, + "code": null, + "created_at": "2024-08-22T06:44:16.926440Z", + "updated_at": "2024-08-22T06:44:16.926468Z", + "workspace": 512 + }, + { + "id": 253198, + "attribute_type": "VENDOR", + "display_name": "vendor", + "value": "Abhishek 2", + "destination_id": "146", + "auto_created": false, + "active": true, + "detail": { + "email": null, + "currency": "USD" + }, + "code": null, + "created_at": "2024-08-22T06:44:16.926600Z", + "updated_at": "2024-08-22T06:44:16.926609Z", + "workspace": 512 + }, + { + "id": 253199, + "attribute_type": "VENDOR", + "display_name": "vendor", + "value": "Abhishek ji", + "destination_id": "167", + "auto_created": false, + "active": true, + "detail": { + "email": null, + "currency": "USD" + }, + "code": null, + "created_at": "2024-08-22T06:44:16.926648Z", + "updated_at": "2024-08-22T06:44:16.926654Z", + "workspace": 512 + } + ] +}; + +export const mockemployeeAttributes = { + "count": 3, + "next": null, + "previous": null, + "results": [ + { + "id": 1456114, + "employeemapping": [], + "attribute_type": "EMPLOYEE", + "display_name": "Employee", + "value": "aadams@efficientoffice.com", + "source_id": "ouNnLODE2MhX", + "auto_mapped": false, + "auto_created": false, + "active": true, + "detail": { + "user_id": "usAwZNxzZENS", + "location": null, + "full_name": "Ashley Adams", + "department": "Human Resources", + "department_id": "deptMLvcJapilU", + "employee_code": "5", + "department_code": null + }, + "created_at": "2024-08-22T06:42:43.482374Z", + "updated_at": "2024-08-22T06:42:43.482383Z", + "workspace": 512 + }, + { + "id": 1456123, + "employeemapping": [], + "attribute_type": "EMPLOYEE", + "display_name": "Employee", + "value": "aaron@efficientoffice.com", + "source_id": "ouh8MSWBpWJI", + "auto_mapped": false, + "auto_created": false, + "active": true, + "detail": { + "user_id": "usA8hk3BOIX7", + "location": null, + "full_name": "Aaron Eckerly", + "department": "Customer Success", + "department_id": "dept6rVZn3smSh", + "employee_code": "35", + "department_code": null + }, + "created_at": "2024-08-22T06:42:43.482800Z", + "updated_at": "2024-08-22T06:42:43.482808Z", + "workspace": 512 + }, + { + "id": 1456122, + "employeemapping": [], + "attribute_type": "EMPLOYEE", + "display_name": "Employee", + "value": "abhisheksingh@prod.com", + "source_id": "ouTBfIlGoZCL", + "auto_mapped": false, + "auto_created": false, + "active": true, + "detail": { + "user_id": "usGdQoFQWiEs", + "location": null, + "full_name": "Abhishek Singh", + "department": "Human Resources", + "department_id": "deptMLvcJapilU", + "employee_code": "112", + "department_code": null + }, + "created_at": "2024-08-22T06:42:43.482753Z", + "updated_at": "2024-08-22T06:42:43.482762Z", + "workspace": 512 + } + ] +}; + +export const mockMappingStats = {"all_attributes_count": 105, "unmapped_attributes_count": 92}; + export const mockPageSize = { limit: 10, offset: 0 }; \ No newline at end of file