Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions packages/analytics-controller/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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`;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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: {
Expand All @@ -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 () => {
Expand Down
13 changes: 7 additions & 6 deletions packages/analytics-controller/src/AnalyticsController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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<string, Json>;
};
Expand Down Expand Up @@ -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) => {
Expand All @@ -960,6 +962,5 @@ export class AnalyticsController extends BaseController<
});

this.#clearQueuedEvents();
this.#clearPreConsentEvents();
}
}
Loading