From d1f26efa6b9665b6f6490a73a118e8a56da214c6 Mon Sep 17 00:00:00 2001 From: Anish Kr Singh <116036738+anishfyle@users.noreply.github.com> Date: Fri, 11 Oct 2024 15:00:34 +0530 Subject: [PATCH] test: qbo base mapping (#999) * 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 * test: qbo base mapping * lint fix * additional fixtures and test * fix conflicts * lint fixes * lint * lint fix --- .../qbo-base-mapping.component.spec.ts | 160 +++++++++++++++++- src/app/integrations/qbo/qbo.fixture.ts | 17 +- 2 files changed, 170 insertions(+), 7 deletions(-) diff --git a/src/app/integrations/qbo/qbo-main/qbo-mapping/qbo-base-mapping/qbo-base-mapping.component.spec.ts b/src/app/integrations/qbo/qbo-main/qbo-mapping/qbo-base-mapping/qbo-base-mapping.component.spec.ts index ca0e9f684..3bd499003 100644 --- a/src/app/integrations/qbo/qbo-main/qbo-mapping/qbo-base-mapping/qbo-base-mapping.component.spec.ts +++ b/src/app/integrations/qbo/qbo-main/qbo-mapping/qbo-base-mapping/qbo-base-mapping.component.spec.ts @@ -1,23 +1,171 @@ +/* eslint-disable max-lines */ +/* eslint-disable dot-notation */ import { ComponentFixture, TestBed } from '@angular/core/testing'; - +import { ActivatedRoute } from '@angular/router'; +import { of, throwError } from 'rxjs'; import { QboBaseMappingComponent } from './qbo-base-mapping.component'; +import { MappingService } from 'src/app/core/services/common/mapping.service'; +import { IntegrationsToastService } from 'src/app/core/services/common/integrations-toast.service'; +import { WorkspaceService } from 'src/app/core/services/common/workspace.service'; +import { QboImportSettingsService } from 'src/app/core/services/qbo/qbo-configuration/qbo-import-settings.service'; +import { AccountingDisplayName, AccountingField, FyleField, ToastSeverity } from 'src/app/core/models/enum/enum.model'; +import { mockCreditCardAccounts, mockGeneralSettings, mockImportSettings, mockMappingSetting } from '../../../qbo.fixture'; +import { QBOWorkspaceGeneralSetting } from 'src/app/core/models/qbo/db/workspace-general-setting.model'; +import { MappingSetting } from 'src/app/core/models/db/mapping-setting.model'; +import { QBOImportSettingGet } from 'src/app/core/models/qbo/qbo-configuration/qbo-import-setting.model'; -xdescribe('QboBaseMappingComponent', () => { +describe('QboBaseMappingComponent', () => { let component: QboBaseMappingComponent; let fixture: ComponentFixture; + let mockActivatedRoute: any; + let mockMappingService: jasmine.SpyObj; + let mockToastService: jasmine.SpyObj; + let mockWorkspaceService: jasmine.SpyObj; + let mockImportSettingsService: jasmine.SpyObj; beforeEach(async () => { + mockActivatedRoute = { + params: of({ source_field: 'EMPLOYEE' }), + snapshot: { + params: { source_field: 'EMPLOYEE' } + } + }; + + mockMappingService = jasmine.createSpyObj('MappingService', ['triggerAutoMapEmployees', 'getMappingSettings', 'getPaginatedDestinationAttributes']); + mockToastService = jasmine.createSpyObj('IntegrationsToastService', ['displayToastMessage']); + mockWorkspaceService = jasmine.createSpyObj('WorkspaceService', ['getWorkspaceGeneralSettings']); + mockImportSettingsService = jasmine.createSpyObj('QboImportSettingsService', ['getImportSettings']); + await TestBed.configureTestingModule({ - declarations: [ QboBaseMappingComponent ] - }) - .compileComponents(); + declarations: [ QboBaseMappingComponent ], + providers: [ + { provide: ActivatedRoute, useValue: mockActivatedRoute }, + { provide: MappingService, useValue: mockMappingService }, + { provide: IntegrationsToastService, useValue: mockToastService }, + { provide: WorkspaceService, useValue: mockWorkspaceService }, + { provide: QboImportSettingsService, useValue: mockImportSettingsService } + ] + }).compileComponents(); fixture = TestBed.createComponent(QboBaseMappingComponent); component = fixture.componentInstance; - fixture.detectChanges(); }); it('should create', () => { expect(component).toBeTruthy(); }); + + it('should trigger auto map employees successfully', () => { + mockMappingService.triggerAutoMapEmployees.and.returnValue(of(null)); + + component.triggerAutoMapEmployees(); + + expect(component.isLoading).toBeFalse(); + expect(mockToastService.displayToastMessage).toHaveBeenCalledWith(ToastSeverity.INFO, 'Auto mapping of employees may take few minutes'); + }); + + it('should handle error when triggering auto map employees', () => { + mockMappingService.triggerAutoMapEmployees.and.returnValue(throwError('Error')); + + component.triggerAutoMapEmployees(); + + expect(component.isLoading).toBeFalse(); + expect(mockToastService.displayToastMessage).toHaveBeenCalledWith(ToastSeverity.ERROR, 'Something went wrong, please try again'); + }); + + it('should handle route parameter changes', () => { + mockWorkspaceService.getWorkspaceGeneralSettings.and.returnValue(of(mockGeneralSettings)); + mockMappingService.getMappingSettings.and.returnValue(of({ count: 1, next: null, previous: null, results: mockImportSettings.mapping_settings })); + mockImportSettingsService.getImportSettings.and.returnValue(of(mockImportSettings)); + mockMappingService.getPaginatedDestinationAttributes.and.returnValue(of(mockCreditCardAccounts)); + + mockActivatedRoute.params = of({ source_field: 'Vendor' }); + fixture.detectChanges(); + + expect(component.sourceField).toBe(FyleField.EMPLOYEE); + expect(component.isLoading).toBeFalse(); + }); + + it('should return employee_field_mapping when sourceField is EMPLOYEE', () => { + component.sourceField = FyleField.EMPLOYEE; + const workspaceGeneralSetting = { employee_field_mapping: 'VENDOR' } as QBOWorkspaceGeneralSetting; + const mappingSettings: MappingSetting[] = []; + + const result = (component as any).getDestinationField(workspaceGeneralSetting, mappingSettings); + expect(result).toBe('VENDOR'); + }); + + it('should return ACCOUNT when sourceField is CATEGORY', () => { + component.sourceField = FyleField.CATEGORY; + const workspaceGeneralSetting = {} as QBOWorkspaceGeneralSetting; + const mappingSettings: MappingSetting[] = []; + + const result = (component as any).getDestinationField(workspaceGeneralSetting, mappingSettings); + expect(result).toBe(AccountingField.ACCOUNT); + }); + + it('should return destination_field from mappingSettings for other sourceFields', () => { + component.sourceField = FyleField.CATEGORY; + const workspaceGeneralSetting = {} as QBOWorkspaceGeneralSetting; + const mappingSettings: MappingSetting[] = [ + { + source_field: FyleField.CATEGORY, + destination_field: AccountingField.ACCOUNT, + id: 0, + created_at: new Date(), + updated_at: new Date(), + workspace: 0, + import_to_fyle: false, + is_custom: false, + source_placeholder: null + } + ]; + + const result = (component as any).getDestinationField(workspaceGeneralSetting, mappingSettings); + expect(result).toBe('ACCOUNT'); + }); + + it('should return empty string if no matching mapping setting is found', () => { + component.sourceField = FyleField.VENDOR; + const workspaceGeneralSetting = {} as QBOWorkspaceGeneralSetting; + const mappingSettings: MappingSetting[] = []; + + const result = (component as any).getDestinationField(workspaceGeneralSetting, mappingSettings); + expect(result).toBe(''); + }); + + it('should return employee_field_mapping when sourceField is EMPLOYEE', () => { + component.sourceField = FyleField.EMPLOYEE; + const workspaceGeneralSetting = { employee_field_mapping: 'VENDOR' } as QBOWorkspaceGeneralSetting; + const mappingSettings: MappingSetting[] = []; + + const result = (component as any).getDestinationField(workspaceGeneralSetting, mappingSettings); + expect(result).toBe('VENDOR'); + }); + + it('should return ACCOUNT when sourceField is CATEGORY', () => { + component.sourceField = FyleField.CATEGORY; + const workspaceGeneralSetting = {} as QBOWorkspaceGeneralSetting; + const mappingSettings: MappingSetting[] = []; + + const result = (component as any).getDestinationField(workspaceGeneralSetting, mappingSettings); + expect(result).toBe(AccountingField.ACCOUNT); + }); + + it('should return destination_field from mappingSettings for VENDOR sourceField', () => { + component.sourceField = FyleField.VENDOR; + const workspaceGeneralSetting = {} as QBOWorkspaceGeneralSetting; + + const result = (component as any).getDestinationField(workspaceGeneralSetting, mockMappingSetting); + expect(result).toBe(AccountingField.ACCOUNT); + }); + + it('should return empty string if no matching mapping setting is found', () => { + component.sourceField = FyleField.VENDOR; + const workspaceGeneralSetting = {} as QBOWorkspaceGeneralSetting; + const mappingSettings: MappingSetting[] = []; + + const result = (component as any).getDestinationField(workspaceGeneralSetting, mappingSettings); + expect(result).toBe(''); + }); }); diff --git a/src/app/integrations/qbo/qbo.fixture.ts b/src/app/integrations/qbo/qbo.fixture.ts index b64990334..f93043169 100644 --- a/src/app/integrations/qbo/qbo.fixture.ts +++ b/src/app/integrations/qbo/qbo.fixture.ts @@ -1,5 +1,5 @@ import { MinimalUser } from "src/app/core/models/db/user.model"; -import { AutoMapEmployeeOptions, EmployeeFieldMapping, CCCExpenseState, ExpenseState, ExportDateType, NameInJournalEntry, QBOCorporateCreditCardExpensesObject, QBOOnboardingState, SplitExpenseGrouping, QBOReimbursableExpensesObject, QboExportSettingDestinationOptionKey, Operator, AccountingErrorType, TaskLogState, QBOTaskLogType } from "src/app/core/models/enum/enum.model"; +import { AutoMapEmployeeOptions, EmployeeFieldMapping, CCCExpenseState, ExpenseState, ExportDateType, NameInJournalEntry, QBOCorporateCreditCardExpensesObject, QBOOnboardingState, SplitExpenseGrouping, QBOReimbursableExpensesObject, QboExportSettingDestinationOptionKey, Operator, AccountingErrorType, TaskLogState, QBOTaskLogType, AccountingField } from "src/app/core/models/enum/enum.model"; import { QBOEmployeeSettingGet, QBOEmployeeSettingPost } from "src/app/core/models/qbo/qbo-configuration/qbo-employee-setting.model"; import { GroupedDestinationAttribute, PaginatedDestinationAttribute } from 'src/app/core/models/db/destination-attribute.model'; import { SelectFormOption } from "src/app/core/models/common/select-form-option.model"; @@ -13,6 +13,7 @@ import { AccountingExport } from "src/app/core/models/db/accounting-export.model import { ExpenseGroupResponse } from "src/app/core/models/db/expense-group.model"; import { SkipExportLogResponse } from "src/app/core/models/intacct/db/expense-group.model"; import { Paginator } from "src/app/core/models/misc/paginator.model"; +import { MappingSetting } from "src/app/core/models/db/mapping-setting.model"; export const mockUser: MinimalUser = { org_id: '123', @@ -2442,4 +2443,18 @@ export const mockemployeeAttributes = { export const mockMappingStats = {"all_attributes_count": 105, "unmapped_attributes_count": 92}; +export const mockMappingSetting: MappingSetting[] = [ + { + source_field: 'VENDOR', + destination_field: AccountingField.ACCOUNT, + id: 0, + created_at: new Date(), + updated_at: new Date(), + workspace: 0, + import_to_fyle: false, + is_custom: false, + source_placeholder: null + } +]; + export const mockPageSize = { limit: 10, offset: 0 }; \ No newline at end of file