177 lines
4.2 KiB
TypeScript
177 lines
4.2 KiB
TypeScript
import { act, renderHook } from '@testing-library/react-native'
|
|
|
|
import { useUserBalanceStore } from '@/stores/userBalanceStore'
|
|
import { subscription } from '@/lib/auth'
|
|
|
|
// Mock subscription API
|
|
jest.mock('@/lib/auth', () => ({
|
|
subscription: {
|
|
list: jest.fn(),
|
|
},
|
|
}))
|
|
|
|
// Mock AppState
|
|
jest.mock('react-native', () => ({
|
|
AppState: {
|
|
addEventListener: jest.fn(() => ({ remove: jest.fn() })),
|
|
},
|
|
}))
|
|
|
|
describe('userBalanceStore', () => {
|
|
beforeEach(() => {
|
|
// Reset store state before each test
|
|
const { reset } = useUserBalanceStore.getState()
|
|
reset()
|
|
jest.clearAllMocks()
|
|
})
|
|
|
|
describe('load', () => {
|
|
it('should load balance from API', async () => {
|
|
const mockData = [
|
|
{
|
|
type: 'metered',
|
|
creditBalance: {
|
|
remainingTokenBalance: 1000,
|
|
},
|
|
},
|
|
]
|
|
;(subscription.list as jest.Mock).mockResolvedValue({ data: mockData })
|
|
|
|
const { load } = useUserBalanceStore.getState()
|
|
await act(async () => {
|
|
await load(true)
|
|
})
|
|
|
|
const { balance } = useUserBalanceStore.getState()
|
|
expect(balance).toBe(1000)
|
|
})
|
|
|
|
it('should handle API error', async () => {
|
|
const mockError = { message: 'API Error', status: 500, statusText: 'Internal Server Error' }
|
|
;(subscription.list as jest.Mock).mockResolvedValue({ error: mockError })
|
|
|
|
const { load } = useUserBalanceStore.getState()
|
|
await act(async () => {
|
|
await load(true)
|
|
})
|
|
|
|
const { error } = useUserBalanceStore.getState()
|
|
expect(error).toEqual(mockError)
|
|
})
|
|
|
|
it('should debounce requests within 5 seconds', async () => {
|
|
const mockData = [
|
|
{
|
|
type: 'metered',
|
|
creditBalance: {
|
|
remainingTokenBalance: 500,
|
|
},
|
|
},
|
|
]
|
|
;(subscription.list as jest.Mock).mockResolvedValue({ data: mockData })
|
|
|
|
const { load } = useUserBalanceStore.getState()
|
|
|
|
// First call
|
|
await act(async () => {
|
|
await load(false)
|
|
})
|
|
|
|
// Second call within 5 seconds (should be skipped)
|
|
await act(async () => {
|
|
await load(false)
|
|
})
|
|
|
|
// API should only be called once
|
|
expect(subscription.list).toHaveBeenCalledTimes(1)
|
|
})
|
|
|
|
it('should force load when force=true', async () => {
|
|
const mockData = [
|
|
{
|
|
type: 'metered',
|
|
creditBalance: {
|
|
remainingTokenBalance: 500,
|
|
},
|
|
},
|
|
]
|
|
;(subscription.list as jest.Mock).mockResolvedValue({ data: mockData })
|
|
|
|
const { load } = useUserBalanceStore.getState()
|
|
|
|
// First call
|
|
await act(async () => {
|
|
await load(true)
|
|
})
|
|
|
|
// Second call with force=true (should not be skipped)
|
|
await act(async () => {
|
|
await load(true)
|
|
})
|
|
|
|
// API should be called twice
|
|
expect(subscription.list).toHaveBeenCalledTimes(2)
|
|
})
|
|
})
|
|
|
|
describe('setBalance', () => {
|
|
it('should set balance directly', () => {
|
|
const { setBalance } = useUserBalanceStore.getState()
|
|
|
|
act(() => {
|
|
setBalance(2000)
|
|
})
|
|
|
|
const { balance } = useUserBalanceStore.getState()
|
|
expect(balance).toBe(2000)
|
|
})
|
|
})
|
|
|
|
describe('deductBalance', () => {
|
|
it('should deduct balance', () => {
|
|
const { setBalance, deductBalance } = useUserBalanceStore.getState()
|
|
|
|
act(() => {
|
|
setBalance(1000)
|
|
deductBalance(300)
|
|
})
|
|
|
|
const { balance } = useUserBalanceStore.getState()
|
|
expect(balance).toBe(700)
|
|
})
|
|
|
|
it('should not go below zero', () => {
|
|
const { setBalance, deductBalance } = useUserBalanceStore.getState()
|
|
|
|
act(() => {
|
|
setBalance(100)
|
|
deductBalance(500)
|
|
})
|
|
|
|
const { balance } = useUserBalanceStore.getState()
|
|
expect(balance).toBe(0)
|
|
})
|
|
})
|
|
|
|
describe('reset', () => {
|
|
it('should reset all state', () => {
|
|
const { setBalance, reset } = useUserBalanceStore.getState()
|
|
|
|
act(() => {
|
|
setBalance(5000)
|
|
})
|
|
|
|
expect(useUserBalanceStore.getState().balance).toBe(5000)
|
|
|
|
act(() => {
|
|
reset()
|
|
})
|
|
|
|
const state = useUserBalanceStore.getState()
|
|
expect(state.balance).toBe(0)
|
|
expect(state.loading).toBe(false)
|
|
expect(state.error).toBe(null)
|
|
})
|
|
})
|
|
})
|