vega-frontend-monorepo/apps/trading/components/navbar/navbar.spec.tsx
Matthew Russell 1d721dc748
fix(trading): party alias snags (#5947)
Co-authored-by: Dariusz Majcherczyk <dariusz.majcherczyk@gmail.com>
2024-03-08 17:29:41 +00:00

242 lines
7.3 KiB
TypeScript

import { act, render, screen, within } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { MemoryRouter } from 'react-router-dom';
import { Navbar } from './navbar';
import { useGlobalStore } from '../../stores';
import { ENV, useFeatureFlags } from '@vegaprotocol/environment';
import {
mockConfig,
MockedWalletProvider,
} from '@vegaprotocol/wallet-react/testing';
import { MockedProvider, type MockedResponse } from '@apollo/react-testing';
import {
PartyProfilesDocument,
type PartyProfilesQuery,
type PartyProfilesQueryVariables,
} from '../vega-wallet-connect-button/__generated__/PartyProfiles';
jest.mock('@vegaprotocol/proposals', () => ({
ProtocolUpgradeCountdown: () => null,
}));
describe('Navbar', () => {
const mockKeys = [
{
name: 'Key 1',
publicKey: '1'.repeat(64),
},
{
name: 'Key 2',
publicKey: '2'.repeat(64),
},
];
const key1Alias = 'key 1 alias';
const marketId = 'abc';
const navbarContent = 'navbar-menu-content';
const partyProfilesMock: MockedResponse<
PartyProfilesQuery,
PartyProfilesQueryVariables
> = {
request: {
query: PartyProfilesDocument,
variables: {
partyIds: mockKeys.map((k) => k.publicKey),
},
},
result: {
data: {
partiesProfilesConnection: {
edges: [
{
node: {
partyId: mockKeys[0].publicKey,
alias: key1Alias,
metadata: [],
},
},
],
},
},
},
};
const renderComponent = (initialEntries?: string[]) => {
return render(
<MemoryRouter initialEntries={initialEntries}>
<MockedProvider mocks={[partyProfilesMock]}>
<MockedWalletProvider>
<Navbar />
</MockedWalletProvider>
</MockedProvider>
</MemoryRouter>
);
};
beforeAll(() => {
useGlobalStore.setState({ marketId });
useFeatureFlags.setState({ flags: { REFERRALS: true } });
const mockedENV = jest.mocked(ENV);
mockedENV.VEGA_TOKEN_URL = 'governance';
});
afterAll(() => {
jest.clearAllMocks();
});
afterEach(() => {
act(() => {
mockConfig.reset();
});
});
it('should be properly rendered', () => {
renderComponent();
const expectedLinks = [
['/', ''],
['/markets', 'Markets'],
[`/markets/${marketId}`, 'Trading'],
['/portfolio', 'Portfolio'],
['/referrals', 'Referrals'],
['/fees', 'Fees'],
['/rewards', 'Rewards'],
[expect.stringContaining('governance'), 'Governance'],
];
const links = screen.getAllByRole('link');
links.forEach((link, i) => {
const [href, text] = expectedLinks[i];
expect(link).toHaveAttribute('href', href);
expect(link).toHaveTextContent(text);
});
});
it('Markets page route should not match empty market page', () => {
renderComponent(['/markets']);
expect(screen.getByRole('link', { name: 'Markets' })).toHaveClass('active');
expect(screen.getByRole('link', { name: 'Trading' })).not.toHaveClass(
'active'
);
});
it('can open menu and navigate on small screens', async () => {
renderComponent();
await userEvent.click(screen.getByRole('button', { name: 'Menu' }));
const menuEl = screen.getByTestId(navbarContent);
expect(menuEl).toBeInTheDocument();
const menu = within(menuEl);
const expectedLinks = [
['/markets', 'Markets'],
[`/markets/${marketId}`, 'Trading'],
['/portfolio', 'Portfolio'],
['/referrals', 'Referrals'],
['/fees', 'Fees'],
['/rewards', 'Rewards'],
[expect.stringContaining('governance'), 'Governance'],
];
const links = menu.getAllByRole('link');
links.forEach((link, i) => {
const [href, text] = expectedLinks[i];
expect(link).toHaveAttribute('href', href);
expect(link).toHaveTextContent(text);
});
await userEvent.click(screen.getByRole('button', { name: 'Close menu' }));
expect(screen.queryByTestId(navbarContent)).not.toBeInTheDocument();
});
it('can close menu by clicking overlay', async () => {
renderComponent();
await userEvent.click(screen.getByRole('button', { name: 'Menu' }));
expect(screen.getByTestId(navbarContent)).toBeInTheDocument();
await userEvent.click(screen.getByTestId('navbar-menu-overlay'));
expect(screen.queryByTestId(navbarContent)).not.toBeInTheDocument();
});
it('can open wallet menu on small screens and change pubkey', async () => {
mockConfig.store.setState({
status: 'connected',
keys: mockKeys,
pubKey: mockKeys[0].publicKey,
});
const mockSelectPubKey = jest.spyOn(mockConfig.store, 'setState');
renderComponent(undefined);
await userEvent.click(screen.getByRole('button', { name: 'Wallet' }));
const menuEl = screen.getByTestId(navbarContent);
expect(menuEl).toBeInTheDocument();
const menu = within(menuEl);
expect(menu.getAllByTestId(/key-\d+-mobile/)).toHaveLength(mockKeys.length);
const activeKey = within(menu.getByTestId(/key-1+-mobile/));
expect(activeKey.getByText(mockKeys[0].name)).toBeInTheDocument();
expect(activeKey.getByTestId('icon-tick')).toBeInTheDocument();
expect(screen.getByText(key1Alias)).toBeInTheDocument();
const inactiveKey = within(menu.getByTestId(/key-2+-mobile/));
await userEvent.click(inactiveKey.getByText(mockKeys[1].name));
expect(mockSelectPubKey).toHaveBeenCalledWith({
pubKey: mockKeys[1].publicKey,
});
});
it('can transfer and close menu', async () => {
mockConfig.store.setState({
status: 'connected',
keys: mockKeys,
pubKey: mockKeys[0].publicKey,
});
renderComponent();
await userEvent.click(screen.getByRole('button', { name: 'Wallet' }));
const menuEl = screen.getByTestId(navbarContent);
expect(menuEl).toBeInTheDocument();
const menu = within(menuEl);
await userEvent.click(menu.getByText('Transfer'));
expect(screen.queryByTestId(navbarContent)).not.toBeInTheDocument();
});
it('can disconnect and close menu', async () => {
mockConfig.store.setState({
status: 'connected',
keys: mockKeys,
pubKey: mockKeys[0].publicKey,
});
const mockDisconnect = jest.spyOn(mockConfig, 'disconnect');
renderComponent(undefined);
await userEvent.click(screen.getByRole('button', { name: 'Wallet' }));
const menuEl = screen.getByTestId(navbarContent);
expect(menuEl).toBeInTheDocument();
const menu = within(menuEl);
await userEvent.click(menu.getByText('Disconnect'));
expect(mockDisconnect).toHaveBeenCalled();
expect(screen.queryByTestId(navbarContent)).not.toBeInTheDocument();
});
it('does not render the language selector until we have more languages', () => {
renderComponent();
expect(screen.queryByTestId('icon-globe')).not.toBeInTheDocument();
});
it('renders the theme switcher', async () => {
renderComponent();
await userEvent.click(screen.getByTestId('icon-moon'));
expect(screen.queryByTestId('icon-moon')).not.toBeInTheDocument();
expect(screen.getByTestId('icon-sun')).toBeInTheDocument();
await userEvent.click(screen.getByTestId('icon-sun'));
expect(screen.queryByTestId('icon-sun')).not.toBeInTheDocument();
expect(screen.getByTestId('icon-moon')).toBeInTheDocument();
});
});