Skip to content

Commit 6eca484

Browse files
committed
feat(metrics): Add more glean metrics for signup code view
1 parent 92d6cab commit 6eca484

11 files changed

Lines changed: 134 additions & 8 deletions

File tree

packages/fxa-settings/src/components/OAuthDataError/index.tsx

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,24 @@
22
* License, v. 2.0. If a copy of the MPL was not distributed with this
33
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
44

5-
import React from 'react';
5+
import React, { useEffect } from 'react';
66
import { getLocalizedErrorMessage } from '../../lib/error-utils';
77
import { AuthError } from '../../lib/oauth';
88
import { useFtlMsgResolver } from '../../models';
99
import AppLayout from '../AppLayout';
1010
import Banner from '../Banner';
1111
import CardHeader from '../CardHeader';
1212

13-
const OAuthDataError = ({ error }: { error: AuthError }) => {
13+
const OAuthDataError = ({ error, gleanMetric }: { error: AuthError, gleanMetric?: (data: { event: { reason: string } }) => void }) => {
1414
const ftlMsgResolver = useFtlMsgResolver();
1515

16+
17+
useEffect(() => {
18+
if (gleanMetric) {
19+
gleanMetric({ event: { reason: error.errno.toString() }});
20+
}
21+
}, [gleanMetric, error.errno]);
22+
1623
return (
1724
<AppLayout>
1825
<CardHeader

packages/fxa-settings/src/lib/glean/index.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -254,6 +254,11 @@ const recordEventMetric = (
254254
case 'reg_signup_code_submit':
255255
reg.signupCodeSubmit.record();
256256
break;
257+
case 'reg_signup_code_submit_frontend_error':
258+
reg.signupCodeSubmitFrontendError.record({
259+
reason: gleanPingMetrics?.event?.['reason'] || '',
260+
});
261+
break;
257262
case 'reg_success_view':
258263
reg.successView.record();
259264
break;

packages/fxa-settings/src/pages/Signup/ConfirmSignupCode/container.test.tsx

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import { renderWithLocalizationProvider } from 'fxa-react/lib/test-utils/localiz
1919
import SignupConfirmCodeContainer from './container';
2020
import { Integration } from '../../../models';
2121
import { mockSensitiveDataClient as createMockSensitiveDataClient } from '../../../models/mocks';
22+
import GleanMetrics from '../../../lib/glean';
2223

2324
import {
2425
MOCK_EMAIL,
@@ -46,6 +47,17 @@ jest.mock('@reach/router', () => ({
4647
useNavigate: () => mockNavigate,
4748
}));
4849

50+
jest.mock('../../../lib/glean', () => ({
51+
__esModule: true,
52+
default: {
53+
signupConfirmation: {
54+
view: jest.fn(),
55+
submit: jest.fn(),
56+
error: jest.fn(),
57+
}
58+
},
59+
}));
60+
4961
// Global instances
5062
let integration: Integration;
5163
let mockAuthClient = new AuthClient('localhost:9000', { keyStretchVersion: 1 });
@@ -272,14 +284,17 @@ describe('confirm-signup-container', () => {
272284
};
273285
}
274286
),
275-
oAuthDataError: { message: 'BOOM', errno: 1, version: 1 },
287+
oAuthDataError: { message: 'Something went wrong. Please close this tab and try again.', errno: 1, version: 1 },
276288
};
277289
});
278290
render();
279291
await waitFor(() =>
280292
expect(screen.getByText('Bad Request')).toBeInTheDocument()
281293
);
282294
expect(screen.getByText('Unexpected error')).toBeInTheDocument();
295+
expect(GleanMetrics.signupConfirmation.error).toHaveBeenCalledWith({
296+
event: { reason: "1" }
297+
})
283298
});
284299
});
285300
describe('useOAuthKeysCheck', () => {

packages/fxa-settings/src/pages/Signup/ConfirmSignupCode/container.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import { EMAIL_BOUNCE_STATUS_QUERY } from './gql';
2323
import OAuthDataError from '../../../components/OAuthDataError';
2424
import { QueryParams } from '../../..';
2525
import { SensitiveData } from '../../../lib/sensitive-data-client';
26+
import GleanMetrics from '../../../lib/glean';
2627

2728
export const POLL_INTERVAL = 5000;
2829

@@ -131,10 +132,10 @@ const SignupConfirmCodeContainer = ({
131132
}
132133

133134
if (oAuthDataError) {
134-
return <OAuthDataError error={oAuthDataError} />;
135+
return <OAuthDataError error={oAuthDataError} gleanMetric={GleanMetrics.signupConfirmation.error} />;
135136
}
136137
if (oAuthKeysCheckError) {
137-
return <OAuthDataError error={oAuthKeysCheckError} />;
138+
return <OAuthDataError error={oAuthKeysCheckError} gleanMetric={GleanMetrics.signupConfirmation.error}/>;
138139
}
139140

140141
return (

packages/fxa-settings/src/pages/Signup/ConfirmSignupCode/index.test.tsx

Lines changed: 49 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ import {
1717
Subject,
1818
createMockOAuthNativeIntegration,
1919
createMockOAuthWebIntegration,
20-
createMockWebIntegration,
20+
createMockWebIntegration, MOCK_AUTH_ERROR_INVALID_CODE, MOCK_AUTH_ERROR_RATE_LIMIT,
2121
} from './mocks';
2222
import {
2323
MOCK_OAUTH_FLOW_HANDLER_RESPONSE,
@@ -64,6 +64,7 @@ jest.mock('../../../lib/glean', () => ({
6464
signupConfirmation: {
6565
view: jest.fn(),
6666
submit: jest.fn(),
67+
error: jest.fn(),
6768
},
6869
isDone: jest.fn(),
6970
},
@@ -317,6 +318,7 @@ describe('ConfirmSignupCode page', () => {
317318
});
318319
});
319320
});
321+
320322
it('sends expected web channel messages when service=relay', async () => {
321323
const integration = createMockOAuthNativeIntegration(false);
322324
renderWithSession({
@@ -421,7 +423,52 @@ describe('ConfirmSignupCode page with error states', () => {
421423
});
422424
});
423425

424-
// TODO add test for expected behaviour on verifySession fail in FXA-8303
426+
it('renders an error tooltip when the form is submitted with invalid code', async () => {
427+
session = {
428+
verifySession: jest.fn().mockRejectedValue(MOCK_AUTH_ERROR_INVALID_CODE),
429+
} as unknown as Session;
430+
431+
renderWithSession({ session, integration: createMockWebIntegration({}) });
432+
433+
const codeInput = screen.getByLabelText('Enter 6-digit code');
434+
fireEvent.change(codeInput, {
435+
target: { value: '123123' },
436+
});
437+
438+
const submitButton = screen.getByRole('button', { name: 'Confirm' });
439+
fireEvent.click(submitButton);
440+
await waitFor(() => {
441+
expect(screen.getByTestId('tooltip')).toHaveTextContent(
442+
'Invalid or expired confirmation code'
443+
);
444+
expect(GleanMetrics.signupConfirmation.submit).toHaveBeenCalled();
445+
expect(GleanMetrics.signupConfirmation.error).toHaveBeenCalledWith({
446+
event: { reason: MOCK_AUTH_ERROR_INVALID_CODE.errno.toString() }
447+
});
448+
});
449+
});
450+
451+
it('renders an error when the form is submitted with rate limit', async () => {
452+
session = {
453+
verifySession: jest.fn().mockRejectedValue(MOCK_AUTH_ERROR_RATE_LIMIT),
454+
} as unknown as Session;
455+
456+
renderWithSession({ session, integration: createMockWebIntegration({}) });
457+
458+
const codeInput = screen.getByLabelText('Enter 6-digit code');
459+
fireEvent.change(codeInput, {
460+
target: { value: '123123' },
461+
});
462+
463+
const submitButton = screen.getByRole('button', { name: 'Confirm' });
464+
fireEvent.click(submitButton);
465+
await waitFor(() => {
466+
expect(GleanMetrics.signupConfirmation.submit).toHaveBeenCalled();
467+
expect(GleanMetrics.signupConfirmation.error).toHaveBeenCalledWith({
468+
event: { reason: MOCK_AUTH_ERROR_RATE_LIMIT.errno.toString() }
469+
});
470+
});
471+
});
425472
});
426473

427474
describe('Resending a new code from ConfirmSignupCode page', () => {

packages/fxa-settings/src/pages/Signup/ConfirmSignupCode/index.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -247,6 +247,7 @@ const ConfirmSignupCode = ({
247247
}
248248
}
249249
} catch (error) {
250+
GleanMetrics.signupConfirmation.error({ event: { reason: error.errno?.toString() } });
250251
let localizedErrorMessage: string;
251252
// Intercept invalid parameter error and set the error message to INVALID_EXPIRED_OTP_CODE
252253
// This error occurs when the submitted code does not pass validation for the code param

packages/fxa-settings/src/pages/Signup/ConfirmSignupCode/mocks.tsx

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,15 @@ export const MOCK_AUTH_ERROR = {
4141
message: 'Something broke',
4242
};
4343

44+
export const MOCK_AUTH_ERROR_INVALID_CODE = {
45+
errno: 183,
46+
message: 'Invalid or expired confirmation code',
47+
};
48+
49+
export const MOCK_AUTH_ERROR_RATE_LIMIT = {
50+
errno: 114,
51+
message: 'Client has sent too many requests',
52+
};
4453
export const MOCK_SIGNUP_CODE = '123456';
4554

4655
export function createMockWebIntegration({

packages/fxa-shared/metrics/glean/fxa-ui-metrics.yaml

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1408,6 +1408,27 @@ reg:
14081408
expires: never
14091409
data_sensitivity:
14101410
- interaction
1411+
signup_code_submit_frontend_error:
1412+
type: event
1413+
description: |
1414+
Emit any frontend errors that occur when a user attempts to submit the code on registration confirmation page.
1415+
send_in_pings:
1416+
- events
1417+
notification_emails:
1418+
1419+
1420+
bugs:
1421+
- https://mozilla-hub.atlassian.net/browse/FXA-7265
1422+
data_reviews:
1423+
- https://bugzilla.mozilla.org/show_bug.cgi?id=1830504
1424+
- https://bugzilla.mozilla.org/show_bug.cgi?id=1844121
1425+
expires: never
1426+
data_sensitivity:
1427+
- interaction
1428+
extra_keys:
1429+
reason:
1430+
description: additional context-dependent info, e.g. the cause of an error
1431+
type: string
14111432
submit:
14121433
type: event
14131434
description: |

packages/fxa-shared/metrics/glean/web/event.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@
44

55
// AUTOGENERATED BY glean_parser v14.5.2. DO NOT EDIT. DO NOT COMMIT.
66

7-
import StringMetricType from '@mozilla/glean/private/metrics/string';
87
import BooleanMetricType from '@mozilla/glean/private/metrics/boolean';
8+
import StringMetricType from '@mozilla/glean/private/metrics/string';
99

1010
/**
1111
* The name of the event

packages/fxa-shared/metrics/glean/web/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ export const eventsMap = {
7474
signupConfirmation: {
7575
view: 'reg_signup_code_view',
7676
submit: 'reg_signup_code_submit',
77+
error: 'reg_signup_code_submit_frontend_error',
7778
},
7879

7980
login: {

0 commit comments

Comments
 (0)