fix: bug
This commit is contained in:
@@ -251,6 +251,7 @@ export default function MembershipScreen() {
|
|||||||
autoPlayInterval={2000}
|
autoPlayInterval={2000}
|
||||||
loop
|
loop
|
||||||
onSnapToItem={(index) => setCurrentImageIndex(index)}
|
onSnapToItem={(index) => setCurrentImageIndex(index)}
|
||||||
|
enabled={false}
|
||||||
/>
|
/>
|
||||||
<View style={styles.dotsContainer}>
|
<View style={styles.dotsContainer}>
|
||||||
{carouselImages.map((_, index) => (
|
{carouselImages.map((_, index) => (
|
||||||
|
|||||||
@@ -1,8 +1,6 @@
|
|||||||
import { renderHook, act, waitFor } from '@testing-library/react-native'
|
import { renderHook, act, waitFor } from '@testing-library/react-native'
|
||||||
import { useMembership } from './use-membership'
|
import { useMembership } from './use-membership'
|
||||||
import { subscription, useSession } from '@/lib/auth'
|
import { subscription, useSession } from '@/lib/auth'
|
||||||
import { useRouter } from 'expo-router'
|
|
||||||
import { Linking, Alert } from 'react-native'
|
|
||||||
|
|
||||||
jest.mock('@/lib/auth', () => ({
|
jest.mock('@/lib/auth', () => ({
|
||||||
subscription: {
|
subscription: {
|
||||||
@@ -19,47 +17,15 @@ jest.mock('@/lib/auth', () => ({
|
|||||||
useSession: jest.fn(),
|
useSession: jest.fn(),
|
||||||
}))
|
}))
|
||||||
|
|
||||||
jest.mock('expo-router', () => ({
|
|
||||||
useRouter: jest.fn(),
|
|
||||||
}))
|
|
||||||
|
|
||||||
jest.mock('react-native', () => ({
|
|
||||||
Linking: {
|
|
||||||
openURL: jest.fn(),
|
|
||||||
},
|
|
||||||
Alert: {
|
|
||||||
alert: jest.fn(),
|
|
||||||
},
|
|
||||||
}))
|
|
||||||
|
|
||||||
const mockUseQuery = jest.fn()
|
|
||||||
const mockUseMutation = jest.fn()
|
|
||||||
|
|
||||||
jest.mock('@tanstack/react-query', () => ({
|
|
||||||
useQuery: (...args: any[]) => mockUseQuery(args[0]),
|
|
||||||
useMutation: (...args: any[]) => mockUseMutation(args[0]),
|
|
||||||
}))
|
|
||||||
|
|
||||||
describe('useMembership', () => {
|
describe('useMembership', () => {
|
||||||
const mockRouter = { push: jest.fn() }
|
|
||||||
const mockSession = {
|
const mockSession = {
|
||||||
user: { id: 'user-123' },
|
user: { id: 'user-123' },
|
||||||
}
|
}
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
jest.clearAllMocks()
|
jest.clearAllMocks()
|
||||||
;(useRouter as jest.Mock).mockReturnValue(mockRouter)
|
|
||||||
;(useSession as jest.Mock).mockReturnValue({ data: mockSession })
|
;(useSession as jest.Mock).mockReturnValue({ data: mockSession })
|
||||||
|
;(subscription.list as jest.Mock).mockResolvedValue({ data: [], error: null })
|
||||||
mockUseQuery.mockReturnValue({
|
|
||||||
data: null,
|
|
||||||
isLoading: false,
|
|
||||||
refetch: jest.fn(),
|
|
||||||
})
|
|
||||||
|
|
||||||
mockUseMutation.mockReturnValue({
|
|
||||||
mutate: jest.fn(),
|
|
||||||
})
|
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('获取 Stripe 定价表数据', () => {
|
describe('获取 Stripe 定价表数据', () => {
|
||||||
@@ -74,16 +40,38 @@ describe('useMembership', () => {
|
|||||||
},
|
},
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
|
;(subscription.plans as jest.Mock).mockResolvedValue({
|
||||||
mockUseQuery.mockReturnValue({
|
|
||||||
data: mockPricingData,
|
data: mockPricingData,
|
||||||
isLoading: false,
|
error: null,
|
||||||
refetch: jest.fn(),
|
|
||||||
})
|
})
|
||||||
|
|
||||||
const { result } = renderHook(() => useMembership())
|
const { result } = renderHook(() => useMembership())
|
||||||
|
|
||||||
expect(result.current.stripePricingData).toEqual(mockPricingData)
|
await waitFor(() => {
|
||||||
|
expect(result.current.stripePricingData).toEqual(mockPricingData)
|
||||||
|
})
|
||||||
|
|
||||||
|
expect(subscription.plans).toHaveBeenCalledWith({
|
||||||
|
query: {
|
||||||
|
id: '',
|
||||||
|
key: '',
|
||||||
|
},
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
it('应该处理定价表获取错误', async () => {
|
||||||
|
;(subscription.plans as jest.Mock).mockResolvedValue({
|
||||||
|
data: null,
|
||||||
|
error: { message: 'Failed to fetch pricing' },
|
||||||
|
})
|
||||||
|
|
||||||
|
const { result } = renderHook(() => useMembership())
|
||||||
|
|
||||||
|
await waitFor(() => {
|
||||||
|
expect(subscription.plans).toHaveBeenCalled()
|
||||||
|
})
|
||||||
|
|
||||||
|
expect(result.current.stripePricingData).toBeNull()
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -97,77 +85,40 @@ describe('useMembership', () => {
|
|||||||
stripeSubscriptionId: 'sub-123',
|
stripeSubscriptionId: 'sub-123',
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
;(subscription.plans as jest.Mock).mockResolvedValue({ data: null, error: null })
|
||||||
let queryCallCount = 0
|
;(subscription.list as jest.Mock).mockResolvedValue({
|
||||||
mockUseQuery.mockImplementation((config) => {
|
data: mockSubscriptions,
|
||||||
queryCallCount++
|
error: null,
|
||||||
if (queryCallCount === 2) {
|
|
||||||
return {
|
|
||||||
data: mockSubscriptions,
|
|
||||||
isLoading: false,
|
|
||||||
refetch: jest.fn(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return {
|
|
||||||
data: null,
|
|
||||||
isLoading: false,
|
|
||||||
refetch: jest.fn(),
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
|
|
||||||
const { result } = renderHook(() => useMembership())
|
const { result } = renderHook(() => useMembership())
|
||||||
|
|
||||||
expect(result.current.isLoadingSubscriptions).toBe(false)
|
await waitFor(() => {
|
||||||
|
expect(subscription.list).toHaveBeenCalledWith({
|
||||||
|
query: { referenceId: 'user-123' },
|
||||||
|
})
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
it('应该在没有用户会话时不获取订阅', () => {
|
it('应该在没有用户会话时不获取订阅', () => {
|
||||||
;(useSession as jest.Mock).mockReturnValue({ data: null })
|
;(useSession as jest.Mock).mockReturnValue({ data: null })
|
||||||
|
;(subscription.plans as jest.Mock).mockResolvedValue({ data: null, error: null })
|
||||||
mockUseQuery.mockImplementation((config) => {
|
|
||||||
if (config.enabled === false) {
|
|
||||||
return {
|
|
||||||
data: null,
|
|
||||||
isLoading: false,
|
|
||||||
refetch: jest.fn(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return {
|
|
||||||
data: null,
|
|
||||||
isLoading: false,
|
|
||||||
refetch: jest.fn(),
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
renderHook(() => useMembership())
|
renderHook(() => useMembership())
|
||||||
|
|
||||||
expect(mockUseQuery).toHaveBeenCalled()
|
expect(subscription.list).not.toHaveBeenCalled()
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('创建订阅', () => {
|
describe('创建订阅', () => {
|
||||||
it('应该成功创建订阅并打开支付链接', async () => {
|
it('应该调用 subscription.create', async () => {
|
||||||
const mockUrl = 'https://checkout.stripe.com/test'
|
const mockUrl = 'https://checkout.stripe.com/test'
|
||||||
|
;(subscription.plans as jest.Mock).mockResolvedValue({ data: null, error: null })
|
||||||
;(subscription.create as jest.Mock).mockResolvedValue({
|
;(subscription.create as jest.Mock).mockResolvedValue({
|
||||||
data: { url: mockUrl },
|
data: { url: mockUrl },
|
||||||
error: null,
|
error: null,
|
||||||
})
|
})
|
||||||
|
|
||||||
const mutateFn = jest.fn(async (variables) => {
|
|
||||||
const { data, error } = await subscription.create({
|
|
||||||
priceId: variables.priceId,
|
|
||||||
productId: variables.productId,
|
|
||||||
successUrl: expect.stringContaining('/membership'),
|
|
||||||
cancelUrl: expect.stringContaining('/membership?canceled=true'),
|
|
||||||
})
|
|
||||||
if (error) throw new Error(error.message)
|
|
||||||
if (data?.url) await Linking.openURL(data.url)
|
|
||||||
return data
|
|
||||||
})
|
|
||||||
|
|
||||||
mockUseMutation.mockReturnValue({
|
|
||||||
mutate: mutateFn,
|
|
||||||
})
|
|
||||||
|
|
||||||
const { result } = renderHook(() => useMembership())
|
const { result } = renderHook(() => useMembership())
|
||||||
|
|
||||||
await act(async () => {
|
await act(async () => {
|
||||||
@@ -177,50 +128,41 @@ describe('useMembership', () => {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
expect(mutateFn).toHaveBeenCalled()
|
expect(subscription.create).toHaveBeenCalledWith({
|
||||||
expect(Linking.openURL).toHaveBeenCalledWith(mockUrl)
|
priceId: 'price-123',
|
||||||
|
productId: 'prod-123',
|
||||||
|
successUrl: expect.stringContaining('/membership'),
|
||||||
|
cancelUrl: expect.stringContaining('/membership?canceled=true'),
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
it('应该处理创建订阅错误', async () => {
|
it('应该处理创建订阅错误', async () => {
|
||||||
|
;(subscription.plans as jest.Mock).mockResolvedValue({ data: null, error: null })
|
||||||
;(subscription.create as jest.Mock).mockResolvedValue({
|
;(subscription.create as jest.Mock).mockResolvedValue({
|
||||||
data: null,
|
data: null,
|
||||||
error: { message: 'Failed to create subscription' },
|
error: { message: 'Failed to create subscription' },
|
||||||
})
|
})
|
||||||
|
|
||||||
const mutateFn = jest.fn(async (variables) => {
|
|
||||||
try {
|
|
||||||
const { data, error } = await subscription.create(variables)
|
|
||||||
if (error) throw new Error(error.message)
|
|
||||||
return data
|
|
||||||
} catch (error) {
|
|
||||||
Alert.alert('错误', '订阅创建失败')
|
|
||||||
throw error
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
mockUseMutation.mockReturnValue({
|
|
||||||
mutate: mutateFn,
|
|
||||||
})
|
|
||||||
|
|
||||||
const { result } = renderHook(() => useMembership())
|
const { result } = renderHook(() => useMembership())
|
||||||
|
|
||||||
await act(async () => {
|
await act(async () => {
|
||||||
try {
|
await result.current.createSubscription({
|
||||||
await result.current.createSubscription({
|
priceId: 'price-123',
|
||||||
priceId: 'price-123',
|
productId: 'prod-123',
|
||||||
productId: 'prod-123',
|
})
|
||||||
})
|
|
||||||
} catch (e) {
|
|
||||||
// Expected error
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
|
|
||||||
expect(Alert.alert).toHaveBeenCalledWith('错误', '订阅创建失败')
|
expect(subscription.create).toHaveBeenCalled()
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('升级订阅', () => {
|
describe('升级订阅', () => {
|
||||||
it('应该成功升级订阅', async () => {
|
it('应该成功升级订阅', async () => {
|
||||||
|
const mockPricingData = {
|
||||||
|
pricing_table_items: [
|
||||||
|
{ amount: '1000', product_name: 'basic', recurring: { interval: 'month' }, metadata: { grant_token: '1000' } },
|
||||||
|
],
|
||||||
|
}
|
||||||
const mockSubscriptions = [
|
const mockSubscriptions = [
|
||||||
{
|
{
|
||||||
type: 'licenced',
|
type: 'licenced',
|
||||||
@@ -229,41 +171,37 @@ describe('useMembership', () => {
|
|||||||
stripeSubscriptionId: 'sub-123',
|
stripeSubscriptionId: 'sub-123',
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
;(subscription.plans as jest.Mock).mockResolvedValue({ data: mockPricingData, error: null })
|
||||||
let queryCallCount = 0
|
;(subscription.list as jest.Mock).mockResolvedValue({ data: mockSubscriptions, error: null })
|
||||||
mockUseQuery.mockImplementation(() => {
|
|
||||||
queryCallCount++
|
|
||||||
if (queryCallCount === 2) {
|
|
||||||
return {
|
|
||||||
data: mockSubscriptions,
|
|
||||||
isLoading: false,
|
|
||||||
refetch: jest.fn(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return {
|
|
||||||
data: null,
|
|
||||||
isLoading: false,
|
|
||||||
refetch: jest.fn(),
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
;(subscription.upgrade as jest.Mock).mockResolvedValue({
|
;(subscription.upgrade as jest.Mock).mockResolvedValue({
|
||||||
data: { success: true },
|
data: { success: true },
|
||||||
error: null,
|
error: null,
|
||||||
})
|
})
|
||||||
|
|
||||||
const mutateFn = jest.fn()
|
const { result } = renderHook(() => useMembership())
|
||||||
mockUseMutation.mockReturnValue({
|
|
||||||
mutate: mutateFn,
|
await waitFor(() => {
|
||||||
|
expect(result.current.activeAuthSubscription).toBeDefined()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
await act(async () => {
|
||||||
|
await result.current.upgradeSubscription({ credits: 1000 })
|
||||||
|
})
|
||||||
|
|
||||||
|
expect(subscription.upgrade).toHaveBeenCalled()
|
||||||
|
})
|
||||||
|
|
||||||
|
it('应该处理未找到活跃订阅的情况', async () => {
|
||||||
|
;(subscription.plans as jest.Mock).mockResolvedValue({ data: null, error: null })
|
||||||
|
;(subscription.list as jest.Mock).mockResolvedValue({ data: [], error: null })
|
||||||
|
|
||||||
const { result } = renderHook(() => useMembership())
|
const { result } = renderHook(() => useMembership())
|
||||||
|
|
||||||
await act(async () => {
|
await act(async () => {
|
||||||
result.current.upgradeSubscription({ credits: 1000 })
|
await result.current.upgradeSubscription({ credits: 1000 })
|
||||||
})
|
})
|
||||||
|
|
||||||
expect(mutateFn).toHaveBeenCalled()
|
expect(subscription.upgrade).not.toHaveBeenCalled()
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -278,127 +216,101 @@ describe('useMembership', () => {
|
|||||||
referenceId: 'user-123',
|
referenceId: 'user-123',
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
;(subscription.plans as jest.Mock).mockResolvedValue({ data: null, error: null })
|
||||||
let queryCallCount = 0
|
;(subscription.list as jest.Mock).mockResolvedValue({ data: mockSubscriptions, error: null })
|
||||||
mockUseQuery.mockImplementation(() => {
|
|
||||||
queryCallCount++
|
|
||||||
if (queryCallCount === 2) {
|
|
||||||
return {
|
|
||||||
data: mockSubscriptions,
|
|
||||||
isLoading: false,
|
|
||||||
refetch: jest.fn(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return {
|
|
||||||
data: null,
|
|
||||||
isLoading: false,
|
|
||||||
refetch: jest.fn(),
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
;(subscription.restore as jest.Mock).mockResolvedValue({
|
;(subscription.restore as jest.Mock).mockResolvedValue({
|
||||||
data: { success: true },
|
data: { success: true },
|
||||||
error: null,
|
error: null,
|
||||||
})
|
})
|
||||||
|
|
||||||
const mutateFn = jest.fn()
|
const { result } = renderHook(() => useMembership())
|
||||||
mockUseMutation.mockReturnValue({
|
|
||||||
mutate: mutateFn,
|
await waitFor(() => {
|
||||||
|
expect(result.current.activeAuthSubscription).toBeDefined()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
await act(async () => {
|
||||||
|
await result.current.restoreSubscription()
|
||||||
|
})
|
||||||
|
|
||||||
|
expect(subscription.restore).toHaveBeenCalledWith({
|
||||||
|
subscriptionId: 'sub-123',
|
||||||
|
referenceId: 'user-123',
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
it('应该处理未找到可恢复订阅的情况', async () => {
|
||||||
|
;(subscription.plans as jest.Mock).mockResolvedValue({ data: null, error: null })
|
||||||
|
;(subscription.list as jest.Mock).mockResolvedValue({ data: [], error: null })
|
||||||
|
|
||||||
const { result } = renderHook(() => useMembership())
|
const { result } = renderHook(() => useMembership())
|
||||||
|
|
||||||
await act(async () => {
|
await act(async () => {
|
||||||
result.current.restoreSubscription()
|
await result.current.restoreSubscription()
|
||||||
})
|
})
|
||||||
|
|
||||||
expect(mutateFn).toHaveBeenCalled()
|
expect(subscription.restore).not.toHaveBeenCalled()
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('充值积分', () => {
|
describe('充值积分', () => {
|
||||||
it('应该成功充值积分并打开支付链接', async () => {
|
it('应该成功充值积分', async () => {
|
||||||
const mockUrl = 'https://checkout.stripe.com/topup'
|
const mockUrl = 'https://checkout.stripe.com/topup'
|
||||||
const mockSubscriptions = [
|
const mockSubscriptions = [
|
||||||
{
|
{
|
||||||
type: 'metered',
|
type: 'metered',
|
||||||
priceId: 'price-metered-123',
|
priceId: 'price-metered-123',
|
||||||
|
creditBalance: { remainingTokenBalance: 100 },
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
;(subscription.plans as jest.Mock).mockResolvedValue({ data: null, error: null })
|
||||||
let queryCallCount = 0
|
;(subscription.list as jest.Mock).mockResolvedValue({ data: mockSubscriptions, error: null })
|
||||||
mockUseQuery.mockImplementation(() => {
|
|
||||||
queryCallCount++
|
|
||||||
if (queryCallCount === 2) {
|
|
||||||
return {
|
|
||||||
data: mockSubscriptions,
|
|
||||||
isLoading: false,
|
|
||||||
refetch: jest.fn(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return {
|
|
||||||
data: null,
|
|
||||||
isLoading: false,
|
|
||||||
refetch: jest.fn(),
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
;(subscription.credit.topup as jest.Mock).mockResolvedValue({
|
;(subscription.credit.topup as jest.Mock).mockResolvedValue({
|
||||||
data: { url: mockUrl },
|
data: { url: mockUrl },
|
||||||
error: null,
|
error: null,
|
||||||
})
|
})
|
||||||
|
|
||||||
const mutateFn = jest.fn(async (amount) => {
|
const { result } = renderHook(() => useMembership())
|
||||||
const { data, error } = await subscription.credit.topup({
|
|
||||||
amount,
|
await waitFor(() => {
|
||||||
priceId: 'price-metered-123',
|
expect(result.current.creditBalance).toBe(100)
|
||||||
successUrl: expect.stringContaining('/membership'),
|
|
||||||
cancelUrl: expect.stringContaining('/membership?canceled=true'),
|
|
||||||
})
|
|
||||||
if (error) throw new Error(error.message)
|
|
||||||
if (data?.url) await Linking.openURL(data.url)
|
|
||||||
return data
|
|
||||||
})
|
})
|
||||||
|
|
||||||
mockUseMutation.mockReturnValue({
|
await act(async () => {
|
||||||
mutate: mutateFn,
|
await result.current.rechargeToken(1000)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
expect(subscription.credit.topup).toHaveBeenCalledWith({
|
||||||
|
amount: 1000,
|
||||||
|
priceId: 'price-metered-123',
|
||||||
|
successUrl: expect.stringContaining('/membership'),
|
||||||
|
cancelUrl: expect.stringContaining('/membership?canceled=true'),
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
it('应该处理无效充值金额', async () => {
|
||||||
|
;(subscription.plans as jest.Mock).mockResolvedValue({ data: null, error: null })
|
||||||
|
|
||||||
|
const { result } = renderHook(() => useMembership())
|
||||||
|
|
||||||
|
await act(async () => {
|
||||||
|
await result.current.rechargeToken(0)
|
||||||
|
})
|
||||||
|
|
||||||
|
expect(subscription.credit.topup).not.toHaveBeenCalled()
|
||||||
|
})
|
||||||
|
|
||||||
|
it('应该处理定价数据不可用的情况', async () => {
|
||||||
|
;(subscription.plans as jest.Mock).mockResolvedValue({ data: null, error: null })
|
||||||
|
;(subscription.list as jest.Mock).mockResolvedValue({ data: [], error: null })
|
||||||
|
|
||||||
const { result } = renderHook(() => useMembership())
|
const { result } = renderHook(() => useMembership())
|
||||||
|
|
||||||
await act(async () => {
|
await act(async () => {
|
||||||
await result.current.rechargeToken(1000)
|
await result.current.rechargeToken(1000)
|
||||||
})
|
})
|
||||||
|
|
||||||
expect(mutateFn).toHaveBeenCalledWith(1000)
|
expect(subscription.credit.topup).not.toHaveBeenCalled()
|
||||||
expect(Linking.openURL).toHaveBeenCalledWith(mockUrl)
|
|
||||||
})
|
|
||||||
|
|
||||||
it('应该处理无效充值金额', async () => {
|
|
||||||
const mutateFn = jest.fn(async (amount) => {
|
|
||||||
try {
|
|
||||||
if (!amount || amount <= 0) throw new Error('充值金额无效')
|
|
||||||
} catch (error) {
|
|
||||||
Alert.alert('错误', '充值失败')
|
|
||||||
throw error
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
mockUseMutation.mockReturnValue({
|
|
||||||
mutate: mutateFn,
|
|
||||||
})
|
|
||||||
|
|
||||||
const { result } = renderHook(() => useMembership())
|
|
||||||
|
|
||||||
await act(async () => {
|
|
||||||
try {
|
|
||||||
await result.current.rechargeToken(0)
|
|
||||||
} catch (e) {
|
|
||||||
// Expected error
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
expect(Alert.alert).toHaveBeenCalledWith('错误', '充值失败')
|
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -43,6 +43,12 @@ jest.mock('react-native', () => {
|
|||||||
get: jest.fn(),
|
get: jest.fn(),
|
||||||
set: jest.fn(),
|
set: jest.fn(),
|
||||||
},
|
},
|
||||||
|
Alert: {
|
||||||
|
alert: jest.fn(),
|
||||||
|
},
|
||||||
|
Linking: {
|
||||||
|
openURL: jest.fn(),
|
||||||
|
},
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user