Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

test: qbo base mapping #999

Merged
merged 23 commits into from
Oct 11, 2024
Merged
Show file tree
Hide file tree
Changes from 21 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -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<QboBaseMappingComponent>;
let mockActivatedRoute: any;
let mockMappingService: jasmine.SpyObj<MappingService>;
let mockToastService: jasmine.SpyObj<IntegrationsToastService>;
let mockWorkspaceService: jasmine.SpyObj<WorkspaceService>;
let mockImportSettingsService: jasmine.SpyObj<QboImportSettingsService>;

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();
});
Comment on lines +76 to +87
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Correct the expectation in 'should handle route parameter changes' test

In this test, you're setting mockActivatedRoute.params = of({ source_field: 'Vendor' }); (line 82), but the expectation on line 85 is expect(component.sourceField).toBe(FyleField.EMPLOYEE);. Shouldn't component.sourceField reflect the updated route parameter and be FyleField.VENDOR instead?

Apply this diff to correct the expectation:

-    expect(component.sourceField).toBe(FyleField.EMPLOYEE);
+    expect(component.sourceField).toBe(FyleField.VENDOR);
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
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 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.VENDOR);
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');
});
Comment on lines +89 to +96
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Remove duplicate test cases for 'should return employee_field_mapping when sourceField is EMPLOYEE'

The test case in lines 137-144 is a duplicate of the one in lines 89-96. Please remove the duplicate to avoid redundancy.

Apply this diff to remove the duplicate test case:

-  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');
-  });

Also applies to: 137-144


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);
});
Comment on lines +98 to +105
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Remove duplicate test cases for 'should return ACCOUNT when sourceField is CATEGORY'

The test case in lines 146-153 is duplicated from lines 98-105. Consider removing the duplicate to keep the test suite concise.

Apply this diff to remove the duplicate test case:

-  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);
-  });

Also applies to: 146-153


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('');
});
Comment on lines +128 to +135
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Remove duplicate test cases for 'should return empty string if no matching mapping setting is found'

The test case in lines 163-170 is a duplicate of the one in lines 128-135. Removing duplicates helps maintain clarity in your tests.

Apply this diff to remove the duplicate test case:

-  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('');
-  });

Also applies to: 163-170


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('');
});
});
17 changes: 16 additions & 1 deletion src/app/integrations/qbo/qbo.fixture.ts
Original file line number Diff line number Diff line change
@@ -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";
Expand All @@ -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',
Expand Down Expand Up @@ -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 };
Loading