Skip to content

BREAKING Adds messenger to token controller#1166

Merged
bergarces merged 9 commits intomainfrom
token-controller-messenger
Apr 18, 2023
Merged

BREAKING Adds messenger to token controller#1166
bergarces merged 9 commits intomainfrom
token-controller-messenger

Conversation

@bergarces
Copy link
Copy Markdown
Contributor

@bergarces bergarces commented Apr 5, 2023

BREAKING Adds messenger to token controller

Description

Adds a messenger to TokensController so that the confirmation can be triggered by sending a message to ApprovalController.

  • BREAKING:

    • The new messenger field in the constructor introduces a breaking change.
  • CHANGED:

    • It uses ApprovalController messages to initiate and complete the request instead of an event.

Checklist

  • Tests are included if applicable
  • Any added code is fully documented

Issue

Resolves https://github.com/MetaMask/MetaMask-planning/issues/409

@bergarces bergarces force-pushed the token-controller-messenger branch 2 times, most recently from 80cf8ad to 33e207d Compare April 5, 2023 19:09
@bergarces bergarces changed the title Add messenger to token controller Adds messenger to token controller Apr 5, 2023
@bergarces bergarces changed the title Adds messenger to token controller BREAKING Adds messenger to token controller Apr 5, 2023
@bergarces bergarces marked this pull request as ready for review April 5, 2023 19:22
@bergarces bergarces requested a review from a team as a code owner April 5, 2023 19:22
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Any chance we could provide a real messenger object instead of nothing? We'd like to avoid using any across the monorepo if we can, even in tests.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I've created real messenger objects for those tests to avoid use of any.

Having said that, I don't think it's going to be scalable if we have to instantiate real dependencies instead of mocking them. If we are instantiating real TokensController with real messengers for other controllers, these are no longer unit tests.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Is there a compromise where we can still provide a mock for these arguments to reduce coupling, but cast to the correct type rather than any, so a as unknown as TokensControllerMessenger?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I've pushed another commit with the as unknown as TokensControllerMessenger. The messenger is not even used during those tests, so it's set to undefined.

We should not have to use real object instantiations on unit tests when that is not the subject of the test.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I see what you mean, but I'm not so sure that using a real messenger would make this an integration test. Unless we're using it to talk to another controller — that would be unnecessary. But if we're just using it to satisfy the argument, then I don't see why we can't use a real one.

Copy link
Copy Markdown
Member

@matthewwalsh0 matthewwalsh0 Apr 12, 2023

Choose a reason for hiding this comment

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

I'd argue it's just a matter of future-proofing and minimising the code being executed in the test for the sake of avoiding fragility and ensuring we're testing a isolated unit whenever possible, rather than dependency code, in this case the ControllerMessenger.

As an example, if we were to change the code in future to invoke a method in the TokensController from the TokenBalancesController that did use the messenger, any related errors in the messenger code would needlessly cause the TokenBalancesController tests to fail and they would be harder to diagnose as the errors would be originating from code the test wasn't intending to validate.

There's also a performance argument with this pattern if we're consistently loading additional dependencies and code that isn't functionally required for a test.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This change seems fine to me as a short-term fix because the tests shouldn't have a TokenController in the fist place, but fixing that would be out-of-scope of this PR.

But in general I would recommend using a real controller messenger in tests, if only because it's such a simple construct that mocking it would add complexity. The messenger is meant as a way of doing dependency injection, it's a way for us to pass mocks into the code under test.

It's the use of additional controllers that aren't under test that makes this example needlessly complex. Not the messenger. In your example here @matthewwalsh0 you seem to be talking about one such case. I don't think @mcmire meant to suggest that using real controllers that aren't under-test is a good idea.

@bergarces bergarces force-pushed the token-controller-messenger branch from 33e207d to 0c0e8bf Compare April 6, 2023 08:06
Comment thread packages/assets-controllers/src/TokenBalancesController.test.ts Outdated
Comment thread packages/assets-controllers/src/TokensController.ts Outdated
Comment thread packages/assets-controllers/src/TokensController.ts Outdated
Comment thread packages/assets-controllers/src/TokensController.ts Outdated
@bergarces bergarces force-pushed the token-controller-messenger branch from 2c4f33f to 8a1d2b9 Compare April 11, 2023 13:46
matthewwalsh0
matthewwalsh0 previously approved these changes Apr 12, 2023
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I had to remove the line that updates status directly (suggestedAssetMeta.status = SuggestedAssetStatus.accepted;) and replace it by a new object using the spread operator, as otherwise that line throws a read error when using this controller in mobile codebase with react-native.

Attempted to assign to readonly property

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Same as with the previous one, I had to create a new object instead of updating status directly to prevent an error in react-native codebase.

@bergarces bergarces requested a review from matthewwalsh0 April 14, 2023 14:03
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

For mobile, we will need requestData to be populated with the following values, as it currently relies on the suggestedAssetMeta object sent by the pendingSuggestedAsset event.

Unfortunately, the type SuggestedAssetMeta is not compatible with requestData as it has several optional and an unknown field within the Token type, so we are sending precisely the data it needs.

@bergarces bergarces force-pushed the token-controller-messenger branch from 101114c to b0ff768 Compare April 16, 2023 19:39
matthewwalsh0
matthewwalsh0 previously approved these changes Apr 17, 2023
vinistevam
vinistevam previously approved these changes Apr 18, 2023
@bergarces bergarces dismissed stale reviews from vinistevam and matthewwalsh0 via 77afb2f April 18, 2023 09:48
@bergarces bergarces merged commit 1970dc1 into main Apr 18, 2023
@bergarces bergarces deleted the token-controller-messenger branch April 18, 2023 11:15
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.

5 participants