-
Notifications
You must be signed in to change notification settings - Fork 153
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
chore: market page tests and jest environment update (#2529)
* Update market tests * Add Github action workflow for jest tests * Update tests CI workflow * Add pnpm i step to workflow * Clean up * Fix sdk mock * Update Jest config * Fix warnings * Update tests CI config * Update market test and add codecov action * Rename InfoBox textValueSpan prop to textValueIcon * Remove unused type * Correct market closed test * Update codecov workflow * Temp comment out test * fix: lint warnings * fix: jest workflow * fix: sentry workflow * Mock rainbowkit for all tests * Add codecov yml to enforce coverage --------- Co-authored-by: Ralf <platschi@posteo.org>
- Loading branch information
Showing
50 changed files
with
830 additions
and
284 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
coverage: | ||
precision: 2 | ||
round: down | ||
range: '50...85' # Will lift this number as coverage increases | ||
|
||
status: | ||
project: | ||
default: | ||
# basic | ||
target: auto | ||
threshold: 1% | ||
base: auto | ||
patch: | ||
default: | ||
# basic | ||
target: 80% | ||
threshold: 1% | ||
base: auto | ||
|
||
ignore: | ||
- 'packages/sdk/.*' # Waiting for sdk tests |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
name: 'Jest' | ||
on: | ||
push: | ||
branches: | ||
- master | ||
pull_request: | ||
|
||
jobs: | ||
sentry_release: | ||
name: Jest tests | ||
runs-on: ubuntu-latest | ||
|
||
steps: | ||
- name: Checkout code | ||
uses: actions/checkout@v3 | ||
with: | ||
fetch-depth: 0 | ||
|
||
- name: Setup Node.js environment | ||
uses: actions/setup-node@v3 | ||
with: | ||
node-version: 16.x | ||
|
||
- uses: pnpm/action-setup@v2 | ||
name: Install pnpm | ||
id: pnpm-install | ||
with: | ||
version: 8 | ||
run_install: false | ||
|
||
- name: Install dependencies | ||
run: pnpm i | ||
|
||
- name: Run tests | ||
run: cd packages/app && pnpm run test:jest | ||
env: | ||
NEXT_PUBLIC_WALLETCONNECT_V2_ID: ${{ secrets.NEXT_PUBLIC_WALLETCONNECT_V2_ID }} | ||
|
||
- name: Upload coverage to codecov.io | ||
uses: codecov/codecov-action@v3 | ||
env: | ||
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,25 +1,30 @@ | ||
const nextJest = require('next/jest'); | ||
const nextJest = require('next/jest') | ||
|
||
const createJestConfig = nextJest({ dir: './' }); | ||
const createJestConfig = nextJest({ dir: './' }) | ||
|
||
const customJestConfig = { | ||
roots: ['<rootDir>'], | ||
modulePaths: ['<rootDir>'], | ||
moduleDirectories: ['node_modules'], | ||
roots: ['<rootDir>', 'src'], | ||
modulePaths: ['<rootDir>', 'src'], | ||
moduleDirectories: ['node_modules', 'src'], | ||
moduleNameMapper: { | ||
'@kwenta/sdk/(.+)$': '<rootDir>/../sdk/dist/$1', | ||
'@kwenta/sdk': '<rootDir>/../sdk/dist/index.js', | ||
}, | ||
globalSetup: './testing/unit/setup/global.js', | ||
setupFilesAfterEnv: ['./testing/unit/setup/setup.js'], | ||
testEnvironment: 'jest-environment-jsdom', | ||
transform: { | ||
'^.+\\.(svg)$': `jest-transformer-svg`, | ||
}, | ||
}; | ||
} | ||
|
||
const getCustomConfig = async () => { | ||
// Delete next js module name mapper transform and use above svg | ||
// transformer to avoid errors with svg and styled components | ||
const config = await createJestConfig(customJestConfig)(); | ||
delete config['moduleNameMapper']['^.+\\.(svg)$']; | ||
return config; | ||
}; | ||
const config = await createJestConfig(customJestConfig)() | ||
delete config['moduleNameMapper']['^.+\\.(svg)$'] | ||
config.transformIgnorePatterns = [] | ||
return config | ||
} | ||
|
||
module.exports = getCustomConfig(); | ||
module.exports = getCustomConfig() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,196 @@ | ||
import { FuturesMarket } from '@kwenta/sdk/dist/types' | ||
import { wei } from '@synthetixio/wei' | ||
import { fireEvent, render, waitFor } from '@testing-library/react' | ||
import { ReactNode } from 'react' | ||
|
||
import { fetchMarkets } from 'state/futures/actions' | ||
|
||
import { mockResizeObserver } from '../../../testing/unit/mocks/app' | ||
import { PRELOADED_STATE } from '../../../testing/unit/mocks/data/app' | ||
import { | ||
mockSmartMarginAccount, | ||
preloadedStateWithSmartMarginAccount, | ||
SDK_MARKETS, | ||
} from '../../../testing/unit/mocks/data/futures' | ||
import { mockUseWindowSize } from '../../../testing/unit/mocks/hooks' | ||
import mockConnector from '../../../testing/unit/mocks/mockConnector' | ||
import MockProviders from '../../../testing/unit/mocks/MockProviders' | ||
import { mockReactQuery } from '../../../testing/unit/mocks/queries' | ||
import Market from '../../pages/market' | ||
import { selectTradePreview } from '../../state/futures/selectors' | ||
import sdk from '../../state/sdk' | ||
import { setupStore } from '../../state/store' | ||
|
||
jest.mock('../../state/sdk') | ||
|
||
jest.mock('../../queries/futures/useGetFuturesTrades', () => { | ||
return jest.fn(() => ({ | ||
data: [], | ||
isLoading: false, | ||
fetchNextPage: () => {}, | ||
})) | ||
}) | ||
|
||
jest.mock('../../components/Media', () => ({ | ||
...jest.requireActual('../../components/Media'), | ||
DesktopOnlyView: ({ children }: { children: ReactNode }) => <div>{children}</div>, | ||
MobileOnlyView: ({ children }: { children: ReactNode }) => <div>{children}</div>, | ||
})) | ||
|
||
describe('Futures market page - smart margin', () => { | ||
beforeAll(() => { | ||
jest.setTimeout(60000) | ||
mockUseWindowSize() | ||
mockReactQuery() | ||
mockResizeObserver() | ||
mockConnector() | ||
}) | ||
|
||
test('Calculates correct fees from trade preview', async () => { | ||
const { findByTestId, findByText } = render( | ||
<MockProviders | ||
route="market/?accountType=cross_margin&asset=sETH" | ||
preloadedState={PRELOADED_STATE} | ||
> | ||
<Market /> | ||
</MockProviders> | ||
) | ||
|
||
const marginInput = await findByTestId('set-order-margin-susd-desktop') | ||
fireEvent.change(marginInput, { target: { value: '100' } }) | ||
|
||
const sizeInput = await findByTestId('set-order-size-amount-susd-desktop') | ||
fireEvent.change(sizeInput, { target: { value: '1000' } }) | ||
|
||
const fees = await findByText('$1.69') | ||
expect(fees).toBeTruthy() | ||
}) | ||
|
||
test('Submits LONG order with correct desired fill price', async () => { | ||
const store = setupStore(preloadedStateWithSmartMarginAccount()) | ||
const { findByTestId, findByText } = render( | ||
<MockProviders route="market/?accountType=cross_margin&asset=sETH" store={store}> | ||
<Market /> | ||
</MockProviders> | ||
) | ||
|
||
const marginInput = await findByTestId('set-order-margin-susd-desktop') | ||
fireEvent.change(marginInput, { target: { value: '100' } }) | ||
|
||
const sizeInput = await findByTestId('set-order-size-amount-susd-desktop') | ||
fireEvent.change(sizeInput, { target: { value: '1000' } }) | ||
|
||
const fees = await findByText('$1.69') | ||
expect(fees).toBeTruthy() | ||
|
||
const submitButton = await findByTestId('trade-panel-submit-button') | ||
fireEvent.click(submitButton) | ||
|
||
const confirmButton = await findByTestId('trade-confirm-order-button') | ||
fireEvent.click(confirmButton) | ||
|
||
// Preview generated fill price displayed in confirmation view | ||
const fillPrice = await findByText('$1,847.76') | ||
expect(fillPrice).toBeTruthy() | ||
|
||
// Desired fill price is higher than fill price by 1% | ||
// (as a long order the price is worse to account for slippage in delayed order) | ||
expect(selectTradePreview(store.getState())?.desiredFillPrice.toString()).toBe( | ||
'1866.234411491951332934' | ||
) | ||
}) | ||
|
||
test('Submits SHORT order with correct desired fill price', async () => { | ||
const store = setupStore(preloadedStateWithSmartMarginAccount()) | ||
const { findByTestId, findByText } = render( | ||
<MockProviders route="market/?accountType=cross_margin&asset=sETH" store={store}> | ||
<Market /> | ||
</MockProviders> | ||
) | ||
|
||
const shortToggle = await findByTestId('position-side-short-button') | ||
fireEvent.click(shortToggle) | ||
|
||
const marginInput = await findByTestId('set-order-margin-susd-desktop') | ||
fireEvent.change(marginInput, { target: { value: '100' } }) | ||
|
||
const sizeInput = await findByTestId('set-order-size-amount-susd-desktop') | ||
fireEvent.change(sizeInput, { target: { value: '1000' } }) | ||
|
||
const fees = await findByText('$1.69') | ||
expect(fees).toBeTruthy() | ||
|
||
const submitButton = await findByTestId('trade-panel-submit-button') | ||
fireEvent.click(submitButton) | ||
|
||
const confirmButton = await findByTestId('trade-confirm-order-button') | ||
fireEvent.click(confirmButton) | ||
|
||
// Preview generated fill price displayed in confirmation view | ||
const fillPrice = await findByText('$1,847.76') | ||
expect(fillPrice).toBeTruthy() | ||
|
||
// Desired fill price is lower than fill price by 1% | ||
// (as a short order the price is worse to account for slippage in delayed order) | ||
expect(selectTradePreview(store.getState())?.desiredFillPrice.toString()).toBe( | ||
'1829.279274630724573866' | ||
) | ||
}) | ||
|
||
test('Displays error when trade exceeds max OI', async () => { | ||
// Update the mock to return some different data | ||
sdk.futures.getMarkets = () => | ||
Promise.resolve([{ ...SDK_MARKETS[1], marketLimitUsd: wei(100000) } as FuturesMarket]) | ||
|
||
const store = setupStore( | ||
preloadedStateWithSmartMarginAccount(mockSmartMarginAccount('1000000')) | ||
) | ||
const { findByTestId, findByText } = render( | ||
<MockProviders route="market/?accountType=cross_margin&asset=sETH" store={store}> | ||
<Market /> | ||
</MockProviders> | ||
) | ||
|
||
const marginInput = await findByTestId('set-order-margin-susd-desktop') | ||
fireEvent.change(marginInput, { target: { value: '100000' } }) | ||
|
||
const sizeInput = await findByTestId('set-order-size-amount-susd-desktop') | ||
fireEvent.change(sizeInput, { target: { value: '1000000' } }) | ||
|
||
// OI limit warning displayed | ||
const fillPrice = await findByText('Open interest limit exceeded') | ||
expect(fillPrice).toBeTruthy() | ||
}) | ||
|
||
test('Trade panel is disabled when market is closed', async () => { | ||
sdk.futures.getMarkets = () => Promise.resolve([...SDK_MARKETS] as FuturesMarket[]) | ||
const store = setupStore(preloadedStateWithSmartMarginAccount()) | ||
const { findByTestId, findByText } = render( | ||
<MockProviders route="market/?accountType=cross_margin&asset=sETH" store={store}> | ||
<Market /> | ||
</MockProviders> | ||
) | ||
|
||
const marginInput = await findByTestId('set-order-margin-susd-desktop') | ||
fireEvent.change(marginInput, { target: { value: '100' } }) | ||
|
||
const sizeInput = await findByTestId('set-order-size-amount-susd-desktop') | ||
fireEvent.change(sizeInput, { target: { value: '1000' } }) | ||
|
||
const fees = await findByText('$1.69') | ||
expect(fees).toBeTruthy() | ||
|
||
const submitButton = await findByTestId('trade-panel-submit-button') | ||
expect(submitButton).toBeEnabled() | ||
|
||
sdk.futures.getMarkets = () => | ||
Promise.resolve([{ ...SDK_MARKETS[1], isSuspended: true } as FuturesMarket]) | ||
|
||
waitFor(() => store.dispatch(fetchMarkets())) | ||
|
||
const message = await findByText('Market suspended') | ||
expect(message).toBeTruthy() | ||
|
||
expect(submitButton).toBeDisabled() | ||
}) | ||
}) |
Oops, something went wrong.