chore: add back telemetry approval - refactor a solution
This commit is contained in:
@@ -24,8 +24,8 @@ export const Settings = () => {
|
||||
>
|
||||
<Switch
|
||||
name="settings-telemetry-switch"
|
||||
onCheckedChange={(isOn) => setIsApproved(isOn)}
|
||||
checked={isApproved}
|
||||
onCheckedChange={(isOn) => setIsApproved(isOn ? 'true' : 'false')}
|
||||
checked={isApproved === 'true'}
|
||||
/>
|
||||
</SettingsGroup>
|
||||
<SettingsGroup label={t('Toast location')}>
|
||||
|
||||
@@ -2,29 +2,35 @@ import { render, screen } from '@testing-library/react';
|
||||
import userEvent from '@testing-library/user-event';
|
||||
import { TelemetryApproval } from './telemetry-approval';
|
||||
|
||||
jest.mock('@vegaprotocol/logger', () => ({
|
||||
SentryInit: () => undefined,
|
||||
SentryClose: () => undefined,
|
||||
}));
|
||||
|
||||
jest.mock('@vegaprotocol/environment', () => ({
|
||||
useEnvironment: () => ({ VEGA_ENV: 'test', SENTRY_DSN: 'sentry-dsn' }),
|
||||
}));
|
||||
|
||||
describe('TelemetryApproval', () => {
|
||||
it('click on checkbox should be properly handled', async () => {
|
||||
const helpText = 'My help text';
|
||||
render(<TelemetryApproval helpText={helpText} />);
|
||||
expect(screen.getByRole('checkbox')).toHaveAttribute(
|
||||
'data-state',
|
||||
'unchecked'
|
||||
it('click on buttons should be properly handled', async () => {
|
||||
const mockSetTelemetryValue = jest.fn();
|
||||
render(
|
||||
<TelemetryApproval
|
||||
telemetryValue="false"
|
||||
setTelemetryValue={mockSetTelemetryValue}
|
||||
/>
|
||||
);
|
||||
await userEvent.click(screen.getByRole('checkbox'));
|
||||
expect(screen.getByRole('checkbox')).toHaveAttribute(
|
||||
'data-state',
|
||||
'checked'
|
||||
expect(
|
||||
screen.getByRole('button', { name: 'No thanks' })
|
||||
).toBeInTheDocument();
|
||||
await userEvent.click(screen.getByRole('button', { name: 'No thanks' }));
|
||||
expect(mockSetTelemetryValue).toHaveBeenCalledWith('false');
|
||||
expect(screen.getByText('Share data')).toBeInTheDocument();
|
||||
await userEvent.click(screen.getByText('Share data'));
|
||||
expect(mockSetTelemetryValue).toHaveBeenCalledWith('true');
|
||||
});
|
||||
|
||||
it('confirm button should have proper text', async () => {
|
||||
const mockSetTelemetryValue = jest.fn();
|
||||
render(
|
||||
<TelemetryApproval
|
||||
telemetryValue="true"
|
||||
setTelemetryValue={mockSetTelemetryValue}
|
||||
/>
|
||||
);
|
||||
expect(screen.getByText('Share usage data')).toBeInTheDocument();
|
||||
expect(screen.getByText(helpText)).toBeInTheDocument();
|
||||
expect(screen.getByText('Continue sharing data')).toBeInTheDocument();
|
||||
await userEvent.click(screen.getByText('Continue sharing data'));
|
||||
expect(mockSetTelemetryValue).toHaveBeenCalledWith('true');
|
||||
});
|
||||
});
|
||||
|
||||
@@ -2,11 +2,14 @@ import { Button, Icon } from '@vegaprotocol/ui-toolkit';
|
||||
import { t } from '@vegaprotocol/i18n';
|
||||
|
||||
interface Props {
|
||||
isApproved: string;
|
||||
setApproved: (value: string) => void;
|
||||
telemetryValue: string;
|
||||
setTelemetryValue: (value: string) => void;
|
||||
}
|
||||
|
||||
export const TelemetryApproval = ({ isApproved, setApproved }: Props) => {
|
||||
export const TelemetryApproval = ({
|
||||
telemetryValue,
|
||||
setTelemetryValue,
|
||||
}: Props) => {
|
||||
return (
|
||||
<div className="flex flex-col py-3">
|
||||
<div className="mr-4" role="form">
|
||||
@@ -32,7 +35,7 @@ export const TelemetryApproval = ({ isApproved, setApproved }: Props) => {
|
||||
</div>
|
||||
<div className="flex justify-around items-center mt-10 gap-4 w-full">
|
||||
<Button
|
||||
onClick={() => setApproved('false')}
|
||||
onClick={() => setTelemetryValue('false')}
|
||||
variant="default"
|
||||
data-testid="do-not-share-data-button"
|
||||
>
|
||||
@@ -40,11 +43,11 @@ export const TelemetryApproval = ({ isApproved, setApproved }: Props) => {
|
||||
</Button>
|
||||
|
||||
<Button
|
||||
onClick={() => setApproved('true')}
|
||||
onClick={() => setTelemetryValue('true')}
|
||||
variant="primary"
|
||||
data-testid="share-data-button"
|
||||
>
|
||||
{isApproved === 'true'
|
||||
{telemetryValue === 'true'
|
||||
? t('Continue sharing data')
|
||||
: t('Share data')}
|
||||
</Button>
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import React, { useCallback, useEffect } from 'react';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
import { Dialog, Intent } from '@vegaprotocol/ui-toolkit';
|
||||
import { t } from '@vegaprotocol/i18n';
|
||||
@@ -16,19 +15,8 @@ import { TelemetryApproval } from './telemetry-approval';
|
||||
import { useTelemetryApproval } from '../../lib/hooks/use-telemetry-approval';
|
||||
|
||||
export const WelcomeDialog = () => {
|
||||
const [
|
||||
telemetryOn,
|
||||
setTelemetryOn,
|
||||
defaultTelemetryValue,
|
||||
isTelemetryNeeded,
|
||||
closeTelemetry,
|
||||
] = useTelemetryApproval();
|
||||
useEffect(() => {
|
||||
if (!telemetryOn) {
|
||||
setTelemetryOn(defaultTelemetryValue);
|
||||
}
|
||||
}, [telemetryOn, setTelemetryOn, defaultTelemetryValue]);
|
||||
|
||||
const [telemetryValue, setTelemetryValue, isTelemetryNeeded, closeTelemetry] =
|
||||
useTelemetryApproval();
|
||||
const { VEGA_ENV } = useEnvironment();
|
||||
const [onBoardingViewed] = useLocalStorage(constants.ONBOARDING_VIEWED_KEY);
|
||||
const update = useGlobalStore((store) => store.update);
|
||||
@@ -43,17 +31,9 @@ export const WelcomeDialog = () => {
|
||||
!dismissed;
|
||||
const marketId = useGlobalStore((store) => store.marketId);
|
||||
|
||||
const setApproved = useCallback(
|
||||
(value: string) => {
|
||||
setTelemetryOn(value);
|
||||
closeTelemetry();
|
||||
},
|
||||
[setTelemetryOn, closeTelemetry]
|
||||
);
|
||||
|
||||
const onClose = () => {
|
||||
if (isTelemetryNeeded) {
|
||||
setApproved(telemetryOn || defaultTelemetryValue);
|
||||
closeTelemetry();
|
||||
} else {
|
||||
const link = marketId
|
||||
? Links[Routes.MARKET](marketId)
|
||||
@@ -78,7 +58,10 @@ export const WelcomeDialog = () => {
|
||||
);
|
||||
|
||||
const content = isTelemetryNeeded ? (
|
||||
<TelemetryApproval isApproved={telemetryOn} setApproved={setApproved} />
|
||||
<TelemetryApproval
|
||||
telemetryValue={telemetryValue}
|
||||
setTelemetryValue={setTelemetryValue}
|
||||
/>
|
||||
) : isOnboardingDialogNeeded ? (
|
||||
<WelcomeDialogContent />
|
||||
) : null;
|
||||
|
||||
@@ -2,18 +2,22 @@ import { renderHook, act, waitFor } from '@testing-library/react';
|
||||
import { useLocalStorage } from '@vegaprotocol/react-helpers';
|
||||
import { SentryInit, SentryClose } from '@vegaprotocol/logger';
|
||||
import { STORAGE_KEY, useTelemetryApproval } from './use-telemetry-approval';
|
||||
import { Networks } from '@vegaprotocol/environment';
|
||||
|
||||
const mockSetValue = jest.fn();
|
||||
const mockRemoveValue = jest.fn();
|
||||
let mockStorageHookResult = [null, mockSetValue];
|
||||
jest.mock('@vegaprotocol/logger');
|
||||
jest.mock('@vegaprotocol/react-helpers', () => ({
|
||||
...jest.requireActual('@vegaprotocol/react-helpers'),
|
||||
useLocalStorage: jest
|
||||
.fn()
|
||||
.mockImplementation(() => [false, mockSetValue, mockRemoveValue]),
|
||||
useLocalStorage: jest.fn().mockImplementation(() => mockStorageHookResult),
|
||||
}));
|
||||
let mockVegaEnv = 'test';
|
||||
jest.mock('@vegaprotocol/environment', () => ({
|
||||
useEnvironment: () => ({ VEGA_ENV: 'test', SENTRY_DSN: 'sentry-dsn' }),
|
||||
...jest.requireActual('@vegaprotocol/environment'),
|
||||
useEnvironment: jest.fn(() => ({
|
||||
VEGA_ENV: mockVegaEnv,
|
||||
SENTRY_DSN: 'sentry-dsn',
|
||||
})),
|
||||
}));
|
||||
|
||||
describe('useTelemetryApproval', () => {
|
||||
@@ -21,32 +25,53 @@ describe('useTelemetryApproval', () => {
|
||||
jest.clearAllMocks();
|
||||
});
|
||||
|
||||
it('hook should return proper array', () => {
|
||||
it('when empty hook should return proper array', () => {
|
||||
const { result } = renderHook(() => useTelemetryApproval());
|
||||
expect(result.current[0]).toEqual(false);
|
||||
expect(result.current[0]).toEqual('');
|
||||
expect(result.current[1]).toEqual(expect.any(Function));
|
||||
expect(result.current[2]).toEqual(true);
|
||||
expect(result.current[3]).toEqual(expect.any(Function));
|
||||
expect(useLocalStorage).toHaveBeenCalledWith(STORAGE_KEY);
|
||||
expect(mockSetValue).toHaveBeenCalledWith('true');
|
||||
});
|
||||
|
||||
it('when NOT empty hook should return proper array', () => {
|
||||
mockStorageHookResult = ['false', mockSetValue];
|
||||
const { result } = renderHook(() => useTelemetryApproval());
|
||||
expect(result.current[0]).toEqual('false');
|
||||
expect(result.current[1]).toEqual(expect.any(Function));
|
||||
expect(result.current[2]).toEqual(false);
|
||||
expect(result.current[3]).toEqual(expect.any(Function));
|
||||
expect(useLocalStorage).toHaveBeenCalledWith(STORAGE_KEY);
|
||||
expect(mockSetValue).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('on mainnet hook should init properly', () => {
|
||||
mockStorageHookResult = [null, mockSetValue];
|
||||
mockVegaEnv = Networks.MAINNET;
|
||||
renderHook(() => useTelemetryApproval());
|
||||
expect(mockSetValue).toHaveBeenCalledWith('false');
|
||||
});
|
||||
|
||||
it('hook should init stuff properly', async () => {
|
||||
const { result } = renderHook(() => useTelemetryApproval());
|
||||
await act(() => {
|
||||
result.current[1](true);
|
||||
result.current[1]('true');
|
||||
});
|
||||
await waitFor(() => {
|
||||
expect(SentryInit).toHaveBeenCalled();
|
||||
expect(mockSetValue).toHaveBeenCalledWith('1');
|
||||
expect(mockSetValue).toHaveBeenCalledWith('true');
|
||||
});
|
||||
});
|
||||
|
||||
it('hook should close stuff properly', async () => {
|
||||
const { result } = renderHook(() => useTelemetryApproval());
|
||||
await act(() => {
|
||||
result.current[1](false);
|
||||
result.current[1]('false');
|
||||
});
|
||||
await waitFor(() => {
|
||||
expect(SentryClose).toHaveBeenCalled();
|
||||
expect(mockRemoveValue).toHaveBeenCalledWith();
|
||||
expect(mockSetValue).toHaveBeenCalledWith('false');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
import { useLocalStorage } from '@vegaprotocol/react-helpers';
|
||||
import { useCallback, useEffect, useRef, useState } from 'react';
|
||||
import { useCallback, useEffect, useState } from 'react';
|
||||
import { SentryInit, SentryClose } from '@vegaprotocol/logger';
|
||||
import { Networks, useEnvironment } from '@vegaprotocol/environment';
|
||||
|
||||
export const STORAGE_KEY = 'vega_telemetry_approval';
|
||||
|
||||
export const useTelemetryApproval = (): [
|
||||
value: string,
|
||||
setValue: (value: string) => void,
|
||||
defaultValue: string,
|
||||
shouldOpen: boolean,
|
||||
close: () => void
|
||||
] => {
|
||||
@@ -16,16 +16,10 @@ export const useTelemetryApproval = (): [
|
||||
VEGA_ENV === Networks.MAINNET ? 'false' : 'true';
|
||||
const [value, setValue] = useLocalStorage(STORAGE_KEY);
|
||||
const [shouldOpen, setShouldOpen] = useState(!value);
|
||||
const valueRef = useRef(Boolean(value));
|
||||
useEffect(() => {
|
||||
if (!valueRef.current) {
|
||||
setShouldOpen(true);
|
||||
}
|
||||
}, []);
|
||||
const close = useCallback(() => {
|
||||
setShouldOpen(false);
|
||||
}, []);
|
||||
const setApprove = useCallback(
|
||||
const manageValue = useCallback(
|
||||
(value: string) => {
|
||||
if (value === 'true' && SENTRY_DSN) {
|
||||
SentryInit(SENTRY_DSN, VEGA_ENV);
|
||||
@@ -36,5 +30,18 @@ export const useTelemetryApproval = (): [
|
||||
},
|
||||
[setValue, SENTRY_DSN, VEGA_ENV]
|
||||
);
|
||||
return [value || '', setApprove, defaultTelemetryValue, shouldOpen, close];
|
||||
const setTelemetryValue = useCallback(
|
||||
(value: string) => {
|
||||
setShouldOpen(false);
|
||||
manageValue(value);
|
||||
},
|
||||
[manageValue]
|
||||
);
|
||||
useEffect(() => {
|
||||
if (!value) {
|
||||
manageValue(defaultTelemetryValue);
|
||||
}
|
||||
}, [value, manageValue, defaultTelemetryValue]);
|
||||
|
||||
return [value || '', setTelemetryValue, shouldOpen, close];
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user