Skip to content

Commit f3a4e9c

Browse files
committed
fix more tests
1 parent 99eea9d commit f3a4e9c

File tree

6 files changed

+720
-227
lines changed

6 files changed

+720
-227
lines changed
Lines changed: 143 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -1,82 +1,177 @@
11
import { V4PositionManager } from '@uniswap/v4-sdk'
2+
import { Percent } from '@uniswap/sdk-core'
23
import { beforeEach, describe, expect, it, vi } from 'vitest'
34
import { createMockSdkInstance } from '@/test/helpers/sdkInstance'
4-
import { createMockPositionData } from '@/test/helpers/testFactories'
5+
import { createMockPositionData, createTestPool } from '@/test/helpers/testFactories'
56
import { getPosition } from '@/utils/getPosition'
7+
import { getDefaultDeadline } from '@/utils/getDefaultDeadline'
8+
import { percentFromBips } from '@/helpers/percent'
9+
import { DEFAULT_SLIPPAGE_TOLERANCE } from '@/constants/common'
10+
import type { GetPositionResponse } from '@/types/utils/getPosition'
11+
import { buildRemoveLiquidityCallData } from '@/utils/buildRemoveLiquidityCallData'
612

7-
const instance = createMockSdkInstance()
8-
const mockPosition = createMockPositionData()
13+
// Test constants
14+
const MOCK_DEADLINE = BigInt(1234567890)
15+
const MOCK_DEADLINE_STRING = '1234567890'
16+
const MOCK_SLIPPAGE_PERCENT = new Percent(50, 10000) // 0.5%
17+
const MOCK_CALLDATA = '0x1234567890abcdef'
18+
const MOCK_VALUE = '0x0'
19+
const CUSTOM_SLIPPAGE_BIPS = 500 // 5%
20+
const CUSTOM_DEADLINE = '1234567890'
21+
const CUSTOM_LIQUIDITY_PERCENTAGE = 7500 // 75%
22+
const MOCK_TOKEN_ID = '123'
923

24+
// Mock the V4PositionManager.removeCallParameters method
25+
vi.mock('@uniswap/v4-sdk', async (importOriginal) => {
26+
const actual = await importOriginal<typeof import('@uniswap/v4-sdk')>()
27+
return {
28+
...actual,
29+
V4PositionManager: {
30+
...actual.V4PositionManager,
31+
removeCallParameters: vi.fn(),
32+
},
33+
}
34+
})
35+
36+
// Mock getPosition
1037
vi.mock('@/utils/getPosition', () => ({
1138
getPosition: vi.fn(),
1239
}))
1340

41+
// Mock getDefaultDeadline
1442
vi.mock('@/utils/getDefaultDeadline', () => ({
15-
getDefaultDeadline: vi.fn().mockResolvedValue('1234567890'),
43+
getDefaultDeadline: vi.fn(),
1644
}))
1745

46+
// Mock percentFromBips
47+
vi.mock('@/helpers/percent', () => ({
48+
percentFromBips: vi.fn(),
49+
}))
50+
51+
// Type for the options passed to V4PositionManager.removeCallParameters
52+
type RemoveCallParametersOptions = {
53+
slippageTolerance: unknown
54+
deadline: string
55+
liquidityPercentage: unknown
56+
tokenId: string
57+
}
58+
1859
describe('buildRemoveLiquidityCallData', () => {
60+
const instance = createMockSdkInstance()
61+
const pool = createTestPool()
62+
const mockPositionData = createMockPositionData(pool)
63+
64+
// Get mocked functions at module level
65+
const mockRemoveCallParameters = vi.mocked(V4PositionManager.removeCallParameters)
66+
const mockGetPosition = vi.mocked(getPosition)
67+
const mockGetDefaultDeadline = vi.mocked(getDefaultDeadline)
68+
const mockPercentFromBips = vi.mocked(percentFromBips)
69+
1970
beforeEach(() => {
20-
vi.resetAllMocks()
21-
})
71+
vi.clearAllMocks()
2272

23-
it('should build calldata for removing liquidity', async () => {
24-
vi.mocked(getPosition).mockResolvedValueOnce(mockPosition)
25-
vi.spyOn(V4PositionManager, 'removeCallParameters').mockReturnValueOnce({
26-
calldata: '0x123',
27-
value: '0',
73+
// Default mock implementations
74+
mockRemoveCallParameters.mockReturnValue({
75+
calldata: MOCK_CALLDATA,
76+
value: MOCK_VALUE,
2877
})
2978

30-
const { buildRemoveLiquidityCallData } = await import('@/utils/buildRemoveLiquidityCallData')
31-
const result = await buildRemoveLiquidityCallData(
32-
{ liquidityPercentage: 10_000, tokenId: '1', deadline: '123' },
33-
instance,
34-
)
35-
36-
expect(result.calldata).toBe('0x123')
37-
expect(result.value).toBe('0')
79+
mockGetPosition.mockResolvedValue(mockPositionData)
80+
mockGetDefaultDeadline.mockResolvedValue(MOCK_DEADLINE)
81+
mockPercentFromBips.mockReturnValue(MOCK_SLIPPAGE_PERCENT)
3882
})
3983

40-
it('should use custom slippageTolerance', async () => {
41-
vi.mocked(getPosition).mockResolvedValueOnce(mockPosition)
42-
const spy = vi.spyOn(V4PositionManager, 'removeCallParameters').mockReturnValueOnce({
43-
calldata: '0xabc',
44-
value: '1',
84+
it('should call V4PositionManager.removeCallParameters with correct parameters when all required params are provided', async () => {
85+
const params = {
86+
liquidityPercentage: 10_000, // 100%
87+
tokenId: MOCK_TOKEN_ID,
88+
deadline: CUSTOM_DEADLINE,
89+
slippageTolerance: CUSTOM_SLIPPAGE_BIPS,
90+
}
91+
92+
const result = await buildRemoveLiquidityCallData(params, instance)
93+
94+
// Verify getPosition was called with correct tokenId
95+
expect(mockGetPosition).toHaveBeenCalledWith({ tokenId: MOCK_TOKEN_ID }, instance)
96+
97+
// Verify getDefaultDeadline was NOT called since custom deadline was provided
98+
expect(mockGetDefaultDeadline).not.toHaveBeenCalled()
99+
100+
// Verify percentFromBips was called with custom slippage
101+
expect(mockPercentFromBips).toHaveBeenCalledWith(CUSTOM_SLIPPAGE_BIPS)
102+
expect(mockPercentFromBips).toHaveBeenCalledWith(10_000) // liquidityPercentage
103+
104+
// Verify V4PositionManager.removeCallParameters was called with exact parameters
105+
expect(mockRemoveCallParameters).toHaveBeenCalledTimes(1)
106+
const [position, options] = mockRemoveCallParameters.mock.calls[0]
107+
108+
expect(position).toBe(mockPositionData.position)
109+
expect(options).toEqual({
110+
slippageTolerance: MOCK_SLIPPAGE_PERCENT,
111+
deadline: CUSTOM_DEADLINE,
112+
liquidityPercentage: MOCK_SLIPPAGE_PERCENT, // percentFromBips result for liquidityPercentage
113+
tokenId: MOCK_TOKEN_ID,
45114
})
46115

47-
const { buildRemoveLiquidityCallData } = await import('@/utils/buildRemoveLiquidityCallData')
48-
await buildRemoveLiquidityCallData(
49-
{ liquidityPercentage: 5000, tokenId: '1', slippageTolerance: 123, deadline: '123' },
50-
instance,
116+
// Verify return value
117+
expect(result).toEqual({
118+
calldata: MOCK_CALLDATA,
119+
value: MOCK_VALUE,
120+
})
121+
})
122+
123+
it('should call V4PositionManager.removeCallParameters with default deadline when not provided', async () => {
124+
const params = {
125+
liquidityPercentage: CUSTOM_LIQUIDITY_PERCENTAGE,
126+
tokenId: MOCK_TOKEN_ID,
127+
}
128+
129+
await buildRemoveLiquidityCallData(params, instance)
130+
131+
// Verify getDefaultDeadline was called
132+
expect(mockGetDefaultDeadline).toHaveBeenCalledWith(instance)
133+
134+
// Verify percentFromBips was called with default slippage
135+
expect(mockPercentFromBips).toHaveBeenCalledWith(DEFAULT_SLIPPAGE_TOLERANCE)
136+
expect(mockPercentFromBips).toHaveBeenCalledWith(CUSTOM_LIQUIDITY_PERCENTAGE)
137+
138+
expect(mockRemoveCallParameters).toHaveBeenCalledTimes(1)
139+
const [, options] = mockRemoveCallParameters.mock.calls[0]
140+
141+
expect((options as RemoveCallParametersOptions).deadline).toBe(MOCK_DEADLINE_STRING)
142+
expect((options as RemoveCallParametersOptions).slippageTolerance).toEqual(
143+
MOCK_SLIPPAGE_PERCENT,
51144
)
145+
})
52146

53-
expect(spy).toHaveBeenCalledWith(
54-
mockPosition.position,
55-
expect.objectContaining({ slippageTolerance: expect.any(Object) }),
147+
it('should call V4PositionManager.removeCallParameters with default slippage when not provided', async () => {
148+
const params = {
149+
liquidityPercentage: 5000, // 50%
150+
tokenId: MOCK_TOKEN_ID,
151+
deadline: CUSTOM_DEADLINE,
152+
}
153+
154+
await buildRemoveLiquidityCallData(params, instance)
155+
156+
// Verify percentFromBips was called with default slippage
157+
expect(mockPercentFromBips).toHaveBeenCalledWith(DEFAULT_SLIPPAGE_TOLERANCE)
158+
expect(mockPercentFromBips).toHaveBeenCalledWith(5000)
159+
160+
expect(mockRemoveCallParameters).toHaveBeenCalledTimes(1)
161+
const [, options] = mockRemoveCallParameters.mock.calls[0]
162+
163+
expect((options as RemoveCallParametersOptions).slippageTolerance).toEqual(
164+
MOCK_SLIPPAGE_PERCENT,
56165
)
57166
})
58167

59-
it('should throw if position not found', async () => {
60-
vi.mocked(getPosition).mockResolvedValueOnce(undefined as any)
168+
it('should throw error when position is not found', async () => {
169+
mockGetPosition.mockResolvedValueOnce(undefined as unknown as GetPositionResponse)
61170

62-
const { buildRemoveLiquidityCallData } = await import('@/utils/buildRemoveLiquidityCallData')
63171
await expect(
64172
buildRemoveLiquidityCallData({ liquidityPercentage: 10_000, tokenId: '404' }, instance),
65173
).rejects.toThrow('Position not found')
66-
})
67-
68-
it('should throw if V4PositionManager throws', async () => {
69-
vi.mocked(getPosition).mockResolvedValueOnce(mockPosition)
70-
vi.spyOn(V4PositionManager, 'removeCallParameters').mockImplementationOnce(() => {
71-
throw new Error('fail')
72-
})
73174

74-
const { buildRemoveLiquidityCallData } = await import('@/utils/buildRemoveLiquidityCallData')
75-
await expect(
76-
buildRemoveLiquidityCallData(
77-
{ liquidityPercentage: 10_000, tokenId: '1', deadline: '123' },
78-
instance,
79-
),
80-
).rejects.toThrow('fail')
175+
expect(mockRemoveCallParameters).not.toHaveBeenCalled()
81176
})
82177
})

0 commit comments

Comments
 (0)