Skip to content

Commit

Permalink
feat(27254): flattern data applied to controller
Browse files Browse the repository at this point in the history
  • Loading branch information
DDDDDanica committed Nov 28, 2024
1 parent 2c8eb1f commit d6a3839
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 67 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -14,17 +14,12 @@ import type {
} from './remote-feature-flag-controller';
import type { FeatureFlags } from './remote-feature-flag-controller-types';

const MOCK_FLAGS: FeatureFlags = [
{ feature1: true },
{ feature2: { chrome: '<109' } },
];
const MOCK_FLAGS_WITH_NAMES = [
{ feature1: true, name: 'feature1' },
{ feature2: { chrome: '<109' }, name: 'feature2' },
];

const MOCK_FLAGS_TWO = [{ different: true }];
const MOCK_FLAGS_TWO_WITH_NAMES = [{ different: true, name: 'different' }];
const MOCK_FLAGS: FeatureFlags = {
feature1: true,
feature2: { chrome: '<109' },
};

const MOCK_FLAGS_TWO = { different: true };

/**
* Creates a controller instance with default parameters for testing
Expand Down Expand Up @@ -58,7 +53,7 @@ describe('RemoteFeatureFlagController', () => {
const controller = createController();

expect(controller.state).toStrictEqual({
remoteFeatureFlags: [],
remoteFeatureFlags: {},
cacheTimestamp: 0,
});
});
Expand All @@ -67,7 +62,7 @@ describe('RemoteFeatureFlagController', () => {
const controller = createController({ disabled: true });

expect(controller.state).toStrictEqual({
remoteFeatureFlags: [],
remoteFeatureFlags: {},
cacheTimestamp: 0,
});
});
Expand Down Expand Up @@ -133,10 +128,6 @@ describe('RemoteFeatureFlagController', () => {
jest
.spyOn(clientConfigApiService, 'fetchRemoteFeatureFlags')
.mockImplementation(async () => ({
error: false,
message: 'Success',
statusCode: '200',
statusText: 'OK',
remoteFeatureFlags: MOCK_FLAGS_TWO,
cacheTimestamp: Date.now(),
}));
Expand All @@ -145,9 +136,7 @@ describe('RemoteFeatureFlagController', () => {
expect(
clientConfigApiService.fetchRemoteFeatureFlags,
).toHaveBeenCalledTimes(1);
expect(controller.state.remoteFeatureFlags).toStrictEqual(
MOCK_FLAGS_TWO_WITH_NAMES,
);
expect(controller.state.remoteFeatureFlags).toStrictEqual(MOCK_FLAGS_TWO);
});

it('should use previously cached flags when cache is valid', async () => {
Expand Down Expand Up @@ -187,9 +176,7 @@ describe('RemoteFeatureFlagController', () => {
clientConfigApiService.fetchRemoteFeatureFlags,
).toHaveBeenCalledTimes(1);

expect(controller.state.remoteFeatureFlags).toStrictEqual(
MOCK_FLAGS_WITH_NAMES,
);
expect(controller.state.remoteFeatureFlags).toStrictEqual(MOCK_FLAGS);
});

it('should create a new fetch, and correctly update state, when called sequentially with awaiting and sufficient delay', async () => {
Expand Down Expand Up @@ -220,17 +207,15 @@ describe('RemoteFeatureFlagController', () => {

const controller = createController({
clientConfigApiService,
state: { remoteFeatureFlags: [], cacheTimestamp: 0 },
state: { remoteFeatureFlags: {}, cacheTimestamp: 0 },
});

let currentState;

// First call - should fetch new data
await controller.updateRemoteFeatureFlags();
currentState = controller.state;
expect(currentState.remoteFeatureFlags).toStrictEqual(
MOCK_FLAGS_WITH_NAMES,
);
expect(currentState.remoteFeatureFlags).toStrictEqual(MOCK_FLAGS);
expect(fetchSpy).toHaveBeenCalledTimes(1);

// Advance time past cache duration
Expand All @@ -239,32 +224,10 @@ describe('RemoteFeatureFlagController', () => {
// Second call - should fetch new data again
await controller.updateRemoteFeatureFlags();
currentState = controller.state;
expect(currentState.remoteFeatureFlags).toStrictEqual(
MOCK_FLAGS_TWO_WITH_NAMES,
);
expect(currentState.remoteFeatureFlags).toStrictEqual(MOCK_FLAGS_TWO);
expect(fetchSpy).toHaveBeenCalledTimes(2);
});

// TODO: remove the handling of the empty array case
it('should handle empty data from API', async () => {
const clientConfigApiService = buildClientConfigApiService({
remoteFeatureFlags: [],
});

const controller = createController({
clientConfigApiService,
state: {
remoteFeatureFlags: MOCK_FLAGS,
},
});
await controller.updateRemoteFeatureFlags();

expect(
clientConfigApiService.fetchRemoteFeatureFlags,
).toHaveBeenCalledTimes(1);
expect(controller.state.remoteFeatureFlags).toStrictEqual(MOCK_FLAGS);
});

it('should throw an API error to the caller, while leaving cached state unchanged', async () => {
const clientConfigApiService = buildClientConfigApiService({
error: new Error('API Error'),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { BaseController } from '@metamask/base-controller';
import type { AbstractClientConfigApiService } from './client-config-api-service/abstract-client-config-api-service';
import type {
FeatureFlags,
ApiResponse,
ServiceResponse,
} from './remote-feature-flag-controller-types';

// === GENERAL ===
Expand Down Expand Up @@ -73,7 +73,7 @@ export type RemoteFeatureFlagControllerMessenger =
*/
export function getDefaultRemoteFeatureFlagControllerState(): RemoteFeatureFlagControllerState {
return {
remoteFeatureFlags: [],
remoteFeatureFlags: {},
cacheTimestamp: 0,
};
}
Expand All @@ -95,7 +95,7 @@ export class RemoteFeatureFlagController extends BaseController<

#clientConfigApiService: AbstractClientConfigApiService;

#inProgressFlagUpdate?: Promise<ApiResponse>;
#inProgressFlagUpdate?: Promise<ServiceResponse>;

/**
* Constructs a new RemoteFeatureFlagController instance.
Expand Down Expand Up @@ -172,12 +172,7 @@ export class RemoteFeatureFlagController extends BaseController<
this.#inProgressFlagUpdate = undefined;
}

if (serverData) {
const featureFlagsWithNames = this.getFeatureFlagsWithNames(
serverData.remoteFeatureFlags,
);
this.updateCache(featureFlagsWithNames);
}
this.#updateCache(serverData.remoteFeatureFlags);
}

/**
Expand All @@ -195,14 +190,6 @@ export class RemoteFeatureFlagController extends BaseController<
});
}

#getFeatureFlagsWithNames(remoteFeatureFlags: FeatureFlags) {
const featureFlagsWithNames = remoteFeatureFlags.map((flag) => ({
...flag,
name: Object.keys(flag)?.[0],
}));
return featureFlagsWithNames;
}

/**
* Enables the controller, allowing it to make network requests.
*/
Expand Down

0 comments on commit d6a3839

Please sign in to comment.