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

Conversation

JustARatherRidiculouslyLongUsername
Copy link
Contributor

@JustARatherRidiculouslyLongUsername JustARatherRidiculouslyLongUsername commented Sep 26, 2024

Clickup

https://app.clickup.com/t/86cwh86c6

Summary by CodeRabbit

  • Tests
    • Enhanced test coverage for the IntacctBaseMappingComponent and IntacctMappingComponent with new test cases for initialization, category mapping, and auto-mapping functionalities.
    • Improved robustness of tests by simulating various scenarios and conditions, including custom fields and branding configurations.
    • Introduced new mock data structures to facilitate comprehensive testing of Intacct integration features.

Copy link
Contributor

coderabbitai bot commented Sep 26, 2024

Walkthrough

The changes involve enhancements to the test suites for the IntacctBaseMappingComponent and IntacctMappingComponent, including the addition of multiple test cases and mock data structures in the intacct.fixture.ts file. The test setups have been improved to cover various functionalities and edge cases, ensuring comprehensive testing of the Intacct integration components.

Changes

File Path Change Summary
src/app/integrations/intacct/.../intacct-base-mapping.component.spec.ts Added multiple test cases for the IntacctBaseMappingComponent, including initialization and mapping tests.
src/app/integrations/intacct/.../intacct-mapping.component.spec.ts Enhanced the test suite for IntacctMappingComponent with new test cases and improved test setup.
src/app/integrations/intacct/intacct.fixture.ts Introduced new mock data structures and constants to support comprehensive testing scenarios.

Possibly related PRs

Suggested labels

size/XL, deploy, c1_staging_deploy

Suggested reviewers

  • DhaaraniCIT
  • ashwin1111

Poem

In the land of code where rabbits play,
Tests are hopping in a grand array.
With mocks and checks, they leap and bound,
Ensuring all functions are safe and sound.
So let’s celebrate this joyful spree,
For testing brings us harmony! 🐇✨


Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@github-actions github-actions bot added the size/L Large PR label Sep 26, 2024
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 6

🧹 Outside diff range and nitpick comments (5)
src/app/integrations/intacct/intacct-main/intacct-mapping/intacct-mapping.component.spec.ts (5)

11-34: LGTM: Comprehensive test suite setup with a minor suggestion.

The test suite setup is well-structured and covers all necessary aspects for thorough testing. The use of spies, mocks, and router setup is appropriate for unit testing.

Consider extracting the mock data initialization (lines 29-31) into a separate beforeEach block or a setup function. This would improve readability and make it easier to modify these values for specific tests if needed in the future.

let mockMappingSettings: MappingSettingResponse;

beforeEach(() => {
  mockMappingSettings = {...mockMappingSettingsResponse};
  mappingServiceSpy.getMappingSettings.and.returnValue(of(mockMappingSettings));
  brandingConfig.brandId = 'fyle';
  brandingFeatureConfig.featureFlags.mapEmployees = true;
});

53-60: LGTM: Effective custom mapping fields test with a suggestion.

This test case successfully verifies the component's ability to handle custom mapping fields. The use of a specific mock response and the expectations covering the number of mapping pages and custom field properties are appropriate.

Consider adding an expectation to verify that the existing mapping pages are still present and in the correct order. This would ensure that adding custom fields doesn't disrupt the standard mapping pages.

expect(component.mappingPages[0].label).toBe('Employee');
expect(component.mappingPages[1].label).toBe('Category');
expect(component.mappingPages[2].label).toBe('Project');

62-68: LGTM: Good test for feature flag handling with a suggestion.

This test case effectively verifies the component's behavior when the employee mapping feature is disabled. It correctly checks the number of mapping pages and the absence of the employee mapping page.

To make the test more robust, consider adding expectations to verify the labels of the remaining mapping pages. This ensures that disabling the employee mapping feature doesn't affect other mapping pages.

expect(component.mappingPages[0].label).toBe('Category');
expect(component.mappingPages[1].label).toBe('Project');

70-76: LGTM: Good test for branding configurations with suggestions for improvement.

This test case effectively verifies the component's response to different branding configurations, particularly in handling custom field labels.

Consider the following improvements to make the test more comprehensive:

  1. Add expectations for standard mapping pages to ensure they're not affected by branding changes.
  2. Test multiple brand IDs to ensure consistent behavior across different brands.
  3. Consider extracting the branding-specific logic into a separate function for better maintainability.

Here's an example of how you could implement these suggestions:

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

    expect(component.mappingPages[0].label).toBe('Employee');
    expect(component.mappingPages[1].label).toBe('Category');
    expect(component.mappingPages[2].label).toBe('Project');
    expect(component.mappingPages[3].label).toBe(expectedLabel);
  };

  testBranding('co', 'Sample custom field');
  testBranding('fyle', 'Sample Custom Field');
  // Add more brand IDs as needed
});

This refactored version provides more comprehensive testing across different brands and ensures that both standard and custom mapping pages are correctly handled.


1-77: Great job on the comprehensive test suite!

The test suite for the IntacctMappingComponent is well-structured and covers crucial aspects of the component's behavior, including initialization, custom fields handling, feature flag responses, and branding configurations. The use of mocks and spies effectively isolates the component for proper unit testing.

To further enhance the test suite, consider the following suggestions:

  1. Add edge cases: Test scenarios with empty or malformed responses from the mapping service.
  2. Error handling: Verify the component's behavior when the mapping service throws an error.
  3. User interactions: If the component has any user interactions (e.g., changing active modules), add tests for these scenarios.
  4. Asynchronous behavior: Ensure that any asynchronous operations are properly tested, possibly using fakeAsync or async/await patterns.

Example for testing error handling:

it('should handle errors from the mapping service', fakeAsync(() => {
  mappingServiceSpy.getMappingSettings.and.returnValue(throwError(() => new Error('Service error')));
  fixture.detectChanges();
  tick();

  expect(component.isLoading).toBeFalse();
  expect(component.error).toBeTruthy();
  // Add more expectations based on how your component handles errors
}));

These additions would make the test suite even more robust and comprehensive.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between b6233f5 and e4fdd45.

📒 Files selected for processing (3)
  • src/app/integrations/intacct/intacct-main/intacct-mapping/intacct-base-mapping/intacct-base-mapping.component.spec.ts (1 hunks)
  • src/app/integrations/intacct/intacct-main/intacct-mapping/intacct-mapping.component.spec.ts (1 hunks)
  • src/app/integrations/intacct/intacct.fixture.ts (2 hunks)
🧰 Additional context used
🪛 Biome
src/app/integrations/intacct/intacct.fixture.ts

[error] 3-3: Do not shadow the global "Error" property.

Consider renaming this variable. It's easy to confuse the origin of variables when they're named after a known global.

(lint/suspicious/noShadowRestrictedNames)

🔇 Additional comments (8)
src/app/integrations/intacct/intacct-main/intacct-mapping/intacct-mapping.component.spec.ts (2)

2-9: LGTM: Imports and setup are appropriate.

The new imports are well-chosen and necessary for the enhanced test suite. They provide the required dependencies for routing, services, branding configuration, and mock data.


44-51: LGTM: Comprehensive initialization test.

This test case effectively verifies the initial state of the component, including loading state, mapping pages, active module, and navigation. The expectations are clear and cover crucial aspects of the component's initialization.

src/app/integrations/intacct/intacct.fixture.ts (6)

50-55: Well-structured mock data for mockTasksInProgress

The mockTasksInProgress object is correctly defined and will enhance the comprehensiveness of unit tests for tasks in progress scenarios.


58-64: Well-structured mock data for mockCompletedTasksWithFailures

The mockCompletedTasksWithFailures object is properly set up and will be valuable for testing scenarios involving completed tasks with failures.


65-120: Comprehensive mock export settings in mockExportSettingGet

The mockExportSettingGet object provides detailed configurations for export settings, which will aid in thorough testing of various export scenarios.


123-134: Accurate mock export details in mockExportDetails

The mockExportDetails object is well-defined, offering a clear summary of accounting exports. This will be beneficial for testing export summaries.


136-239: Detailed mock tasks data in mockTasks

The mockTasks array contains detailed task objects with various statuses and types, which will enhance the robustness of task-related unit tests.


245-278: Well-defined mock configuration in mockConfiguration

The mockConfiguration object is comprehensive and includes various settings that will assist in testing different configuration scenarios.

Comment on lines +97 to +133
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);
});
});
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.

Comment on lines +81 to +95
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');
});
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.

Comment on lines +293 to +298
export const mockErrors = [
{ id: 1, type: AccountingErrorType.EMPLOYEE_MAPPING, error_title: 'Employee mapping error' },
{ id: 2, type: AccountingErrorType.CATEGORY_MAPPING, error_title: 'Category mapping error' },
{ id: 3, type: AccountingErrorType.ACCOUNTING_ERROR, error_title: 'Accounting error' }
] as Error[];
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

Consider renaming the Error type in mock errors

Similar to the import issue, using Error as a type here can cause confusion with the global Error object. Recommend renaming it to AccountingError for clarity.

Apply the following diff to rename the type:

-export const mockErrors = [
+export const mockErrors: AccountingError[] = [
   { id: 1, type: AccountingErrorType.EMPLOYEE_MAPPING, error_title: 'Employee mapping error' },
   { id: 2, type: AccountingErrorType.CATEGORY_MAPPING, error_title: 'Category mapping error' },
   { id: 3, type: AccountingErrorType.ACCOUNTING_ERROR, error_title: 'Accounting error' }
-] as Error[];
+];
📝 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
export const mockErrors = [
{ id: 1, type: AccountingErrorType.EMPLOYEE_MAPPING, error_title: 'Employee mapping error' },
{ id: 2, type: AccountingErrorType.CATEGORY_MAPPING, error_title: 'Category mapping error' },
{ id: 3, type: AccountingErrorType.ACCOUNTING_ERROR, error_title: 'Accounting error' }
] as Error[];
export const mockErrors: AccountingError[] = [
{ id: 1, type: AccountingErrorType.EMPLOYEE_MAPPING, error_title: 'Employee mapping error' },
{ id: 2, type: AccountingErrorType.CATEGORY_MAPPING, error_title: 'Category mapping error' },
{ id: 3, type: AccountingErrorType.ACCOUNTING_ERROR, error_title: 'Accounting error' }
];

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
size/L Large PR
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants