-
-
Notifications
You must be signed in to change notification settings - Fork 188
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
feat(27254): implement new remote-feature-flag-controller #4931
base: main
Are you sure you want to change the base?
Conversation
78af7f4
to
cd93f7a
Compare
No dependency changes detected. Learn more about Socket for GitHub ↗︎ 👍 No dependency changes detected in pull request |
cd93f7a
to
82f7997
Compare
78ca22b
to
a7a3cf1
Compare
0519340
to
fcc71a0
Compare
@metamaskbot publish-preview |
Preview builds have been published. See these instructions for more information about preview builds. Expand for full list of packages and versions.
|
153ebc9
to
0fab160
Compare
993bda6
to
63c3764
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi @DDDDDanica, nice job in creating this controller! This looks really nice. A lot of my comments were minor, to make tests more readable and that sort of thing. I think there might be one missing test.
.idea/core.iml
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thoughts on adding these .idea
files in another commit? I'm not sure what they are. Perhaps they are useful, but another PR would give us a place to explain.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), | ||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). | ||
|
||
## [0.1.0] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There are two kinds of sections in each changelog: one for each version that's been released so far, and then an "Unreleased" section for change that haven't shown up in a release yet. For new packages, there aren't any versions released, so all we should have here is an "Unreleased" section:
## [0.1.0] | |
## [Unreleased] |
@@ -0,0 +1,15 @@ | |||
# `@metamask/example-controllers` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should update this to reflect the name of the package:
# `@metamask/example-controllers` | |
# `@metamask/remote-feature-flag-controller` |
@@ -0,0 +1,15 @@ | |||
# `@metamask/example-controllers` | |||
|
|||
This package is designed to illustrate best practices for controller packages and controller files, including tests. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there a description you can give this package? Here's the one you gave in package.json
:
This package is designed to illustrate best practices for controller packages and controller files, including tests. | |
Controller with caching, fallback, and privacy for managing feature flags via ClientConfigAPI. |
@@ -0,0 +1,70 @@ | |||
{ | |||
"name": "@metamask/remote-feature-flag-controller", | |||
"version": "0.0.1", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
New packages start out at 0.0.0. We will assign a new version when we release the package:
"version": "0.0.1", | |
"version": "0.0.0", |
disabled: true, | ||
}); | ||
|
||
controller.enable(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: Your setup for this test mirrors how consumers might use this method along with other methods in the API for this controller, so it makes sense you wrote it this way. But remember that when you instantiate the controller you can specify whatever initial state or options you want. So you don't need to necessarily call enable
to enable the controller; if you already know that enable
sets disabled
to false
— and you should have a test which confirms this — would it still make sense to pass disabled: false
instead?
expect(result2).toStrictEqual(mockFlags); | ||
}); | ||
|
||
it('should emit state change when updating cache', async () => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you think this test is necessary? The fact that stateChange
gets emitted when state is updated is already built in to BaseController, and we have tests for this there. So could we trust that this already happens?
}); | ||
}); | ||
|
||
it('should initialize with disabled parameter', () => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is being tested? If we really want to test the state, should we be more clear?
it('should initialize with disabled parameter', () => { | |
it('should initialize the controller with default state if the disabled parameter is provided', () => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, should we add a test which verifies that you can override any part of state?
}); | ||
|
||
it('should get feature flags from API when cache is invalid', async () => { | ||
const controller = createController({ clientConfigApiService }); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What in this test is making the cache invalid?
If it's the default data that we are having the service object return, what are your thoughts on including that data in this test? Otherwise it's not totally clear. Something like:
const controller = createController({ clientConfigApiService }); | |
const controller = createController({ clientConfigApiService }); | |
jest | |
.spyOn(clientConfigApiService, 'fetchFlags') | |
.mockImplementation(async () => ({ | |
error: false, | |
message: 'Success', | |
statusCode: '200', | |
statusText: 'OK', | |
cachedData: { differentFlag: true }, | |
cacheTimestamp: Date.now(), | |
})); |
expect(remoteFeatureFlags).toStrictEqual(mockFlags); | ||
}); | ||
|
||
it('should handle concurrent flag updates', async () => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see we have a test which verifies if getRemoteFeatureFlags
is called more than one without awaiting then the invocations get resolved in the order in which they occurred. However, what about a test which simulates calling getRemoteFeatureFlags
twice, awaiting at each step, and waiting an appropriate amount in between so that the second call creates another fetch? This would essentially verify that #inProgressFlagUpdate
gets cleared at the end of the method.
|
||
### Added | ||
|
||
- Initial release |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's best if every changelog entry has a link to the PR that introduced this change. In this case, it's this very PR that introduces the package. So, how about:
- Initial release | |
- Initial release ([#4931](https://github.com/MetaMask/core/pull/4931)) |
63c3764
to
2878ef6
Compare
Explanation
Following the ADR here
Adds a new controller,
remote-feature-flag-controller
that fetches the remote feature flags and provide cache solution for consumers.References
Related to #67890
Changelog
@metamask/remote-feature-flag-controller
ADDED: Initial release
Checklist