Skip to content

Commit a1e1122

Browse files
chore(runway): cherry-pick fix: persist completedOnboarding state value (#15789)
- fix: cp-7.47.0 persist completedOnboarding state value (#15754)
1 parent b23ffc0 commit a1e1122

5 files changed

Lines changed: 48 additions & 111 deletions

File tree

app/store/index.ts

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import getUIStartupSpan from '../core/Performance/UIStartup';
1515
import ReduxService, { ReduxStore } from '../core/redux';
1616
import { onPersistedDataLoaded } from '../actions/user';
1717
import { toggleBasicFunctionality } from '../actions/settings';
18+
import { setCompletedOnboarding } from '../actions/onboarding';
1819

1920
// TODO: Improve type safety by using real Action types instead of `AnyAction`
2021
const pReducer = persistReducer<RootState, AnyAction>(
@@ -69,8 +70,22 @@ const createStoreAndPersistor = async () => {
6970
endTrace({ name: TraceName.StoreInit });
7071
// Signal that persisted data has been loaded
7172
store.dispatch(onPersistedDataLoaded());
73+
74+
const currentState = store.getState();
75+
7276
// This sets the basic functionality value from the persisted state when the app is restarted
73-
store.dispatch(toggleBasicFunctionality(store.getState().settings.basicFunctionalityEnabled));
77+
store.dispatch(
78+
toggleBasicFunctionality(currentState.settings.basicFunctionalityEnabled),
79+
);
80+
81+
// This sets the completedOnboarding value based on the KeyringController state
82+
// This cannot be done in a migration because `state.onboarding` was previously blacklisted in `persistConfig`
83+
if (
84+
!currentState.onboarding.completedOnboarding &&
85+
Boolean(currentState.engine.backgroundState.KeyringController.vault)
86+
) {
87+
store.dispatch(setCompletedOnboarding(true));
88+
}
7489
};
7590

7691
persistor = persistStore(store, null, onPersistComplete);

app/store/migrations/071.test.ts

Lines changed: 3 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -14,75 +14,7 @@ describe('Migration 071: Set completedOnboarding based on the KeyringController
1414
jest.resetAllMocks();
1515
});
1616

17-
const invalidStates = [
18-
{
19-
state: null,
20-
scenario: 'state is invalid',
21-
},
22-
{
23-
state: merge({}, initialRootState, {
24-
engine: null,
25-
}),
26-
scenario: 'engine state is invalid',
27-
},
28-
{
29-
state: merge({}, initialRootState, {
30-
engine: {
31-
backgroundState: null,
32-
},
33-
}),
34-
scenario: 'backgroundState is invalid',
35-
},
36-
];
37-
38-
it.each(invalidStates)('captures exception if %s', async ({ state }) => {
39-
const newState = await migrate(state);
40-
41-
expect(newState).toStrictEqual(state);
42-
expect(mockedCaptureException).toHaveBeenCalledWith(expect.any(Error));
43-
});
44-
45-
it('sets completedOnboarding to true if vault exists', () => {
46-
const state = merge({}, initialRootState, {
47-
onboarding: {
48-
completedOnboarding: false,
49-
},
50-
engine: {
51-
backgroundState: {
52-
KeyringController: {
53-
vault: true,
54-
},
55-
},
56-
},
57-
});
58-
59-
migrate(state);
60-
61-
expect(state.onboarding.completedOnboarding).toBe(true);
62-
expect(mockedCaptureException).not.toHaveBeenCalled();
63-
});
64-
65-
it('sets completedOnboarding to false if vault does not exist', () => {
66-
const state = merge({}, initialRootState, {
67-
onboarding: {
68-
completedOnboarding: false,
69-
},
70-
engine: {
71-
backgroundState: {
72-
KeyringController: {
73-
vault: false,
74-
},
75-
},
76-
},
77-
});
78-
79-
migrate(state);
80-
81-
expect(state.onboarding.completedOnboarding).toBe(false);
82-
expect(mockedCaptureException).not.toHaveBeenCalled();
83-
});
84-
85-
it('adds the completedOnboarding property if it does not exist', () => {
17+
it('returns the initial state', () => {
8618
const state = merge({}, initialRootState, {
8719
onboarding: {},
8820
engine: {
@@ -94,9 +26,9 @@ describe('Migration 071: Set completedOnboarding based on the KeyringController
9426
},
9527
});
9628

97-
migrate(state);
29+
const migratedState = migrate(state);
9830

99-
expect(state.onboarding.completedOnboarding).toBe(true);
31+
expect(migratedState).toStrictEqual(state);
10032
expect(mockedCaptureException).not.toHaveBeenCalled();
10133
});
10234
});

app/store/migrations/071.ts

Lines changed: 4 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,40 +1,9 @@
1-
import { hasProperty, isObject } from '@metamask/utils';
2-
import { ensureValidState } from './util';
3-
import { captureException } from '@sentry/react-native';
4-
51
/**
62
* Migration 71: set completedOnboarding based on the state of the KeyringController.
3+
*
4+
* This migration ended up never being useful, since `onboarding` was blacklisted in `persistConfig`.
5+
* We're instead applying the original logic in `onPersistComplete` in `app/store/index.ts`.
76
*/
8-
const migration = (state: unknown): unknown => {
9-
const migrationVersion = 71;
10-
11-
// Ensure the state is valid for migration
12-
if (!ensureValidState(state, migrationVersion)) {
13-
return state;
14-
}
15-
16-
try {
17-
const KeyringController = state.engine.backgroundState.KeyringController;
18-
19-
if (
20-
KeyringController &&
21-
hasProperty(KeyringController, 'vault') &&
22-
hasProperty(state, 'onboarding') &&
23-
isObject(state.onboarding)
24-
) {
25-
const { vault } = KeyringController;
26-
state.onboarding.completedOnboarding = Boolean(vault);
27-
}
28-
29-
return state;
30-
} catch (error) {
31-
captureException(
32-
new Error(
33-
`Migration 071: setting completedOnboarding failed with error: ${error}`,
34-
),
35-
);
36-
return state;
37-
}
38-
};
7+
const migration = (state: unknown): unknown => state;
398

409
export default migration;

app/store/persistConfig.test.ts

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,6 @@ describe('persistConfig', () => {
113113
expect(persistConfig.version).toBe(version);
114114
expect(persistConfig.timeout).toBe(40000);
115115
expect(persistConfig.blacklist).toEqual([
116-
'onboarding',
117116
'rpcEvents',
118117
'accounts',
119118
'confirmationMetrics',
@@ -232,7 +231,7 @@ describe('persistConfig', () => {
232231

233232
describe('transforms', () => {
234233
it('have engine transform configured', () => {
235-
expect(persistConfig.transforms).toHaveLength(2);
234+
expect(persistConfig.transforms).toHaveLength(3);
236235
const engineTransform = persistConfig.transforms[0] as Transform<
237236
unknown,
238237
unknown
@@ -248,6 +247,14 @@ describe('persistConfig', () => {
248247
expect(userTransform.whitelist).toEqual(['user']);
249248
});
250249

250+
it('has onboarding transform configured', () => {
251+
const onboardingTransform = persistConfig.transforms[2] as Transform<
252+
unknown,
253+
unknown
254+
> & { whitelist?: string[] };
255+
expect(onboardingTransform.whitelist).toEqual(['onboarding']);
256+
});
257+
251258
describe('persistTransform', () => {
252259
const engineTransform = persistConfig.transforms[0] as Transform<
253260
unknown,

app/store/persistConfig.ts

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -130,12 +130,26 @@ const persistUserTransform = createTransform(
130130
{ whitelist: ['user'] },
131131
);
132132

133+
const persistOnboardingTransform = createTransform(
134+
(inboundState: RootState['onboarding']) => {
135+
const { events, ...state } = inboundState;
136+
// Reconstruct data to persist
137+
return state;
138+
},
139+
null,
140+
{ whitelist: ['onboarding'] },
141+
);
142+
133143
const persistConfig = {
134144
key: 'root',
135145
version,
136-
blacklist: ['onboarding', 'rpcEvents', 'accounts', 'confirmationMetrics'],
146+
blacklist: ['rpcEvents', 'accounts', 'confirmationMetrics'],
137147
storage: MigratedStorage,
138-
transforms: [persistTransform, persistUserTransform],
148+
transforms: [
149+
persistTransform,
150+
persistUserTransform,
151+
persistOnboardingTransform,
152+
],
139153
stateReconciler: autoMergeLevel2, // see "Merge Process" section for details.
140154
migrate: createMigrate(migrations, { debug: false }),
141155
timeout: TIMEOUT,

0 commit comments

Comments
 (0)