Compare commits

..
Author SHA1 Message Date
Edd 313fcf2323 feat(governance): enable volume discount update view (#5304) 2023-11-17 17:38:30 +00:00
8 changed files with 64 additions and 213 deletions
-1
View File
@@ -52,4 +52,3 @@ cypress.env.json
/apps/**/cypress/reports/
/apps/**/cypress/downloads/
/apps/**/fixtures/wallet/node**
.nx/
@@ -1,12 +0,0 @@
import { Settings } from './settings';
import { render, screen } from '@testing-library/react';
describe('Settings', () => {
it('should the settings component with all the options', () => {
render(<Settings />);
expect(screen.getByText('Dark mode')).toBeInTheDocument();
expect(screen.getByText('Share usage data')).toBeInTheDocument();
expect(screen.getByText('Toast location')).toBeInTheDocument();
expect(screen.getByText('Reset to default')).toBeInTheDocument();
});
});
+2 -55
View File
@@ -1,19 +1,12 @@
import { t } from '@vegaprotocol/i18n';
import {
Dialog,
Intent,
Switch,
ToastPositionSetter,
TradingButton,
} from '@vegaprotocol/ui-toolkit';
import { Switch, ToastPositionSetter } from '@vegaprotocol/ui-toolkit';
import { useThemeSwitcher } from '@vegaprotocol/react-helpers';
import { useTelemetryApproval } from '../../lib/hooks/use-telemetry-approval';
import { useState, type ReactNode } from 'react';
import type { ReactNode } from 'react';
export const Settings = () => {
const { theme, setTheme } = useThemeSwitcher();
const [isApproved, setIsApproved] = useTelemetryApproval();
const [open, setOpen] = useState(false);
return (
<div>
<SettingsGroup label={t('Dark mode')}>
@@ -38,52 +31,6 @@ export const Settings = () => {
<SettingsGroup label={t('Toast location')}>
<ToastPositionSetter />
</SettingsGroup>
<SettingsGroup label={t('Reset to default')}>
<TradingButton
name="reset-to-defaults"
size="small"
intent={Intent.None}
onClick={() => {
setOpen(true);
}}
>
{t('Reset')}
</TradingButton>
<Dialog open={open} title={t('Reset')}>
<div className="mb-4">
<p>
{t(
'You will lose all persisted settings and you will be logged out.'
)}
</p>
<p>
{t('Are you sure you want to reset all settings to default?')}
</p>
</div>
<div className="flex flex-col gap-4">
<TradingButton
name="reset-to-defaults-cancel"
intent={Intent.Primary}
onClick={() => {
localStorage.clear();
window.location.reload();
}}
>
{t('Yes, clear cache and refresh')}
</TradingButton>
<TradingButton
name="reset-to-defaults-cancel"
intent={Intent.None}
onClick={() => {
setOpen(false);
}}
>
{t('No, keep settings')}
</TradingButton>
</div>
</Dialog>
</SettingsGroup>
</div>
);
};
+40 -28
View File
@@ -1,23 +1,10 @@
import { act, render, screen, within } from '@testing-library/react';
import { act, render, screen } from '@testing-library/react';
import * as Types from '@vegaprotocol/types';
import type { AccountFields } from './accounts-data-provider';
import { getAccountData } from './accounts-data-provider';
import { AccountTable } from './accounts-table';
import userEvent from '@testing-library/user-event';
const asset1 = {
__typename: 'Asset',
id: 'asset-1',
symbol: 'tBTC',
decimals: 5,
name: 'T BTC',
};
const asset2 = {
__typename: 'Asset',
id: 'asset-2',
symbol: 'aBTC',
decimals: 5,
name: 'A BTC',
};
const singleRow = {
__typename: 'AccountBalance',
type: Types.AccountType.ACCOUNT_TYPE_MARGIN,
@@ -26,7 +13,12 @@ const singleRow = {
__typename: 'Market',
id: '10cd0a793ad2887b340940337fa6d97a212e0e517fe8e9eab2b5ef3a38633f35',
},
asset: asset1,
asset: {
__typename: 'Asset',
id: '5cfa87844724df6069b94e4c8a6f03af21907d7bc251593d08e4251043ee9f7c',
symbol: 'tBTC',
decimals: 5,
},
available: '125600000',
used: '125600000',
total: '251200000',
@@ -41,7 +33,12 @@ const secondRow = {
__typename: 'Market',
id: '10cd0a793ad2887b340940337fa6d97a212e0e517fe8e9eab2b5ef3a38633f35',
},
asset: asset2,
asset: {
__typename: 'Asset',
id: '5cfa87844724df6069b94e4c8a6f03af21907d7bc251593d08e4251043ee9f7c',
symbol: 'aBTC',
decimals: 5,
},
available: '125600001',
used: '125600001',
total: '251200002',
@@ -137,7 +134,7 @@ describe('AccountsTable', () => {
it('should sort assets', async () => {
// 7001-COLL-010
render(
const { container } = render(
<AccountTable
rowData={multiRowData}
onClickAsset={() => null}
@@ -145,13 +142,13 @@ describe('AccountsTable', () => {
/>
);
const headerCell = screen
.getAllByRole('columnheader')
.find((h) => h?.getAttribute('col-id') === 'asset.symbol') as HTMLElement;
await userEvent.click(within(headerCell).getByText(/asset/i));
expect(headerCell).toHaveAttribute('aria-sort', 'ascending');
const headerCell = screen.getByText('Asset');
await userEvent.click(headerCell);
const rows = container.querySelectorAll(
'.ag-center-cols-container .ag-row'
);
expect(rows[0].textContent).toContain('aBTC');
expect(rows[1].textContent).toContain('tBTC');
});
it('should apply correct formatting in view as user mode', async () => {
@@ -179,7 +176,12 @@ describe('AccountsTable', () => {
rowData={singleRowData}
onClickAsset={() => null}
isReadOnly={false}
pinnedAsset={asset1}
pinnedAsset={{
decimals: 5,
id: '5cfa87844724df6069b94e4c8a6f03af21907d7bc251593d08e4251043ee9f7c',
symbol: 'tBTC',
name: 'tBTC',
}}
/>
);
await screen.findAllByRole('rowgroup');
@@ -211,13 +213,23 @@ describe('AccountsTable', () => {
const result = getAccountData([singleRow]);
const expected = [
{
asset: asset1,
asset: {
__typename: 'Asset',
decimals: 5,
id: '5cfa87844724df6069b94e4c8a6f03af21907d7bc251593d08e4251043ee9f7c',
symbol: 'tBTC',
},
available: '0',
balance: '0',
breakdown: [
{
__typename: 'AccountBalance',
asset: asset1,
asset: {
__typename: 'Asset',
decimals: 5,
id: '5cfa87844724df6069b94e4c8a6f03af21907d7bc251593d08e4251043ee9f7c',
symbol: 'tBTC',
},
available: '0',
balance: '125600000',
total: '125600000',
+10 -94
View File
@@ -1,10 +1,4 @@
import {
fireEvent,
render,
screen,
waitFor,
within,
} from '@testing-library/react';
import { fireEvent, render, screen, waitFor } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import BigNumber from 'bignumber.js';
import {
@@ -13,7 +7,7 @@ import {
TransferForm,
type TransferFormProps,
} from './transfer-form';
import { AccountType, AccountTypeMapping } from '@vegaprotocol/types';
import { AccountType } from '@vegaprotocol/types';
import { removeDecimal } from '@vegaprotocol/utils';
describe('TransferForm', () => {
@@ -45,7 +39,8 @@ describe('TransferForm', () => {
};
const amount = '100';
const pubKey = '1'.repeat(64);
const pubKey =
'70d14a321e02e71992fd115563df765000ccc4775cbe71a0e2f9ff5a3b9dc680';
const asset = {
id: 'eur',
symbol: '€',
@@ -55,7 +50,10 @@ describe('TransferForm', () => {
};
const props = {
pubKey,
pubKeys: [pubKey, '2'.repeat(64)],
pubKeys: [
pubKey,
'a4b6e3de5d7ef4e31ae1b090be49d1a2ef7bcefff60cccf7658a0d4922651cce',
],
feeFactor: '0.001',
submitTransfer: jest.fn(),
accounts: [
@@ -184,7 +182,7 @@ describe('TransferForm', () => {
// Test use max button
await userEvent.click(screen.getByRole('button', { name: 'Use max' }));
expect(amountInput).toHaveValue('1000.00');
expect(amountInput).toHaveValue('1000');
// Test amount validation
await userEvent.clear(amountInput);
@@ -269,7 +267,7 @@ describe('TransferForm', () => {
// Test use max button
await userEvent.click(screen.getByRole('button', { name: 'Use max' }));
expect(amountInput).toHaveValue('100.00');
expect(amountInput).toHaveValue('100');
// If transfering from a vested account 'include fees' checkbox should
// be disabled and fees should be 0
@@ -298,88 +296,6 @@ describe('TransferForm', () => {
});
});
it('handles lots of decimal places', async () => {
const balance = '904195168829277777';
const expectedBalance = '0.904195168829277777';
const longDecimalAsset = {
id: 'assetId',
symbol: 'VEGA',
name: 'VEGA',
decimals: 18,
quantum: '1',
};
const account = {
type: AccountType.ACCOUNT_TYPE_VESTED_REWARDS,
asset: longDecimalAsset,
balance,
};
const mockSubmit = jest.fn();
renderComponent({
...props,
accounts: [account],
submitTransfer: mockSubmit,
minQuantumMultiple: '100000',
});
// Select a pubkey
await userEvent.selectOptions(
screen.getByLabelText('To Vega key'),
props.pubKeys[1] // Use not current pubkey so we can check it switches to current pubkey later
);
// Select asset
await selectAsset(longDecimalAsset);
const accountSelect = screen.getByLabelText('From account');
const option = within(accountSelect)
.getAllByRole('option')
.find(
(o) => o.getAttribute('value') === `${account.type}-${account.asset.id}`
);
// plus one for disabled 'please select' option
expect(option).toHaveTextContent(
`${AccountTypeMapping[account.type]} (${expectedBalance} ${
account.asset.symbol
})`
);
await userEvent.selectOptions(
accountSelect,
`${AccountType.ACCOUNT_TYPE_VESTED_REWARDS}-${longDecimalAsset.id}`
);
expect(accountSelect).toHaveValue(
`${AccountType.ACCOUNT_TYPE_VESTED_REWARDS}-${longDecimalAsset.id}`
);
// Check switch back to connected key
const amountInput = screen.getByLabelText('Amount');
// Test use max button
await userEvent.click(screen.getByRole('button', { name: 'Use max' }));
expect(amountInput).toHaveValue(expectedBalance);
await submit();
await waitFor(() => {
// 1003-TRAN-023
expect(mockSubmit).toHaveBeenCalledTimes(1);
expect(mockSubmit).toHaveBeenCalledWith({
fromAccountType: AccountType.ACCOUNT_TYPE_VESTED_REWARDS,
toAccountType: AccountType.ACCOUNT_TYPE_GENERAL,
to: props.pubKey,
asset: longDecimalAsset.id,
amount: balance,
oneOff: {},
});
});
});
describe('IncludeFeesCheckbox', () => {
it('validates fields and submits when checkbox is checked', async () => {
const mockSubmit = jest.fn();
+10 -4
View File
@@ -5,6 +5,7 @@ import {
vegaPublicKey,
addDecimal,
formatNumber,
addDecimalsFormatNumber,
toBigNum,
} from '@vegaprotocol/utils';
import { t } from '@vegaprotocol/i18n';
@@ -213,7 +214,12 @@ export const TransferForm = ({
<AssetOption
key={a.key}
asset={a}
balance={<Balance balance={a.balance} symbol={a.symbol} />}
balance={
<Balance
balance={formatNumber(a.balance, a.decimals)}
symbol={a.symbol}
/>
}
/>
))}
</TradingRichSelect>
@@ -280,8 +286,8 @@ export const TransferForm = ({
return (
<option value={id} key={id}>
{AccountTypeMapping[a.type]} (
{addDecimal(a.balance, a.asset.decimals)} {a.asset.symbol}
)
{addDecimalsFormatNumber(a.balance, a.asset.decimals)}{' '}
{a.asset.symbol})
</option>
);
})}
@@ -407,7 +413,7 @@ export const TransferForm = ({
type="button"
className="absolute top-0 right-0 ml-auto text-xs underline"
onClick={() =>
setValue('amount', accountBalance, {
setValue('amount', parseFloat(accountBalance).toString(), {
shouldValidate: true,
})
}
@@ -151,7 +151,6 @@ export const DealTicketMarginDetails = ({
const { decimals: assetDecimals, quantum } = asset;
let marginRequiredBestCase: string | undefined = undefined;
let marginRequiredWorstCase: string | undefined = undefined;
if (marginEstimate) {
if (currentMargins) {
marginRequiredBestCase = (
@@ -289,7 +288,7 @@ export const DealTicketMarginDetails = ({
const quoteName = getQuoteName(market);
return (
<div className="flex flex-col w-full gap-2 pt-2">
<div className="flex flex-col w-full gap-2">
<Accordion>
<AccordionPanel
itemId="margin"
@@ -297,7 +296,7 @@ export const DealTicketMarginDetails = ({
<AccordionPrimitive.Trigger
data-testid="accordion-toggle"
className={classNames(
'w-full',
'w-full pt-2',
'flex items-center gap-2 text-xs',
'group'
)}
-16
View File
@@ -28,22 +28,6 @@ export const getAsset = (market: Partial<Market>) => {
throw new Error('Failed to retrieve asset. Invalid product type');
};
export const getProductType = (market: Partial<Market>) => {
if (!market.tradableInstrument?.instrument.product) {
throw new Error(
'Failed to retrieve product type. Invalid tradable instrument'
);
}
const type = market.tradableInstrument.instrument.product.__typename;
if (!type) {
throw new Error('Failed to retrieve asset. Invalid product type');
}
return type;
};
export const getQuoteName = (market: Partial<Market>) => {
if (!market.tradableInstrument?.instrument.product) {
throw new Error(