fix(trading): update click area in network switcher (#4057)

Co-authored-by: Matthew Russell <mattrussell36@gmail.com>
This commit is contained in:
Maciek 2023-06-10 16:48:48 +02:00 committed by GitHub
parent 2e7a6a6458
commit 37247a504a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 109 additions and 65 deletions

View File

@ -13,6 +13,24 @@ import { Networks } from '../../';
jest.mock('../../hooks/use-environment');
describe('Network switcher', () => {
const { location } = window;
let hrefSetSpy: jest.SpyInstance;
beforeEach(() => {
hrefSetSpy = jest.fn();
// @ts-ignore can't set location as optional
delete window.location;
window.location = {} as Location;
Object.defineProperty(window.location, 'href', {
// @ts-ignore set cannot take SpyInstance
set: hrefSetSpy,
});
});
afterEach(() => {
window.location = location;
});
it.each`
network | label
${Networks.CUSTOM} | ${envTriggerMapping[Networks.CUSTOM]}
@ -49,21 +67,29 @@ describe('Network switcher', () => {
render(<NetworkSwitcher />);
await userEvent.click(screen.getByRole('button'));
let links = screen.getAllByRole('link');
expect(links[0]).toHaveTextContent(envNameMapping[Networks.MAINNET]);
expect(links[1]).toHaveTextContent(envNameMapping[Networks.TESTNET]);
expect(links[0]).not.toHaveTextContent(t('current'));
expect(links[1]).not.toHaveTextContent(t('current'));
expect(links[0]).not.toHaveTextContent(t('not available'));
expect(links[1]).not.toHaveTextContent(t('not available'));
expect(links[2]).toHaveTextContent(t('Propose a network parameter change'));
const menuitems = screen.getAllByRole('menuitem');
expect(menuitems[0]).toHaveTextContent(envNameMapping[Networks.MAINNET]);
expect(menuitems[1]).toHaveTextContent(envNameMapping[Networks.TESTNET]);
expect(menuitems[0]).not.toHaveTextContent(t('current'));
expect(menuitems[1]).not.toHaveTextContent(t('current'));
expect(menuitems[0]).not.toHaveTextContent(t('not available'));
expect(menuitems[1]).not.toHaveTextContent(t('not available'));
expect(menuitems[2]).toHaveTextContent(t('Advanced'));
expect(menuitems[0]).toHaveTextContent('Advanced');
const links = screen.getAllByRole('link');
await userEvent.click(links[0]);
expect(hrefSetSpy).toHaveBeenCalledWith(mainnetUrl);
expect(links[0]).toHaveAttribute('href', mainnetUrl);
expect(links[1]).toHaveAttribute('href', testnetUrl);
// re open dropdown as clicking an item will close it
await userEvent.click(screen.getByRole('button'));
links = screen.getAllByRole('link');
await userEvent.click(links[1]);
expect(hrefSetSpy).toHaveBeenCalledWith(testnetUrl);
});
it('displays the correct selected network on the default dropdown view', async () => {
@ -82,10 +108,10 @@ describe('Network switcher', () => {
await userEvent.click(screen.getByRole('button'));
const menuitems = screen.getAllByRole('menuitem');
const links = screen.getAllByRole('link');
expect(menuitems[0]).toHaveTextContent(envNameMapping[Networks.MAINNET]);
expect(menuitems[0]).toHaveTextContent(t('current'));
expect(links[0]).toHaveTextContent(envNameMapping[Networks.MAINNET]);
expect(links[0]).toHaveTextContent(t('current'));
});
it('displays the correct selected network on the default dropdown view when it does not have an associated url', async () => {
@ -103,10 +129,10 @@ describe('Network switcher', () => {
await userEvent.click(screen.getByRole('button'));
const menuitems = screen.getAllByRole('menuitem');
const links = screen.getAllByRole('link');
expect(menuitems[0]).toHaveTextContent(envNameMapping[Networks.MAINNET]);
expect(menuitems[0]).toHaveTextContent(t('current'));
expect(links[0]).toHaveTextContent(envNameMapping[Networks.MAINNET]);
expect(links[0]).toHaveTextContent(t('current'));
});
it('displays the correct state for a network without url on the default dropdown view', async () => {
@ -123,44 +149,59 @@ describe('Network switcher', () => {
render(<NetworkSwitcher />);
await userEvent.click(screen.getByRole('button'));
const links = screen.getAllByRole('link');
const menuitems = screen.getAllByRole('menuitem');
expect(menuitems[0]).toHaveTextContent(envNameMapping[Networks.MAINNET]);
expect(menuitems[0]).toHaveTextContent(t('not available'));
expect(links[0]).toHaveTextContent(envNameMapping[Networks.MAINNET]);
expect(links[0]).toHaveTextContent(t('not available'));
});
it('displays the advanced view in the correct state', async () => {
const VEGA_NETWORKS: Record<Networks, string | undefined> = {
[Networks.CUSTOM]: undefined,
[Networks.MAINNET]: 'https://main.net',
[Networks.TESTNET]: 'https://test.net',
[Networks.VALIDATOR_TESTNET]: 'https://validator-test.net',
[Networks.DEVNET]: 'https://dev.net',
[Networks.STAGNET1]: 'https://stag1.net',
};
// @ts-ignore Typescript doesn't know about this module being mocked
useEnvironment.mockImplementation(() => ({
VEGA_ENV: Networks.DEVNET,
VEGA_NETWORKS,
}));
it.each([Networks.MAINNET, Networks.TESTNET, Networks.DEVNET])(
'displays the advanced view in the correct state',
async (network) => {
const VEGA_NETWORKS: Record<Networks, string | undefined> = {
[Networks.CUSTOM]: undefined,
[Networks.MAINNET]: 'https://main.net',
[Networks.TESTNET]: 'https://test.net',
[Networks.VALIDATOR_TESTNET]: 'https://validator-test.net',
[Networks.DEVNET]: 'https://dev.net',
[Networks.STAGNET1]: 'https://stag1.net',
};
// @ts-ignore Typescript doesn't know about this module being mocked
useEnvironment.mockImplementation(() => ({
VEGA_ENV: Networks.DEVNET,
VEGA_NETWORKS,
}));
render(<NetworkSwitcher />);
render(<NetworkSwitcher />);
await userEvent.click(screen.getByRole('button'));
await userEvent.click(
screen.getByRole('menuitem', { name: t('Advanced') })
);
await userEvent.click(screen.getByTestId('network-switcher'));
[Networks.MAINNET, Networks.TESTNET, Networks.DEVNET].forEach((network) => {
expect(
screen.getByRole('link', { name: envNameMapping[network] })
).toHaveAttribute('href', VEGA_NETWORKS[network]);
expect(
screen.getByText(envDescriptionMapping[network])
await screen.findByRole('menuitem', { name: t('Advanced') })
).toBeInTheDocument();
});
});
await userEvent.click(
screen.getByRole('menuitem', { name: t('Advanced') })
);
expect(
await screen.findByText(envDescriptionMapping[network])
).toBeInTheDocument();
expect(
screen.getByRole('link', {
name: new RegExp(`^${envNameMapping[network]}`),
})
).toBeInTheDocument();
await userEvent.click(
screen.getByRole('link', {
name: new RegExp(`^${envNameMapping[network]}`),
})
);
expect(hrefSetSpy).toHaveBeenCalledWith(VEGA_NETWORKS[network]);
}
);
it('labels the selected network in the advanced view', async () => {
const selectedNetwork = Networks.DEVNET;
@ -188,7 +229,7 @@ describe('Network switcher', () => {
const label = screen.getByText(`(${t('current')})`);
expect(label).toBeInTheDocument();
expect(label.parentNode?.firstElementChild).toHaveTextContent(
expect(label.parentNode?.parentNode?.firstElementChild).toHaveTextContent(
envNameMapping[selectedNetwork]
);
});
@ -217,7 +258,7 @@ describe('Network switcher', () => {
const label = screen.getByText('(not available)');
expect(label).toBeInTheDocument();
expect(label.parentNode?.firstElementChild).toHaveTextContent(
expect(label.parentNode?.parentNode?.firstElementChild).toHaveTextContent(
envNameMapping[Networks.MAINNET]
);
});

View File

@ -1,7 +1,6 @@
import { useState, useCallback, useRef } from 'react';
import { useState, useCallback } from 'react';
import { t } from '@vegaprotocol/i18n';
import {
Link,
DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
@ -99,7 +98,6 @@ export const NetworkSwitcher = ({
},
[setOpen, setAdvancedView]
);
const menuRef = useRef<HTMLButtonElement | null>(null);
const current = currentNetwork || VEGA_ENV;
@ -110,7 +108,6 @@ export const NetworkSwitcher = ({
trigger={
<DropdownMenuTrigger
data-testid="network-switcher"
ref={menuRef}
className={classNames(
'flex justify-between items-center text-sm text-vega-dark-600 dark:text-vega-light-600 py-1 px-2 rounded border border-vega-dark-200 whitespace-nowrap dark:hover:bg-vega-dark-500 hover:bg-vega-light-500',
className
@ -123,10 +120,7 @@ export const NetworkSwitcher = ({
</DropdownMenuTrigger>
}
>
<DropdownMenuContent
align="start"
style={{ minWidth: `${menuRef.current?.offsetWidth || 290}px` }}
>
<DropdownMenuContent align="start">
{!isAdvancedView && (
<>
{standardNetworkKeys.map((key) => (
@ -134,14 +128,16 @@ export const NetworkSwitcher = ({
key={key}
data-testid="network-item"
disabled={!VEGA_NETWORKS[key]}
role="link"
onClick={() =>
(window.location.href = VEGA_NETWORKS[key] || '')
}
>
<a href={VEGA_NETWORKS[key]}>
{envNameMapping[key]}
<NetworkLabel
isCurrent={current === key}
isAvailable={!!VEGA_NETWORKS[key]}
/>
</a>
{envNameMapping[key]}
<NetworkLabel
isCurrent={current === key}
isAvailable={!!VEGA_NETWORKS[key]}
/>
</DropdownMenuItem>
))}
<DropdownMenuItem
@ -159,10 +155,17 @@ export const NetworkSwitcher = ({
{isAdvancedView && (
<>
{advancedNetworkKeys.map((key) => (
<DropdownMenuItem key={key} data-testid="network-item-advanced">
<DropdownMenuItem
key={key}
data-testid="network-item-advanced"
role="link"
onClick={() =>
(window.location.href = VEGA_NETWORKS[key] || '')
}
>
<div className="w-full flex justify-between gap-2">
<div>
<Link href={VEGA_NETWORKS[key]}>{envNameMapping[key]}</Link>
{envNameMapping[key]}
<NetworkLabel
isCurrent={current === key}
isAvailable={!!VEGA_NETWORKS[key]}