Skip to content

Commit

Permalink
Adding basic metrics for decoding signatures
Browse files Browse the repository at this point in the history
  • Loading branch information
jpuri committed Nov 26, 2024
1 parent 6830a39 commit 67403d5
Show file tree
Hide file tree
Showing 4 changed files with 123 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { getMockTypedSignConfirmStateForRequest } from '../../../../../../../../
import { renderWithConfirmContextProvider } from '../../../../../../../../test/lib/confirmations/render-helpers';
import { permitSignatureMsg } from '../../../../../../../../test/data/confirmations/typed_sign';
import { memoizedGetTokenStandardAndDetails } from '../../../../../utils/token';
import * as SignatureMetrics from '../../../../simulation-details/useDecodedSignatureMetrics';
import PermitSimulation from './permit-simulation';

jest.mock('../../../../../../../store/actions', () => {
Expand Down Expand Up @@ -44,6 +45,25 @@ describe('PermitSimulation', () => {
});
});

it('should call hook to register signature metrics properties', async () => {
const state = getMockTypedSignConfirmStateForRequest({
...permitSignatureMsg,
decodingLoading: false,
decodingData: undefined,
});
const mockStore = configureMockStore([])(state);

const mockedUseDecodedSignatureMetrics = jest
.spyOn(SignatureMetrics, 'useDecodedSignatureMetrics')
.mockImplementation(() => '');

await act(async () => {
renderWithConfirmContextProvider(<PermitSimulation />, mockStore);

expect(mockedUseDecodedSignatureMetrics).toHaveBeenCalledTimes(1);
});
});

it('should render default simulation if decoding api returns error', async () => {
const state = getMockTypedSignConfirmStateForRequest({
...permitSignatureMsg,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,16 @@ import React from 'react';

import { SignatureRequestType } from '../../../../../types/confirm';
import { useConfirmContext } from '../../../../../context/confirm';
import { useDecodedSignatureMetrics } from '../../../../simulation-details/useDecodedSignatureMetrics';
import { DefaultSimulation } from './default-simulation';
import { DecodedSimulation } from './decoded-simulation';

const PermitSimulation: React.FC<object> = () => {
const { currentConfirmation } = useConfirmContext<SignatureRequestType>();
const { decodingLoading, decodingData } = currentConfirmation;

useDecodedSignatureMetrics();

if (
decodingData?.error ||
(decodingData?.stateChanges === undefined && decodingLoading !== true)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import { getMockTypedSignConfirmStateForRequest } from '../../../../../test/data/confirmations/helper';
import { permitSignatureMsg } from '../../../../../test/data/confirmations/typed_sign';
import { renderHookWithConfirmContextProvider } from '../../../../../test/lib/confirmations/render-helpers';
import * as SignatureEventFragment from '../../hooks/useSignatureEventFragment';
import { useDecodedSignatureMetrics } from './useDecodedSignatureMetrics';

describe('useDecodedSignatureMetrics', () => {
it('should not call updateSignatureEventFragment if decodingLoading is true', async () => {
const state = getMockTypedSignConfirmStateForRequest({
...permitSignatureMsg,
decodingLoading: true,
});

const mockUpdateSignatureEventFragment = jest.fn();
jest
.spyOn(SignatureEventFragment, 'useSignatureEventFragment')
.mockImplementation(() => ({
updateSignatureEventFragment: mockUpdateSignatureEventFragment,
}));

renderHookWithConfirmContextProvider(
() => useDecodedSignatureMetrics(),
state,
);

expect(mockUpdateSignatureEventFragment).toHaveBeenCalledTimes(0);
});

it('should call updateSignatureEventFragment with correct parameters', async () => {
const state = getMockTypedSignConfirmStateForRequest({
...permitSignatureMsg,
decodingLoading: false,
});

const mockUpdateSignatureEventFragment = jest.fn();
jest
.spyOn(SignatureEventFragment, 'useSignatureEventFragment')
.mockImplementation(() => ({
updateSignatureEventFragment: mockUpdateSignatureEventFragment,
}));

renderHookWithConfirmContextProvider(
() => useDecodedSignatureMetrics(),
state,
);

expect(mockUpdateSignatureEventFragment).toHaveBeenCalledTimes(1);
expect(mockUpdateSignatureEventFragment).toHaveBeenLastCalledWith({
properties: {
decoding_change_types: [],
decoding_response: 'NO_CHANGE',
},
});
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import { useEffect } from 'react';
import { DecodingDataStateChange } from '@metamask/signature-controller';

import { SignatureRequestType } from '../../types/confirm';
import { useConfirmContext } from '../../context/confirm';
import { useSignatureEventFragment } from '../../hooks/useSignatureEventFragment';

enum DecodingResponse {
Change = 'CHANGE',
NoChange = 'NO_CHANGE',
}

export function useDecodedSignatureMetrics() {
const { updateSignatureEventFragment } = useSignatureEventFragment();
const { currentConfirmation } = useConfirmContext<SignatureRequestType>();
const { decodingLoading, decodingData } = currentConfirmation;

const decodingChangeTypes = (decodingData?.stateChanges ?? []).map(
(change: DecodingDataStateChange) => change.changeType,
);

const decodingResponse =
decodingData?.error?.type ??
(decodingChangeTypes.length
? DecodingResponse.Change
: DecodingResponse.NoChange);

useEffect(() => {
if (decodingLoading) {
return;
}

updateSignatureEventFragment({
properties: {
decoding_response: decodingResponse,
decoding_change_types: decodingChangeTypes,
},
});
}, [
decodingResponse,
decodingLoading,
decodingChangeTypes,
updateSignatureEventFragment,
]);
}

0 comments on commit 67403d5

Please sign in to comment.