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

fix(hooks): support optimistic update for "upsert" #1767

Merged
merged 4 commits into from
Oct 9, 2024
Merged

Conversation

ymc9
Copy link
Member

@ymc9 ymc9 commented Oct 9, 2024

Fixes #1750

Copy link
Contributor

coderabbitai bot commented Oct 9, 2024

📝 Walkthrough
📝 Walkthrough

Walkthrough

The changes in this pull request introduce a new Jest configuration file for the TanStack Query plugin, establishing various testing parameters. Additionally, new test cases are added to the React Hooks testing suite to validate optimistic updates and upserts. Furthermore, a new upsert mutation operation is implemented in the applyMutation function, enhancing mutation capabilities by allowing conditional updates or creations based on existing records.

Changes

File Path Change Summary
packages/plugins/tanstack-query/jest.config.ts Introduced a new Jest configuration file with various testing parameters.
packages/plugins/tanstack-query/tests/react-hooks-v5.test.tsx
packages/plugins/tanstack-query/tests/react-hooks.test.tsx
Added new test cases for optimistic upsert operations: creating a new user and updating an existing user.
packages/runtime/src/cross/mutator.ts Added upsert operation to the applyMutation function, allowing conditional updates or creations.

Assessment against linked issues

Objective Addressed Explanation
Support optimistic updates for Upsert queries (#1750)

Possibly related PRs

  • fix(tanstack): infinite query typing issues #1480: The changes in this PR involve modifications to the test files in the packages/plugins/tanstack-query/tests directory, which are directly related to the new Jest configuration introduced in the main PR, as they both pertain to the testing framework and its setup.

📜 Recent review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between 6332434 and 3f1cc4c.

📒 Files selected for processing (2)
  • packages/plugins/tanstack-query/tests/react-hooks-v5.test.tsx (2 hunks)
  • packages/plugins/tanstack-query/tests/react-hooks.test.tsx (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • packages/plugins/tanstack-query/tests/react-hooks-v5.test.tsx
  • packages/plugins/tanstack-query/tests/react-hooks.test.tsx

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:

‼️ IMPORTANT
Auto-reply has been disabled for this repository in the CodeRabbit settings. The CodeRabbit bot will not respond to your replies unless it is explicitly tagged.

  • 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.

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: 3

🧹 Outside diff range and nitpick comments (4)
jest.config.ts (1)

36-36: LGTM! Consider adding a comment for clarity.

The addition of testEnvironment: 'jsdom' is appropriate for testing React hooks and components that interact with the DOM. This aligns well with the PR's focus on enhancing hook behavior, particularly for optimistic updates in upsert operations.

Consider adding a brief comment explaining the reason for using JSDOM, like this:

+    // Use JSDOM for testing React hooks and components that interact with the DOM
     testEnvironment: 'jsdom',

This will help future contributors understand the rationale behind this configuration choice.

packages/plugins/tanstack-query/tests/react-hooks-v5.test.tsx (1)

535-585: LGTM with a minor suggestion: Optimistic upsert - update test case

This test case effectively verifies the optimistic update behavior for an upsert operation that updates an existing record. The test structure, setup, and assertions are well-implemented.

One minor suggestion for improvement:
In the mutation call (line 577), the create object uses a different name ('zee') than the update object ('bar'). For consistency and to better reflect a real-world upsert scenario, consider using the same name in both objects:

- act(() => mutationResult.current.mutate({ ...queryArgs, update: { name: 'bar' }, create: { name: 'zee' } }));
+ act(() => mutationResult.current.mutate({ ...queryArgs, update: { name: 'bar' }, create: { name: 'bar' } }));

This change would make the test case more realistic, as typically in an upsert operation, you'd want to set the same data for both the update and create scenarios.

packages/plugins/tanstack-query/tests/react-hooks.test.tsx (2)

431-433: Remove unnecessary undefined arguments in useModelMutation calls

In the useModelMutation calls, the last argument is explicitly set to undefined, which is unnecessary. Omitting it enhances code readability without affecting functionality.

Update the code to remove the undefined arguments:

    useModelMutation(
        'User',
        'POST',
        makeUrl('User', 'upsert'),
        modelMeta,
        { optimisticUpdate: true, invalidateQueries: false },
-       undefined
    ),

Also applies to: 494-496


420-422: Clarify console log messages in mock responses

The console log message 'Not mutating data' may be misleading, as the test simulates an 'upsert' operation. Consider updating the log messages to accurately reflect the simulated operation.

Update the console logs for clarity:

-   console.log('Not mutating data');
+   console.log('Simulating upsert operation without server-side mutation');

Also applies to: 482-485

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between a800fe6 and 392cf9d.

📒 Files selected for processing (4)
  • jest.config.ts (1 hunks)
  • packages/plugins/tanstack-query/tests/react-hooks-v5.test.tsx (2 hunks)
  • packages/plugins/tanstack-query/tests/react-hooks.test.tsx (2 hunks)
  • packages/runtime/src/cross/mutator.ts (1 hunks)
🧰 Additional context used
🔇 Additional comments (4)
packages/plugins/tanstack-query/tests/react-hooks-v5.test.tsx (2)

475-533: LGTM: Comprehensive test for optimistic upsert - create scenario

This test case effectively verifies the optimistic update behavior for an upsert operation that creates a new record. The test setup, execution, and assertions are well-structured and cover the expected behavior.

A few observations:

  1. The test correctly mocks the initial empty state and the upsert API call.
  2. It uses the useModelMutation hook with appropriate options for optimistic updates.
  3. The assertions verify that the cache is updated optimistically with the new user data.

475-585: Excellent addition: Comprehensive coverage for optimistic upsert operations

The introduction of these two test cases for optimistic upsert operations significantly enhances the test suite's coverage. By testing both the create and update scenarios, these additions ensure that the optimistic update functionality for upsert operations is thoroughly validated.

These test cases:

  1. Align perfectly with the PR objectives of supporting optimistic updates for upsert hooks.
  2. Follow the established testing patterns, maintaining consistency within the test suite.
  3. Cover edge cases and verify the correct behavior of the cache updates.

This improvement in test coverage will help maintain the reliability and correctness of the optimistic update feature for upsert operations.

packages/plugins/tanstack-query/tests/react-hooks.test.tsx (2)

441-444: Verify optimistic upsert handles both create and update paths

Ensure that the optimistic upsert operation correctly handles both creating a new record and updating an existing one. Currently, the test focuses on creation; consider adding assertions to cover the update scenario as well.

Add assertions to confirm the cache state after an update operation:

// After mutation
expect(cacheData[0].name).toBe('bar'); // Verify update path

502-505: Ensure cache reflects updated data after optimistic upsert

In the 'optimistic upsert - update' test, verify that the cache correctly reflects the updated data (name: 'bar') after the optimistic upsert operation.

Confirm the cache data matches the expected updated values:

expect(cacheData).toMatchObject({ name: 'bar', $optimistic: true });

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.

Caution

Inline review comments failed to post

Actionable comments posted: 1

🧹 Outside diff range and nitpick comments (2)
packages/plugins/tanstack-query/jest.config.ts (2)

12-14: LGTM: Proper setup of global and test environment scripts.

The use of path.join() with __dirname ensures cross-platform compatibility, which is a good practice. The global setup and environment setup scripts are correctly referenced.

Consider extracting the common path segment '../../../script/' into a variable for better maintainability:

const scriptDir = path.join(__dirname, '../../../script');
export default {
  // ...
  globalSetup: path.join(scriptDir, 'test-global-setup.ts'),
  setupFiles: [path.join(scriptDir, 'set-test-env.ts')],
  // ...
};

16-29: LGTM: Comprehensive coverage configuration.

The coverage settings are well-configured:

  • Enabling coverage collection is crucial for maintaining code quality.
  • The coverage directory is appropriately set.
  • Ignoring node_modules and tests directories is standard practice.
  • The 'v8' coverage provider is suitable for Node.js environments.
  • The selection of coverage reporters provides a good mix of formats.

Consider adding a coverageThreshold setting to enforce minimum coverage requirements:

coverageThreshold: {
  global: {
    branches: 80,
    functions: 80,
    lines: 80,
    statements: 80
  }
},

This helps maintain a high standard of test coverage as the project evolves.

🛑 Comments failed to post (1)
packages/plugins/tanstack-query/jest.config.ts (1)

34-34: 💡 Codebase verification

Reduce testTimeout to Enhance Test Performance

The current testTimeout of 300,000 milliseconds (5 minutes) is significantly long for individual tests. Analysis reveals that some tests in prisma-pulse.test.ts utilize setTimeout with durations up to 10,000 milliseconds (10 seconds). While these delays may be necessary for certain operations, a 5-minute timeout could mask performance issues or lead to unnecessarily prolonged test runs.

Consider the following actions:

  • Lower the testTimeout to a more reasonable value, such as 60,000 milliseconds (1 minute), unless a longer duration is explicitly justified.
  • Refactor tests to minimize the use of fixed delays where possible, potentially leveraging async utilities or mocking timers.
  • Separate long-running tests into a distinct test suite with adjusted timeout settings to maintain overall test efficiency.
🔗 Analysis chain

Consider reducing the test timeout.

The current testTimeout of 300,000 milliseconds (5 minutes) is quite long for individual tests. While this might be necessary for complex integration tests or tests involving external services, it could potentially hide performance issues or infinite loops in tests.

Consider reducing this timeout unless there's a specific reason for such a long duration. If long-running tests are necessary, it might be beneficial to separate them into a different test suite with a longer timeout.

To help identify potentially slow tests, you can run the following command:

This command searches for test files that might contain long-running asynchronous tests or explicitly set timeouts.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Find test files with potentially long-running tests
rg --type typescript -g '*.test.ts' -g '*.spec.ts' -i '(timeout|done.*\).*=>)' -C 2

Length of output: 148


Script:

#!/bin/bash
# Find test files with potentially long-running tests without using --type
rg -g '*.test.ts' -g '*.spec.ts' -i '(timeout|done.*\).*=>)' -C 2

Length of output: 2957

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

Successfully merging this pull request may close these issues.

1 participant