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

🧪 improving rules test e2e stability #3512

Merged
merged 2 commits into from
Sep 27, 2024
Merged

Conversation

MatissJanis
Copy link
Member

@MatissJanis MatissJanis commented Sep 26, 2024

Continuing the missing of improving the stability of our e2e tests. Returning back to: rules.

See inline comment for explanation.

#3482

--

sample failure: https://github.com/actualbudget/actual/actions/runs/11041754845/job/30672775182?pr=3507

trace: trace.zip

@actual-github-bot actual-github-bot bot changed the title 🧪 improving rules test e2e stability [WIP] 🧪 improving rules test e2e stability Sep 26, 2024
Copy link
Contributor

coderabbitai bot commented Sep 26, 2024

Walkthrough

The pull request introduces significant changes across multiple files, primarily focusing on the management of schedule data within the application. It replaces the SchedulesQuery mechanism with a new useSchedules hook for fetching schedule data, modifies types to make certain properties optional, and updates function signatures accordingly. Additionally, the SchedulesQuery.ts file has been removed, consolidating the data-fetching logic into the new hook. Overall, these modifications streamline the handling of schedules in the application.

Changes

Files Change Summary
packages/desktop-client/src/components/ManageRules.tsx Added useSchedules hook, renamed ManageRulesContentProps to ManageRulesProps, updated function signature for ManageRules, and removed SchedulesQuery.Provider.
packages/desktop-client/src/components/reports/reports/CashFlow.tsx Made widget optional in CashFlowInnerProps, added error handling in onSaveWidget if widget is undefined.
packages/desktop-client/src/components/reports/reports/Spending.tsx Made widget optional in SpendingInternalProps, added error handling in onSaveWidget if widget is undefined.
packages/desktop-client/src/components/rules/ScheduleValue.tsx Replaced SchedulesQuery with useSchedules for fetching schedule data.
packages/desktop-client/src/components/rules/SchedulesQuery.ts Removed the SchedulesQuery file, which contained the logic for reactive schedule data retrieval.
packages/desktop-client/src/hooks/useSchedules.ts Introduced useSchedules hook for fetching schedule data using useQuery.
packages/loot-core/src/client/query-hooks.ts Added useLiveQuery and useQuery hooks for managing asynchronous data fetching and state management.
packages/loot-core/src/client/query-hooks.tsx Removed the old query-hooks.tsx file, which managed query states using context and hooks.

Possibly related PRs

  • 🧪 improving rules e2e test stability #3498: This PR modifies the mapValue function in ManageRules.tsx, which is directly related to the changes made in the main PR that also involves modifications to the ManageRules.tsx file.

Suggested labels

:sparkles: Merged

Suggested reviewers

  • joel-jeremy

📜 Recent review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between a269802 and 6ac3ae0.

📒 Files selected for processing (1)
  • packages/loot-core/src/client/query-hooks.ts (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/loot-core/src/client/query-hooks.ts

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.

Copy link

netlify bot commented Sep 26, 2024

Deploy Preview for actualbudget ready!

Name Link
🔨 Latest commit 6ac3ae0
🔍 Latest deploy log https://app.netlify.com/sites/actualbudget/deploys/66f5be5cccaf7d0008ce1640
😎 Deploy Preview https://deploy-preview-3512.demo.actualbudget.org
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify site configuration.

Copy link
Contributor

github-actions bot commented Sep 26, 2024

Bundle Stats — desktop-client

Hey there, this message comes from a GitHub action that helps you and reviewers to understand how these changes affect the size of this project's bundle.

As this PR is updated, I'll keep you updated on how the bundle size is impacted.

Total

Files count Total bundle size % Changed
9 5.29 MB → 5.29 MB (-1.46 kB) -0.03%
Changeset
File Δ Size
home/runner/work/actual/actual/packages/loot-core/src/client/query-hooks.ts 🆕 +701 B 0 B → 701 B
src/hooks/useSchedules.ts 🆕 +88 B 0 B → 88 B
src/components/reports/reports/CashFlow.tsx 📈 +81 B (+0.94%) 8.38 kB → 8.46 kB
src/components/reports/reports/Spending.tsx 📈 +81 B (+0.39%) 20.05 kB → 20.13 kB
node_modules/@react-spring/core/dist/react-spring_core.modern.mjs 📉 -4 B (-0.01%) 58.25 kB → 58.25 kB
src/components/rules/ScheduleValue.tsx 📉 -9 B (-1.91%) 471 B → 462 B
src/components/ManageRules.tsx 📉 -278 B (-3.15%) 8.61 kB → 8.34 kB
home/runner/work/actual/actual/packages/loot-core/src/client/query-hooks.tsx 🔥 -2.03 kB (-100%) 2.03 kB → 0 B
src/components/rules/SchedulesQuery.ts 🔥 -70 B (-100%) 70 B → 0 B
View detailed bundle breakdown

Added

No assets were added

Removed

No assets were removed

Bigger

Asset File Size % Changed
static/js/ReportRouter.js 1.5 MB → 1.5 MB (+162 B) +0.01%

Smaller

Asset File Size % Changed
static/js/index.js 3.31 MB → 3.31 MB (-1.61 kB) -0.05%

Unchanged

Asset File Size % Changed
static/js/resize-observer.js 18.37 kB 0%
static/js/indexeddb-main-thread-worker-e59fee74.js 13.5 kB 0%
static/js/AppliedFilters.js 20.97 kB 0%
static/js/BackgroundImage.js 122.29 kB 0%
static/js/usePreviewTransactions.js 1.64 kB 0%
static/js/narrow.js 82.1 kB 0%
static/js/wide.js 225.27 kB 0%

Copy link
Contributor

github-actions bot commented Sep 26, 2024

Bundle Stats — loot-core

Hey there, this message comes from a GitHub action that helps you and reviewers to understand how these changes affect the size of this project's bundle.

As this PR is updated, I'll keep you updated on how the bundle size is impacted.

Total

Files count Total bundle size % Changed
1 1.19 MB 0%

Changeset

No files were changed

View detailed bundle breakdown

Added

No assets were added

Removed

No assets were removed

Bigger

No assets were bigger

Smaller

No assets were smaller

Unchanged

Asset File Size % Changed
kcab.worker.js 1.19 MB 0%

const [allRules, setAllRules] = useState([]);
const [page, setPage] = useState(0);
const [filter, setFilter] = useState('');
const dispatch = useDispatch();

const { data: schedules } = SchedulesQuery.useQuery();
const { data: schedules = [] } = useSchedules();
Copy link
Member Author

Choose a reason for hiding this comment

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

This is the crux of the issue I believe.

The e2e test was trying to filter the schedules list BEFORE the schedules were loaded. So the schedules variable would be undefined. And this would blow up later in the call tree.

So I patched this by moving it to useSchedules (which uses useQuery). And also by adding a default value - empty array.

Every other change is just cleaning up stuff.. removing the usages of SchedulesQuery and all the code that this stuff used.

@@ -0,0 +1,53 @@
import { useState, useMemo, useEffect, type DependencyList } from 'react';
Copy link
Member Author

Choose a reason for hiding this comment

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

This is the same file as query-hooks.tsx. Except: removed makeContext (no longer used) and fixed some small strict TS issues (thus making this file strict TS).

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

🧹 Outside diff range and nitpick comments (9)
packages/desktop-client/src/hooks/useSchedules.ts (1)

5-7: LGTM: Hook implementation is concise and follows best practices.

The useSchedules hook is well-implemented using useQuery. However, consider the following suggestions for improvement:

  1. Instead of selecting all fields ('*'), consider specifying only the required fields for better performance.
  2. The empty dependency array means the query will only run once. Ensure this is the intended behavior.
  3. Consider adding error handling and loading state management, either in this hook or in the components using it.

Here's a potential refactor to address these points:

export function useSchedules() {
  return useQuery<ScheduleEntity[]>(
    () => q('schedules').select('id', 'name', 'frequency'), // Add specific fields
    [],
    {
      onError: (error) => {
        console.error('Failed to fetch schedules:', error);
        // Handle error (e.g., show a notification)
      },
    }
  );
}

Usage example in a component:

const { data: schedules, isLoading, error } = useSchedules();

if (isLoading) return <LoadingSpinner />;
if (error) return <ErrorMessage error={error} />;

// Render schedules
packages/desktop-client/src/components/rules/ScheduleValue.tsx (1)

19-19: LGTM: Improved data fetching with custom hook.

The switch to useSchedules hook for fetching schedules data is a good improvement. It aligns with modern React practices and potentially offers better performance and testability.

Consider adding type annotation for better type safety:

const { data: schedules } = useSchedules();

to:

const { data: schedules }: { data: ScheduleEntity[] } = useSchedules();

This ensures that schedules is correctly typed as an array of ScheduleEntity.

packages/loot-core/src/client/query-hooks.ts (2)

7-14: LGTM: Well-implemented deprecated function.

The useLiveQuery function is correctly implemented as a wrapper around useQuery. The deprecation notice in the JSDoc comment is clear and helpful.

Consider adding a runtime deprecation warning to encourage migration to useQuery:

export function useLiveQuery<Response = unknown>(
  makeQuery: () => Query,
  deps: DependencyList,
): Response | null {
  console.warn('Deprecated: useLiveQuery will be removed in a future version. Please use useQuery instead.');
  const { data } = useQuery<Response>(makeQuery, deps);
  return data;
}

16-53: LGTM: Well-implemented query hook with room for type safety improvement.

The useQuery hook is well-implemented, correctly handling async data fetching, loading state, and cleanup.

Consider improving type safety by using a generic constraint for the Query type:

export function useQuery<Response = unknown, Q extends Query = Query>(
  makeQuery: () => Q,
  deps: DependencyList,
): {
  data: null | Response;
  overrideData: (newData: Response) => void;
  isLoading: boolean;
} {
  // ... rest of the implementation
}

This change ensures that makeQuery returns a Query type while allowing for more specific query types to be used.

🧰 Tools
🪛 GitHub Check: lint

[warning] 26-26:
React Hook useMemo has a missing dependency: 'makeQuery'. Either include it or remove the dependency array

packages/desktop-client/src/components/reports/reports/CashFlow.tsx (1)

145-150: LGTM. Consider improving the error message.

The addition of a null check for the widget property is a good improvement that aligns with making the widget prop optional. It prevents potential runtime errors and improves the overall stability of the code.

Consider making the error message more specific:

- throw new Error('No widget that could be saved.');
+ throw new Error('Cannot save: widget is undefined.');

This change provides more context about the nature of the error, which could be helpful for debugging.

packages/desktop-client/src/components/ManageRules.tsx (3)

100-104: LGTM: Renamed type and made setLoading optional

The renaming of ManageRulesContentProps to ManageRulesProps and making setLoading optional improves the component's flexibility. This change is consistent with the summary provided.

Consider using the React.Dispatch<React.SetStateAction<boolean>> type for setLoading instead of the verbose Dispatch<SetStateAction<boolean>>. This would make the type more consistent with React's naming conventions.


116-116: LGTM: Use useSchedules hook for fetching schedules

The implementation of the useSchedules hook to fetch schedules data is a good improvement. It simplifies the component by removing the need for a separate query component.

Consider using the nullish coalescing operator (??) instead of the logical OR (||) for the default value. This would only use the empty array if data is null or undefined, not for other falsy values like an empty array.

const { data: schedules = [] } = useSchedules() ?? [];

Line range hint 1-359: Overall improvements to ManageRules component

The changes made to the ManageRules component consistently improve its structure and data management:

  1. The shift from SchedulesQuery to the useSchedules hook simplifies the component's data fetching logic.
  2. The renaming of types and updating of the function signature enhance clarity and flexibility.
  3. The removal of the SchedulesQuery.Provider wrapper aligns with the new hook-based approach.

These changes should result in a more maintainable and efficient component while preserving its core functionality.

Consider applying similar hook-based approaches to other data fetching operations in the component (e.g., rules, payees) if they aren't already implemented as such. This would further improve consistency and potentially simplify the component's logic.

packages/desktop-client/src/components/reports/reports/Spending.tsx (1)

136-141: LGTM: Improved error handling and type safety.

The addition of the null check for widget and the removal of the optional chaining operator are good improvements. They ensure that the function only proceeds with a valid widget and provide better error handling.

Consider using a custom error message to provide more context about where the error occurred. Here's a suggested improvement:

 if (!widget) {
-  throw new Error('No widget that could be saved.');
+  throw new Error('onSaveWidget: No widget available to save.');
 }
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between 4373f4d and a269802.

⛔ Files ignored due to path filters (1)
  • upcoming-release-notes/3512.md is excluded by !**/*.md
📒 Files selected for processing (8)
  • packages/desktop-client/src/components/ManageRules.tsx (2 hunks)
  • packages/desktop-client/src/components/reports/reports/CashFlow.tsx (2 hunks)
  • packages/desktop-client/src/components/reports/reports/Spending.tsx (2 hunks)
  • packages/desktop-client/src/components/rules/ScheduleValue.tsx (2 hunks)
  • packages/desktop-client/src/components/rules/SchedulesQuery.ts (0 hunks)
  • packages/desktop-client/src/hooks/useSchedules.ts (1 hunks)
  • packages/loot-core/src/client/query-hooks.ts (1 hunks)
  • packages/loot-core/src/client/query-hooks.tsx (0 hunks)
💤 Files not reviewed due to no reviewable changes (2)
  • packages/desktop-client/src/components/rules/SchedulesQuery.ts
  • packages/loot-core/src/client/query-hooks.tsx
🧰 Additional context used
🪛 GitHub Check: lint
packages/loot-core/src/client/query-hooks.ts

[warning] 26-26:
React Hook useMemo has a missing dependency: 'makeQuery'. Either include it or remove the dependency array

🔇 Additional comments (13)
packages/desktop-client/src/hooks/useSchedules.ts (2)

1-3: LGTM: Imports are appropriate and well-structured.

The imports are correctly bringing in the necessary dependencies and types for the hook's implementation. The use of type imports (ScheduleEntity) is a good practice for maintaining type safety.


1-7: Overall assessment: Good addition, aligns with PR objectives.

The introduction of the useSchedules hook is a positive addition to the project. It provides a consistent and reusable way to fetch schedule data, which can contribute to improving e2e test stability as mentioned in the PR objectives. The implementation follows React best practices and uses TypeScript for type safety.

While the current implementation is good, consider the suggestions in the previous comments for further optimization and robustness. These improvements could enhance the hook's performance and error handling capabilities, potentially further contributing to the stability of e2e tests.

packages/desktop-client/src/components/rules/ScheduleValue.tsx (2)

8-8: LGTM: Improved code organization with custom hook.

The introduction of the useSchedules custom hook is a good practice. It likely encapsulates the schedule fetching logic, promoting code reusability and separation of concerns.


Line range hint 1-31: Verify the impact on the wider project context.

The changes to this component improve code organization and potentially performance without altering its core behavior. This is a positive refactoring.

To ensure a smooth transition across the project:

  1. Verify that the SchedulesQuery import has been removed if it's no longer used.
  2. Check if other components that fetch schedules have been updated similarly.

Run the following script to verify these points:

This will help ensure consistency across the project and identify any remaining areas that might need updating.

packages/loot-core/src/client/query-hooks.ts (4)

1-1: LGTM: Appropriate React imports.

The imports from 'react' are correct and necessary for implementing the hooks in this file.


3-3: LGTM: Correct import for Query type.

The import of the Query type from the shared module is appropriate for type-checking.


5-5: LGTM: Essential imports for live query functionality.

The imports of liveQuery function and LiveQuery type are crucial for implementing the live query feature in this module.


1-53: Overall: Well-implemented query hooks with minor improvements suggested.

This new file introduces two React hooks, useLiveQuery and useQuery, which are well-implemented and provide the necessary functionality for managing asynchronous data fetching and state management. The code is clean, well-structured, and follows React best practices.

Key points:

  1. The deprecated useLiveQuery function is correctly implemented as a wrapper around useQuery.
  2. The main useQuery hook effectively manages data fetching, loading state, and cleanup.
  3. Proper use of TypeScript for type safety throughout the file.

Suggestions for improvement:

  1. Add a runtime deprecation warning to useLiveQuery.
  2. Fix the dependency array in the useMemo hook within useQuery.
  3. Consider enhancing type safety in useQuery with a generic constraint for the Query type.

These changes will further improve the robustness and maintainability of the code.

🧰 Tools
🪛 GitHub Check: lint

[warning] 26-26:
React Hook useMemo has a missing dependency: 'makeQuery'. Either include it or remove the dependency array

packages/desktop-client/src/components/reports/reports/CashFlow.tsx (2)

Line range hint 1-300: Summary: Changes align well with PR objectives

The modifications in this file, particularly making the widget prop optional and adding appropriate null checks, contribute to improving the stability of the code. These changes align well with the PR objective of enhancing e2e test stability for the "rules" component.

The increased flexibility in the CashFlowInner component and the added error handling make the code more robust, which should positively impact test reliability. Good job on these improvements!


61-61: LGTM. Verify component usage with this change.

Making the widget prop optional in CashFlowInnerProps is a good change that increases the flexibility of the CashFlowInner component. This change allows the component to be used in scenarios where a widget might not be available, which could improve test stability.

To ensure this change doesn't introduce any regressions, please run the following script to check all usages of CashFlowInner:

✅ Verification successful

Verified.
The widget prop for CashFlowInner is only used where it's provided, ensuring that making it optional does not introduce any issues.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Find all usages of CashFlowInner component
# Expected: All usages should handle the case where widget prop might be undefined

rg --type typescript --type tsx "CashFlowInner" -A 5 -B 5

Length of output: 92


Script:

#!/bin/bash
# Description: Find all usages of CashFlowInner component in .ts and .tsx files
# Expected: All usages should handle the case where widget prop might be undefined

rg --glob '*.ts' --glob '*.tsx' "CashFlowInner" -A 5 -B 5

Length of output: 1597

packages/desktop-client/src/components/ManageRules.tsx (2)

24-24: LGTM: Import useSchedules hook

The addition of the useSchedules hook import is consistent with the changes described in the summary. This change likely improves the management of schedule data within the component.


106-110: LGTM: Updated ManageRules function signature

The changes to the ManageRules function signature, including the addition of a default no-op function for setLoading, improve the component's usability and align with React best practices for optional callback props.

packages/desktop-client/src/components/reports/reports/Spending.tsx (1)

58-58: LGTM: Optional widget prop improves component flexibility.

The change to make the widget prop optional in SpendingInternalProps is a good improvement. It allows the SpendingInternal component to be used more flexibly, particularly during loading states or when no widget data is available.

To ensure this change doesn't introduce any issues, please verify that all uses of widget within the SpendingInternal component have appropriate null checks. Run the following script to find all occurrences of widget usage:

✅ Verification successful

Verified: All usages of widget include appropriate null checks.

The optional widget prop in SpendingInternalProps is correctly handled throughout the Spending.tsx file. All instances where widget is used incorporate necessary null checks, ensuring that the component handles cases where widget may be undefined without introducing runtime errors.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Find all occurrences of widget usage in SpendingInternal component

ast-grep --lang typescript --pattern 'function SpendingInternal($_) {
  $$$
  widget$_
  $$$
}'

Length of output: 97


Script:

#!/bin/bash
# Description: Search for all occurrences of 'widget' within SpendingInternal component using ripgrep

rg --ignore-case --no-heading --with-filename 'widget' packages/desktop-client/src/components/reports/reports/Spending.tsx

Length of output: 2498


Script:

#!/bin/bash
# Description: Find all usages of 'widget' in SpendingInternal component with flexible pattern

ast-grep --lang typescript --pattern $'const SpendingInternal = ($_): { $$$ widget$_ $$$ }' packages/desktop-client/src/components/reports/reports/Spending.tsx

Length of output: 505

packages/loot-core/src/client/query-hooks.ts Show resolved Hide resolved
@MatissJanis MatissJanis changed the title [WIP] 🧪 improving rules test e2e stability 🧪 improving rules test e2e stability Sep 26, 2024
Copy link
Contributor

@joel-jeremy joel-jeremy left a comment

Choose a reason for hiding this comment

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

LGTM!

let live: null | LiveQuery<Response> = liveQuery<Response>(
query,
async data => {
if (live) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Nice!

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

Successfully merging this pull request may close these issues.

2 participants