diff --git a/packages/analytics-controller/CHANGELOG.md b/packages/analytics-controller/CHANGELOG.md index 87690b1b8ef..900bd778c54 100644 --- a/packages/analytics-controller/CHANGELOG.md +++ b/packages/analytics-controller/CHANGELOG.md @@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Changed + +- Preserve the pre-consent event queue when calling `resetConsentDecision`, matching extension behavior for undecided consent resets during onboarding restarts ([#9284](https://github.com/MetaMask/core/pull/9284)) + ## [1.2.0] ### Added diff --git a/packages/analytics-controller/src/AnalyticsController-method-action-types.ts b/packages/analytics-controller/src/AnalyticsController-method-action-types.ts index 794b68e09e3..db027725a3f 100644 --- a/packages/analytics-controller/src/AnalyticsController-method-action-types.ts +++ b/packages/analytics-controller/src/AnalyticsController-method-action-types.ts @@ -67,9 +67,9 @@ export type AnalyticsControllerOptOutAction = { * Reset the consent decision back to undecided. * * Intended for client flows that restart onboarding. Clears the opt-in - * preference and discards both the delivery queue and any pre-consent events, - * so nothing captured before the reset is delivered and the user is treated - * as undecided again. + * preference and discards the delivery queue, but preserves any pre-consent + * events so they can still be replayed if the user opts in again. The user is + * treated as undecided again. */ export type AnalyticsControllerResetConsentDecisionAction = { type: `AnalyticsController:resetConsentDecision`; diff --git a/packages/analytics-controller/src/AnalyticsController.test.ts b/packages/analytics-controller/src/AnalyticsController.test.ts index 61b422bc2a0..68a7aee0cce 100644 --- a/packages/analytics-controller/src/AnalyticsController.test.ts +++ b/packages/analytics-controller/src/AnalyticsController.test.ts @@ -2138,19 +2138,20 @@ describe('AnalyticsController', () => { expect(mockAdapter.track).not.toHaveBeenCalled(); }); - it('clears the queue and resets the decision on resetConsentDecision', async () => { + it('preserves the pre-consent queue and resets the decision on resetConsentDecision', async () => { const { controller, mockAdapter } = await setupControllerWithQueuedEvent(); + const queuedEvents = controller.state.preConsentEventQueue; controller.resetConsentDecision(); expect(controller.state.optedIn).toBe(false); expect(controller.state.consentDecisionMade).toBe(false); - expect(controller.state.preConsentEventQueue).toStrictEqual({}); + expect(controller.state.preConsentEventQueue).toStrictEqual(queuedEvents); expect(mockAdapter.track).not.toHaveBeenCalled(); }); - it('also clears the delivery queue on resetConsentDecision', async () => { + it('clears the delivery queue on resetConsentDecision', async () => { const mockAdapter = createMockAdapter(); const { controller } = await setupController({ state: { @@ -2172,7 +2173,6 @@ describe('AnalyticsController', () => { expect(controller.state.optedIn).toBe(false); expect(controller.state.consentDecisionMade).toBe(false); expect(controller.state.eventQueue).toStrictEqual({}); - expect(controller.state.preConsentEventQueue ?? {}).toStrictEqual({}); }); it('replays a persisted queue on init when already opted in', async () => { diff --git a/packages/analytics-controller/src/AnalyticsController.ts b/packages/analytics-controller/src/AnalyticsController.ts index 83ea6c58f26..1c8e8170216 100644 --- a/packages/analytics-controller/src/AnalyticsController.ts +++ b/packages/analytics-controller/src/AnalyticsController.ts @@ -70,8 +70,10 @@ export type AnalyticsControllerState = { /** * Persisted queue of track events ({@link AnalyticsQueuedTrackEvent}) captured * while the user is undecided (no consent decision made yet). Replayed on - * opt-in and cleared on opt-out. This is only used when the pre-consent queue - * is enabled. + * opt-in and cleared on opt-out. + * Preserved across {@link AnalyticsController.resetConsentDecision} so onboarding + * restarts do not drop install-time events. + * This is only used when the pre-consent queue is enabled. */ preConsentEventQueue?: Record; }; @@ -949,9 +951,9 @@ export class AnalyticsController extends BaseController< * Reset the consent decision back to undecided. * * Intended for client flows that restart onboarding. Clears the opt-in - * preference and discards both the delivery queue and any pre-consent events, - * so nothing captured before the reset is delivered and the user is treated - * as undecided again. + * preference and discards the delivery queue, but preserves any pre-consent + * events so they can still be replayed if the user opts in again. The user is + * treated as undecided again. */ resetConsentDecision(): void { this.update((state) => { @@ -960,6 +962,5 @@ export class AnalyticsController extends BaseController< }); this.#clearQueuedEvents(); - this.#clearPreConsentEvents(); } }