diff --git a/app/core/AppConstants.ts b/app/core/AppConstants.ts index 33d22389490..649b22457c5 100644 --- a/app/core/AppConstants.ts +++ b/app/core/AppConstants.ts @@ -222,5 +222,6 @@ export default { FEATURE_FLAGS_API: { BASE_URL: 'https://client-config.api.cx.metamask.io', VERSION: 'v1', + DEFAULT_FETCH_INTERVAL: 15 * 60 * 1000, // 15 minutes }, } as const; diff --git a/app/core/Engine/controllers/RemoteFeatureFlagController/types.ts b/app/core/Engine/controllers/RemoteFeatureFlagController/types.ts index d7f68a42f21..509c7bbf173 100644 --- a/app/core/Engine/controllers/RemoteFeatureFlagController/types.ts +++ b/app/core/Engine/controllers/RemoteFeatureFlagController/types.ts @@ -5,5 +5,6 @@ export interface RemoteFeatureFlagInitParamTypes { messenger: RemoteFeatureFlagControllerMessenger; disabled: boolean; getMetaMetricsId: () => string; + fetchInterval?: number; } diff --git a/app/core/Engine/controllers/RemoteFeatureFlagController/utils.test.ts b/app/core/Engine/controllers/RemoteFeatureFlagController/utils.test.ts index add22ad2184..ed0c5522a3e 100644 --- a/app/core/Engine/controllers/RemoteFeatureFlagController/utils.test.ts +++ b/app/core/Engine/controllers/RemoteFeatureFlagController/utils.test.ts @@ -6,6 +6,19 @@ import { import { createRemoteFeatureFlagController } from './utils'; import { v4 as uuidv4 } from 'uuid'; +const mockUpdateRemoteFeatureFlags = jest.fn().mockResolvedValue(undefined); + +jest.mock('@metamask/remote-feature-flag-controller', () => { + const originalModule = jest.requireActual('@metamask/remote-feature-flag-controller'); + return { + ...originalModule, + RemoteFeatureFlagController: jest.fn().mockImplementation((params) => ({ + updateRemoteFeatureFlags: mockUpdateRemoteFeatureFlags, // Ensures it returns a resolved promise + ...params, // Ensure that fetchInterval and other params are stored + })), + }; +}); + describe('RemoteFeatureFlagController utils', () => { let messenger: RemoteFeatureFlagControllerMessenger; @@ -16,47 +29,8 @@ describe('RemoteFeatureFlagController utils', () => { }); describe('createRemoteFeatureFlagController', () => { - it('creates controller with initial undefined state', () => { - const controller = createRemoteFeatureFlagController({ - state: undefined, - messenger, - disabled: false, - getMetaMetricsId: () => uuidv4(), - }); - - expect(controller).toBeDefined(); - - // Initializing with am empty object should return an empty obj? - expect(controller.state).toStrictEqual({ - cacheTimestamp: 0, - remoteFeatureFlags: {}, - }); - }); - - it('internal state matches initial state', () => { - const initialState = { - remoteFeatureFlags: { - testFlag: true, - }, - cacheTimestamp: 123, - }; - - const controller = createRemoteFeatureFlagController({ - state: initialState, - messenger, - disabled: false, - getMetaMetricsId: () => uuidv4(), - }); - - expect(controller.state).toStrictEqual(initialState); - }); it('calls updateRemoteFeatureFlags when enabled', () => { - const spy = jest.spyOn( - RemoteFeatureFlagController.prototype, - 'updateRemoteFeatureFlags', - ); - createRemoteFeatureFlagController({ state: undefined, messenger, @@ -64,15 +38,10 @@ describe('RemoteFeatureFlagController utils', () => { getMetaMetricsId: () => uuidv4(), }); - expect(spy).toHaveBeenCalled(); + expect(mockUpdateRemoteFeatureFlags).toHaveBeenCalled(); }); it('does not call updateRemoteFeatureFlagscontroller when controller is disabled', () => { - const spy = jest.spyOn( - RemoteFeatureFlagController.prototype, - 'updateRemoteFeatureFlags', - ); - createRemoteFeatureFlagController({ state: undefined, messenger, @@ -80,27 +49,25 @@ describe('RemoteFeatureFlagController utils', () => { getMetaMetricsId: () => uuidv4(), }); - expect(spy).not.toHaveBeenCalled(); + expect(mockUpdateRemoteFeatureFlags).not.toHaveBeenCalled(); }); - it('controller keeps initial extra data into its state', () => { - const initialState = { - extraData: true, - }; + it('passes fetchInterval to RemoteFeatureFlagController', async () => { + const fetchInterval = 6000; - const controller = createRemoteFeatureFlagController({ - // @ts-expect-error giving a wrong initial state - state: initialState, + createRemoteFeatureFlagController({ + state: undefined, messenger, disabled: false, getMetaMetricsId: () => uuidv4(), + fetchInterval, }); - expect(controller.state).toStrictEqual({ - cacheTimestamp: 0, - extraData: true, - remoteFeatureFlags: {}, - }); + // Ensure the constructor was called with fetchInterval + expect(RemoteFeatureFlagController).toHaveBeenCalledWith( + expect.objectContaining({ fetchInterval }) + ); }); + }); }); diff --git a/app/core/Engine/controllers/RemoteFeatureFlagController/utils.ts b/app/core/Engine/controllers/RemoteFeatureFlagController/utils.ts index 0e4dac6c947..baf9b976ddb 100644 --- a/app/core/Engine/controllers/RemoteFeatureFlagController/utils.ts +++ b/app/core/Engine/controllers/RemoteFeatureFlagController/utils.ts @@ -9,6 +9,7 @@ import { import Logger from '../../../../util/Logger'; import { RemoteFeatureFlagInitParamTypes } from './types'; +import AppConstants from '../../../AppConstants'; const getFeatureFlagAppEnvironment = () => { const env = process.env.METAMASK_ENVIRONMENT; @@ -34,6 +35,7 @@ export const createRemoteFeatureFlagController = ({ messenger, disabled, getMetaMetricsId, + fetchInterval = AppConstants.FEATURE_FLAGS_API.DEFAULT_FETCH_INTERVAL, }: RemoteFeatureFlagInitParamTypes) => { const remoteFeatureFlagController = new RemoteFeatureFlagController({ messenger, @@ -48,6 +50,7 @@ export const createRemoteFeatureFlagController = ({ distribution: getFeatureFlagAppDistribution(), }, }), + fetchInterval, }); if (disabled) {