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

Refactor sidebar hooks [SW-647] #4641

Merged
merged 12 commits into from
Dec 13, 2024
Merged

Refactor sidebar hooks [SW-647] #4641

merged 12 commits into from
Dec 13, 2024

Conversation

usame-algan
Copy link
Member

@usame-algan usame-algan commented Dec 11, 2024

What it solves

Part of SW-647

How this PR fixes it

  • Adds tests for useAllSafes
  • Removes the cache from useAllOwnedSafes as it is not needed anymore
  • Removes the sorting in useAllSafes since it is already done in MyAccounts
  • Moves useHasSafes into its own file

ToDos

  • Write more tests for useAllSafes
  • Write tests for buildSafeItem
  • Write tests for prepareAddresses
  • Refactor useAllSafes and split up the logic

Copy link

@usame-algan usame-algan changed the title Refactor sidebar hooks [SW-647] WIP: Refactor sidebar hooks [SW-647] Dec 11, 2024
Copy link

github-actions bot commented Dec 11, 2024

Copy link

github-actions bot commented Dec 11, 2024

📦 Next.js Bundle Analysis for safe-wallet-web

This analysis was generated by the Next.js Bundle Analysis action. 🤖

🎉 Global Bundle Size Decreased

Page Size (compressed)
global 1020.68 KB (🟢 -122 B)
Details

The global bundle is the javascript bundle that loads alongside every page. It is in its own category because its impact is much higher - an increase to its size means that every page on your website loads slower, and a decrease means every page loads faster.

Any third party scripts you have added directly to your app using the <script> tag are not accounted for in this analysis

If you want further insight into what is behind the changes, give @next/bundle-analyzer a try!

One Page Changed Size

The following page changed size from the code in this PR compared to its base branch:

Page Size (compressed) First Load
/welcome 6.92 KB (🟡 +119 B) 1 MB
Details

Only the gzipped size is provided here based on an expert tip.

First Load is the size of the global bundle plus the bundle for the individual page. If a user were to show up to your website and land on a given page, the first load size represents the amount of javascript that user would need to download. If next/link is used, subsequent page loads would only need to download that page's bundle (the number in the "Size" column), since the global bundle has already been downloaded.

Any third party scripts you have added directly to your app using the <script> tag are not accounted for in this analysis

Next to the size is how much the size has increased or decreased compared with the base branch of this PR. If this percentage has increased by 20% or more, there will be a red status indicator applied, indicating that special attention should be given to this.

Copy link

github-actions bot commented Dec 11, 2024

Coverage report

St.
Category Percentage Covered / Total
🟡 Statements
73.79% (+0.14% 🔼)
14389/19500
🔴 Branches
51.32% (+0.29% 🔼)
3433/6689
🔴 Functions
56.58% (+0.16% 🔼)
2033/3593
🟡 Lines
75.33% (+0.12% 🔼)
13055/17330

Test suite run success

1696 tests passing in 229 suites.

Report generated by 🧪jest coverage report action from 03c8136

@usame-algan usame-algan requested a review from jmealy December 12, 2024 09:45
@usame-algan usame-algan marked this pull request as ready for review December 12, 2024 09:45
@usame-algan usame-algan changed the title WIP: Refactor sidebar hooks [SW-647] Refactor sidebar hooks [SW-647] Dec 12, 2024
Copy link

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

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

Code review by ChatGPT

}))
})

it('returns an empty array if there is no wallet and allOwned is undefined', () => {

Choose a reason for hiding this comment

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

Consider implementing the buildSafeItem and prepareAddresses test cases soon to ensure the new functionality is correctly tested. Additionally, review current integration coverage to verify any untested edge cases.

const addedOnChain = Object.keys(allAdded[chainId] || {})
const ownedOnChain = allOwned[chainId] || []
const undeployedOnChain = Object.keys(allUndeployed[chainId] || {})

Choose a reason for hiding this comment

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

  1. Use consistent naming conventions for exported functions. Prefixing with an underscore is unconventional and might confuse maintainers.
  2. Consider memoization for _prepareAddresses and _buildSafeItem to avoid recomputation on rerender.
  3. Inline logic inside useAllSafes can be encapsulated into a separate utility function to enhance readability and maintainability.

const isPinned = Boolean(addedSafe) // Pinning a safe means adding it to the added safes storage

// Determine if the user is an owner
const isOwnerFromAdded = addedSafeOwners.some(({ value }) => sameAddress(walletAddress, value))
Copy link
Contributor

Choose a reason for hiding this comment

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

This is just for CF safes, right?

Copy link
Member Author

Choose a reason for hiding this comment

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

Good question. From what I can find is that we are using the isReadOnly flag for two things:

  1. To show the Add network button
  2. To show the queue actions

With that in mind I would expect the following behaviour:

CF Safes:

  • Show the Add network button if the connected wallet is an owner regardless of pinned state 🔴
  • No queue actions required

Owned Safes:

  • Show the Add network button regardless of pinned state ✅
  • Show the queue actions regardless of pinned state ✅

Added but not owned safes:

  • Show neither the Add network button nor the queue actions ✅

Anything I missed? I will implement the CF Safes case

Copy link
Contributor

Choose a reason for hiding this comment

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

That behaviour makes sense, thanks for clarifying!

Copy link
Contributor

@jmealy jmealy Dec 12, 2024

Choose a reason for hiding this comment

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

Good question. From what I can find is that we are using the isReadOnly flag for two things:

It's also used to display the read-only chip for the item in the safe list

Copy link

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

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

Code review by ChatGPT


const { result } = renderHook(() => useAllSafes(), {
initialReduxState: {
addedSafes: {

Choose a reason for hiding this comment

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

Consider factoring out repetitive mock object creation in your tests into reusable shared functions to adhere to DRY principles. This will streamline your test setup and improve maintainability, especially if more tests are added in the future.

Copy link

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

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

Code review by ChatGPT

'1': ['0x456', '0x789'],
}
jest.spyOn(allOwnedSafes, 'default').mockReturnValue([mockOwnedSafes, undefined, false])

Choose a reason for hiding this comment

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

Add mockAllUndeployed to the declarations at the start of the test suite if it's used across multiple tests for consistency. Extract repeated configuration and props setups into a helper function to adhere to DRY principles. Check if casting to UndeployedSafe['props'] is necessary.

export const useHasSafes = () => {
const { address = '' } = useWallet() || {}
const allAdded = useAddedSafes()
const hasAdded = !isEmpty(allAdded)

Choose a reason for hiding this comment

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

  1. Combining isOwnerFromAdded and isOwnerFromCF: Merge the logic of these two conditions if possible since both check ownership; this reduces redundancy.

  2. Consistent Naming: Ensure the term "CF" is well-documented or renamed for clarity if it's not a commonly understood term in this context.

  3. Function Complexity: _buildSafeItem contains several logic checks; consider breaking it into smaller functions for better readability and testability.

@usame-algan usame-algan requested a review from jmealy December 12, 2024 12:56
Copy link

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

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

Code review by ChatGPT

const ownedOnChain = allOwned[chainId] || []
const undeployedOnChain = Object.keys(allUndeployed[chainId] || {})

const combined = [...addedOnChain, ...ownedOnChain, ...undeployedOnChain]

Choose a reason for hiding this comment

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

  1. The initial setting of allOwned = {} implies it should never be undefined; verify that useAllOwnedSafes handles all cases to ensure reliability.
  2. Consider defining _prepareAddresses and _buildSafeItem as standalone functions outside the return statement to align with DRY and improve readability.

Copy link
Contributor

@jmealy jmealy left a comment

Choose a reason for hiding this comment

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

nice work 🚀

const isOwnedSafe = (allOwned[chainId] || []).includes(address)
const isOwned = isOwnedSafe || isOwnerFromAdded
const isOwned = isOwnedSafe || isOwnerFromAdded || isOwnerFromCF
Copy link
Contributor

Choose a reason for hiding this comment

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

I think isOwnerFromAdded is not needed anymore. If it's deployed we check ownership from allOwned, if it's CF we check ownership from allUndeployed, so isOwnerFromAdded is redundant

Copy link
Member Author

Choose a reason for hiding this comment

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

Very true, nice catch!

@usame-algan usame-algan merged commit 49dfe62 into dev Dec 13, 2024
15 checks passed
@usame-algan usame-algan deleted the sidebar-refactor branch December 13, 2024 10:22
@github-actions github-actions bot locked and limited conversation to collaborators Dec 13, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants