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: unit test the intacct mapping page #983

Merged
merged 4 commits into from
Sep 30, 2024
Merged
Show file tree
Hide file tree
Changes from 2 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,134 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';

/* eslint-disable dot-notation */
import { ComponentFixture, fakeAsync, TestBed, tick } from '@angular/core/testing';
JustARatherRidiculouslyLongUsername marked this conversation as resolved.
Show resolved Hide resolved
import { ActivatedRoute } from '@angular/router';
import { of, throwError } from 'rxjs';
import { IntacctBaseMappingComponent } from './intacct-base-mapping.component';
import { MappingService } from 'src/app/core/services/common/mapping.service';
import { WorkspaceService } from 'src/app/core/services/common/workspace.service';
import { IntegrationsToastService } from 'src/app/core/services/common/integrations-toast.service';
import { FyleField, IntacctCategoryDestination, IntacctCorporateCreditCardExpensesObject, IntacctReimbursableExpensesObject, ToastSeverity } from 'src/app/core/models/enum/enum.model';
import { mockConfigurationResponse, mockMappingSettingsResponse, mockDestinationAttributesResponse } from '../../../intacct.fixture';
import { MappingSettingResponse } from 'src/app/core/models/intacct/db/mapping-setting.model';
import { DestinationAttribute, PaginatedDestinationAttribute } from 'src/app/core/models/db/destination-attribute.model';
import { SharedModule } from 'src/app/shared/shared.module';


xdescribe('IntacctBaseMappingComponent', () => {
describe('IntacctBaseMappingComponent', () => {
let component: IntacctBaseMappingComponent;
let fixture: ComponentFixture<IntacctBaseMappingComponent>;
let routeSpy: jasmine.SpyObj<ActivatedRoute>;
let mappingServiceSpy: jasmine.SpyObj<MappingService>;
let workspaceServiceSpy: jasmine.SpyObj<WorkspaceService>;
let toastServiceSpy: jasmine.SpyObj<IntegrationsToastService>;

beforeEach(async () => {
routeSpy = jasmine.createSpyObj('ActivatedRoute', [], {
params: of({ source_field: 'employee' }),
snapshot: { params: { source_field: 'employee' } }
});
mappingServiceSpy = jasmine.createSpyObj('MappingService', ['getMappingSettings', 'getPaginatedDestinationAttributes', 'triggerAutoMapEmployees']);
workspaceServiceSpy = jasmine.createSpyObj('WorkspaceService', ['getConfiguration']);
toastServiceSpy = jasmine.createSpyObj('IntegrationsToastService', ['displayToastMessage']);

await TestBed.configureTestingModule({
declarations: [ IntacctBaseMappingComponent ]
})
.compileComponents();
declarations: [IntacctBaseMappingComponent],
providers: [
{ provide: ActivatedRoute, useValue: routeSpy },
{ provide: MappingService, useValue: mappingServiceSpy },
{ provide: WorkspaceService, useValue: workspaceServiceSpy },
{ provide: IntegrationsToastService, useValue: toastServiceSpy }
]
}).compileComponents();

fixture = TestBed.createComponent(IntacctBaseMappingComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});

it('should create', () => {
expect(component).toBeTruthy();
});
});

it('should initialize correctly', fakeAsync(() => {
workspaceServiceSpy.getConfiguration.and.returnValue(of(mockConfigurationResponse));
mappingServiceSpy.getMappingSettings.and.returnValue(of(mockMappingSettingsResponse as MappingSettingResponse));
mappingServiceSpy.getPaginatedDestinationAttributes.and.returnValue(of(mockDestinationAttributesResponse as PaginatedDestinationAttribute));

fixture.detectChanges();
tick();

expect(component.isLoading).toBeFalse();
expect(component.sourceField).toBe(FyleField.EMPLOYEE);
expect(component.destinationField).toBe('EMPLOYEE');
expect(component.destinationOptions).toEqual(mockDestinationAttributesResponse.results as DestinationAttribute[]);
expect(component.showAutoMapEmployee).toBeTrue();
}));

it('should handle category mapping', fakeAsync(() => {
routeSpy.params = of({ source_field: 'category' });
routeSpy.snapshot.params.source_field = 'category';

workspaceServiceSpy.getConfiguration.and.returnValue(of(mockConfigurationResponse));
JustARatherRidiculouslyLongUsername marked this conversation as resolved.
Show resolved Hide resolved
mappingServiceSpy.getMappingSettings.and.returnValue(of(mockMappingSettingsResponse as MappingSettingResponse));
mappingServiceSpy.getPaginatedDestinationAttributes.and.returnValue(of(mockDestinationAttributesResponse as PaginatedDestinationAttribute));

fixture.detectChanges();
tick();

expect(component.sourceField).toBe('CATEGORY');
expect(component.destinationField).toBe(IntacctCategoryDestination.ACCOUNT);
}));

it('should trigger auto map employees', () => {
mappingServiceSpy.triggerAutoMapEmployees.and.returnValue(of(null));
component.triggerAutoMapEmployees();

expect(component.isLoading).toBeFalse();
expect(toastServiceSpy.displayToastMessage).toHaveBeenCalledWith(ToastSeverity.INFO, 'Auto mapping of employees may take few minutes');
});

it('should handle error when triggering auto map employees', () => {
mappingServiceSpy.triggerAutoMapEmployees.and.returnValue(throwError(() => new Error('Error')));
component.triggerAutoMapEmployees();

expect(component.isLoading).toBeFalse();
expect(toastServiceSpy.displayToastMessage).toHaveBeenCalledWith(ToastSeverity.ERROR, 'Something went wrong, please try again');
});

Comment on lines +81 to +95
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

Ensure 'isLoading' state is properly managed

In the triggerAutoMapEmployees tests, component.isLoading is expected to be false after the operation. However, isLoading is never set to true before the operation starts. Consider setting component.isLoading = true; before triggering the method and updating the component code if necessary to reflect the loading state accurately.

Apply this change to set isLoading to true before the operation:

component.isLoading = true;
mappingServiceSpy.triggerAutoMapEmployees.and.returnValue(of(null));
component.triggerAutoMapEmployees();

Ensure the component method triggerAutoMapEmployees correctly manages the isLoading state.

Committable suggestion was skipped due to low confidence.

describe('getDestinationField', () => {
it('should return employee field mapping when source field is EMPLOYEE', () => {
component.sourceField = FyleField.EMPLOYEE;
const intacctConfiguration = { employee_field_mapping: 'EMPLOYEE' } as any;
const mappingSettings = [] as any;

const result = component['getDestinationField'](intacctConfiguration, mappingSettings);
expect(result).toBe('EMPLOYEE');
});

it('should return EXPENSE_TYPE when source field is CATEGORY and reimbursable_expenses_object is EXPENSE_REPORT', () => {
component.sourceField = FyleField.CATEGORY;
const intacctConfiguration = { reimbursable_expenses_object: IntacctReimbursableExpensesObject.EXPENSE_REPORT } as any;
const mappingSettings = [] as any;

const result = component['getDestinationField'](intacctConfiguration, mappingSettings);
expect(result).toBe(IntacctCategoryDestination.EXPENSE_TYPE);
});

it('should return EXPENSE_TYPE when source field is CATEGORY and corporate_credit_card_expenses_object is EXPENSE_REPORT', () => {
component.sourceField = FyleField.CATEGORY;
const intacctConfiguration = { corporate_credit_card_expenses_object: IntacctCorporateCreditCardExpensesObject.EXPENSE_REPORT } as any;
const mappingSettings = [] as any;

const result = component['getDestinationField'](intacctConfiguration, mappingSettings);
expect(result).toBe(IntacctCategoryDestination.EXPENSE_TYPE);
});

it('should return ACCOUNT when source field is CATEGORY and neither expenses_object is EXPENSE_REPORT', () => {
component.sourceField = FyleField.CATEGORY;
const intacctConfiguration = { reimbursable_expenses_object: 'OTHER', corporate_credit_card_expenses_object: 'OTHER' } as any;
const mappingSettings = [] as any;

const result = component['getDestinationField'](intacctConfiguration, mappingSettings);
expect(result).toBe(IntacctCategoryDestination.ACCOUNT);
});
});
});
Comment on lines +97 to +133
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Consider testing behavior through public methods instead of private methods

Testing private methods like getDestinationField ties your tests to the internal implementation, making refactoring more difficult. It's better to test the public methods or the overall behavior that relies on getDestinationField to ensure that changes in private methods do not require test modifications unless they affect external behavior.

Original file line number Diff line number Diff line change
@@ -1,23 +1,77 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';

import { provideRouter, Router, RouterModule } from '@angular/router';
import { of } from 'rxjs';
import { IntacctMappingComponent } from './intacct-mapping.component';
import { SiMappingsService } from 'src/app/core/services/si/si-core/si-mappings.service';
import { brandingConfig, brandingFeatureConfig } from 'src/app/branding/branding-config';
import { mockMappingSettingsResponse, mockMappingSettingsWithCustomFieldResponse } from '../../intacct.fixture';
import { MappingSettingResponse } from 'src/app/core/models/intacct/db/mapping-setting.model';
import { SharedModule } from 'src/app/shared/shared.module';

xdescribe('IntacctMappingComponent', () => {
describe('IntacctMappingComponent', () => {
let component: IntacctMappingComponent;
let router: Router;
let fixture: ComponentFixture<IntacctMappingComponent>;
let mappingServiceSpy: jasmine.SpyObj<SiMappingsService>;

beforeEach(async () => {
mappingServiceSpy = jasmine.createSpyObj('SiMappingsService', ['getMappingSettings']);

await TestBed.configureTestingModule({
declarations: [ IntacctMappingComponent ]
})
.compileComponents();
imports: [SharedModule, RouterModule.forRoot([])],
declarations: [ IntacctMappingComponent ],
providers: [
provideRouter([]),
{ provide: SiMappingsService, useValue: mappingServiceSpy }
]
}).compileComponents();

mappingServiceSpy.getMappingSettings.and.returnValue(of(mockMappingSettingsResponse as MappingSettingResponse));
brandingConfig.brandId = 'fyle';
brandingFeatureConfig.featureFlags.mapEmployees = true;

router = TestBed.inject(Router);
spyOn(router, 'navigateByUrl');

fixture = TestBed.createComponent(IntacctMappingComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});

it('should create', () => {
expect(component).toBeTruthy();
});
});

it('should initialize correctly', () => {
fixture.detectChanges();

expect(component.isLoading).toBeFalse();
expect(component.mappingPages.length).toBe(3);
expect(component.activeModule).toEqual(component.mappingPages[0]);
expect(router.navigateByUrl).toHaveBeenCalledWith('/integrations/intacct/main/mapping/employee');
});

it('should handle custom mapping fields', () => {
mappingServiceSpy.getMappingSettings.and.returnValue(of(mockMappingSettingsWithCustomFieldResponse as MappingSettingResponse));
fixture.detectChanges();

expect(component.mappingPages.length).toBe(4);
expect(component.mappingPages[3].label).toBe('Sample Custom Field');
expect(component.mappingPages[3].routerLink).toBe('/integrations/intacct/main/mapping/sample_custom_field');
});

it('should not include employee mapping when the feature is disabled', () => {
brandingFeatureConfig.featureFlags.mapEmployees = false;
fixture.detectChanges();

expect(component.mappingPages.length).toBe(2);
expect(component.mappingPages[0].label).not.toBe('Employee');
});

it('should handle different branding configurations', () => {
mappingServiceSpy.getMappingSettings.and.returnValue(of(mockMappingSettingsWithCustomFieldResponse as MappingSettingResponse));
brandingConfig.brandId = 'co';
fixture.detectChanges();

expect(component.mappingPages[3].label).toBe('Sample custom field');
});
});
Loading
Loading