Skip to content

Commit

Permalink
v7.4.5
Browse files Browse the repository at this point in the history
v7.4.5
  • Loading branch information
platschi authored Jul 19, 2023
2 parents 29c8165 + 66f6ff2 commit 49aac27
Show file tree
Hide file tree
Showing 44 changed files with 762 additions and 239 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "kwenta",
"version": "7.4.4",
"version": "7.4.5",
"description": "Kwenta",
"main": "index.js",
"scripts": {
Expand Down
2 changes: 1 addition & 1 deletion packages/app/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@kwenta/app",
"version": "7.4.4",
"version": "7.4.5",
"scripts": {
"dev": "next",
"build": "next build",
Expand Down
206 changes: 205 additions & 1 deletion packages/app/src/__tests__/pages/market.test.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
import { FuturesMarket } from '@kwenta/sdk/dist/types'
import { FuturesMarket, PositionSide } from '@kwenta/sdk/types'
import { wei } from '@synthetixio/wei'
import { fireEvent, render, waitFor } from '@testing-library/react'
import { ReactNode } from 'react'

import { mockFuturesService } from 'state/__mocks__/sdk'
import { fetchMarkets } from 'state/futures/actions'

import { mockResizeObserver } from '../../../testing/unit/mocks/app'
import { PRELOADED_STATE } from '../../../testing/unit/mocks/data/app'
import {
MOCK_TRADE_PREVIEW,
mockSmartMarginAccount,
preloadedStateWithSmartMarginAccount,
SDK_MARKETS,
Expand Down Expand Up @@ -46,6 +48,12 @@ describe('Futures market page - smart margin', () => {
mockConnector()
})

beforeEach(() => {
// Reset the SDK mock
// @ts-ignore
sdk.futures = mockFuturesService()
})

test('Calculates correct fees from trade preview', async () => {
const { findByTestId, findByText } = render(
<MockProviders
Expand Down Expand Up @@ -194,3 +202,199 @@ describe('Futures market page - smart margin', () => {
expect(submitButton).toBeDisabled()
})
})

describe('Futures market page - stop loss validation', () => {
beforeAll(() => {
jest.setTimeout(60000)
mockUseWindowSize()
mockReactQuery()
mockResizeObserver()
mockConnector()
})

beforeEach(() => {
// Reset the SDK mock
// @ts-ignore
sdk.futures = mockFuturesService()
})

test('Restricts stop loss for LONG trade at correct price depending on leverage', 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')
expect(submitButton).toBeEnabled()

const expandButton = await findByTestId('expand-sl-tp-button')
fireEvent.click(expandButton)

const approveButton = await findByTestId('sl-tp-ack-proceed')
fireEvent.click(approveButton)

const stopLossInput = await findByTestId('trade-panel-stop-loss-input')
fireEvent.change(stopLossInput, { target: { value: '1700' } })

// Min / Max SL is shown when invalid
const slMinMaxLabel = await findByText('Min: 1,735.52')
expect(slMinMaxLabel).toBeTruthy()
expect(submitButton).toBeDisabled()

// Input valid when above min
fireEvent.change(stopLossInput, { target: { value: '1750' } })
expect(submitButton).toBeEnabled()
})

test('Restricts stop loss for SHORT trade at correct price depending on leverage', async () => {
const store = setupStore(preloadedStateWithSmartMarginAccount())
const { findByTestId, findByText } = render(
<MockProviders route="market/?accountType=cross_margin&asset=sETH" store={store}>
<Market />
</MockProviders>
)

sdk.futures.getCrossMarginTradePreview = () =>
Promise.resolve({
...MOCK_TRADE_PREVIEW,
liqPrice: wei('2172.467580351348039045'),
side: PositionSide.SHORT,
size: wei('-0.541100000000000000'),
})

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')
expect(submitButton).toBeEnabled()

const expandButton = await findByTestId('expand-sl-tp-button')
fireEvent.click(expandButton)

const approveButton = await findByTestId('sl-tp-ack-proceed')
fireEvent.click(approveButton)

const stopLossInput = await findByTestId('trade-panel-stop-loss-input')
fireEvent.change(stopLossInput, { target: { value: '2150' } })

// Min / Max SL is shown when invalid
// Liqudation price is 2,172.46 and stop is limited to 2,100.07
const slMinMaxLabel = await findByText('Max: 2,107.29')
expect(slMinMaxLabel).toBeTruthy()

expect(submitButton).toBeDisabled()

// Input valid when below max
fireEvent.change(stopLossInput, { target: { value: '2099' } })
expect(submitButton).toBeEnabled()
})

test('Stop loss becomes disabled above a certain leverage', async () => {
const store = setupStore(preloadedStateWithSmartMarginAccount())
const { findByTestId, findByText } = render(
<MockProviders route="market/?accountType=cross_margin&asset=sETH" store={store}>
<Market />
</MockProviders>
)

sdk.futures.getCrossMarginTradePreview = () =>
Promise.resolve({
...MOCK_TRADE_PREVIEW,
liqPrice: wei('1760'),
size: wei('1.1'),
leverage: wei('20'),
})

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: '2000' } })

const fees = await findByText('$1.69')
expect(fees).toBeTruthy()

const submitButton = await findByTestId('trade-panel-submit-button')
expect(submitButton).toBeEnabled()

const expandButton = await findByTestId('expand-sl-tp-button')
fireEvent.click(expandButton)

const approveButton = await findByTestId('sl-tp-ack-proceed')
fireEvent.click(approveButton)

const stopLossInput = await findByTestId('trade-panel-stop-loss-input')

await findByText('Leverage Too High')
expect(stopLossInput).toBeDisabled()
})

test('Displays stop-loss warning in confirmation view when within 5% of liquidation price', async () => {
const store = setupStore(preloadedStateWithSmartMarginAccount())
const { findByTestId, findByText } = render(
<MockProviders route="market/?accountType=cross_margin&asset=sETH" store={store}>
<Market />
</MockProviders>
)

sdk.futures.getCrossMarginTradePreview = () =>
Promise.resolve({
...MOCK_TRADE_PREVIEW,
liqPrice: wei('2172.467580351348039045'),
side: PositionSide.SHORT,
size: wei('-0.5411'),
})

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 expandButton = await findByTestId('expand-sl-tp-button')
fireEvent.click(expandButton)

const approveButton = await findByTestId('sl-tp-ack-proceed')
fireEvent.click(approveButton)

const stopLossInput = await findByTestId('trade-panel-stop-loss-input')
fireEvent.change(stopLossInput, { target: { value: '2090' } })

const submitButton = await findByTestId('trade-panel-submit-button')
fireEvent.click(submitButton)

// Trade confirm button is disabled until the user acknowledges the warning
const confirmButton = await findByTestId('trade-confirm-order-button')
expect(confirmButton).toBeDisabled()

const warningCheck = await findByTestId('sl-risk-warning')
fireEvent.click(warningCheck)
expect(confirmButton).toBeEnabled()
})
})
3 changes: 3 additions & 0 deletions packages/app/src/assets/svg/app/docs.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions packages/app/src/assets/svg/app/support.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
38 changes: 38 additions & 0 deletions packages/app/src/components/AcceptWarningView.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import styled from 'styled-components'

import { Checkbox } from 'components/Checkbox'

type Props = {
checked: boolean
message: string
style?: Record<string, string>
id?: string
onChangeChecked: (checked: boolean) => void
}

export default function AcceptWarningView({ checked, id, onChangeChecked, style, message }: Props) {
return (
<Container style={style}>
<Checkbox
id={id ?? 'accept-warning'}
data-testid={id}
label={message}
checkSide="right"
checked={checked}
color="yellow"
onChange={() => onChangeChecked(!checked)}
/>
</Container>
)
}

const Container = styled.div<{ style?: Record<string, string> }>`
color: ${(props) => props.theme.colors.selectedTheme.button.yellow.text};
font-size: 12px;
margin: ${(props) => props.style?.margin ?? '0'};
padding: 15px;
border: 1px solid rgba(239, 104, 104, 0);
background: ${(props) => props.theme.colors.selectedTheme.button.yellow.fill};
border-radius: 8px;
cursor: default;
`
Loading

1 comment on commit 49aac27

@vercel
Copy link

@vercel vercel bot commented on 49aac27 Jul 19, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

kwenta – ./packages/app

kwenta.io
kwenta-git-main-kwenta.vercel.app
kwenta-kwenta.vercel.app

Please sign in to comment.