137 lines
3.9 KiB
TypeScript
137 lines
3.9 KiB
TypeScript
import React from 'react'
|
|
import { render, fireEvent, waitFor } from '@testing-library/react-native'
|
|
import { View } from 'react-native'
|
|
import MembershipScreen from './membership'
|
|
import { useMembership } from '@/hooks/use-membership'
|
|
|
|
jest.mock('expo-router', () => ({
|
|
useRouter: jest.fn(() => ({
|
|
back: jest.fn(),
|
|
push: jest.fn(),
|
|
})),
|
|
}))
|
|
|
|
jest.mock('react-i18next', () => ({
|
|
useTranslation: jest.fn(() => ({
|
|
t: (key: string) => key,
|
|
})),
|
|
}))
|
|
|
|
jest.mock('expo-status-bar', () => ({
|
|
StatusBar: 'StatusBar',
|
|
}))
|
|
|
|
jest.mock('react-native-safe-area-context', () => ({
|
|
SafeAreaView: ({ children }: { children: React.ReactNode }) => <View>{children}</View>,
|
|
useSafeAreaInsets: () => ({ top: 0, bottom: 0, left: 0, right: 0 }),
|
|
}))
|
|
|
|
jest.mock('expo-linear-gradient', () => ({
|
|
LinearGradient: 'LinearGradient',
|
|
}))
|
|
|
|
jest.mock('expo-image', () => ({
|
|
Image: 'Image',
|
|
}))
|
|
|
|
jest.mock('react-native-reanimated-carousel', () => 'Carousel')
|
|
|
|
jest.mock('react-native-svg', () => ({
|
|
__esModule: true,
|
|
default: 'Svg',
|
|
Svg: 'Svg',
|
|
Path: 'Path',
|
|
Defs: 'Defs',
|
|
LinearGradient: 'LinearGradient',
|
|
Stop: 'Stop',
|
|
}))
|
|
|
|
jest.mock('@/components/icon', () => ({
|
|
LeftArrowIcon: 'LeftArrowIcon',
|
|
OmitIcon: 'OmitIcon',
|
|
CheckIcon: 'CheckIcon',
|
|
UncheckedIcon: 'UncheckedIcon',
|
|
TermsIcon: 'TermsIcon',
|
|
PrivacyIcon: 'PrivacyIcon',
|
|
}))
|
|
|
|
jest.mock('@/components/icon/checkMark', () => ({
|
|
CheckMarkIcon: 'CheckMarkIcon',
|
|
}))
|
|
|
|
jest.mock('@/components/drawer/PointsDrawer', () => 'PointsDrawer')
|
|
jest.mock('@/components/ui/dropdown', () => 'Dropdown')
|
|
jest.mock('@/components/GradientText', () => 'GradientText')
|
|
|
|
jest.mock('@/hooks/use-membership')
|
|
|
|
describe('MembershipScreen - 订阅按钮Loading状态', () => {
|
|
const mockUseMembership = useMembership as jest.MockedFunction<typeof useMembership>
|
|
|
|
beforeEach(() => {
|
|
jest.clearAllMocks()
|
|
mockUseMembership.mockReturnValue({
|
|
creditPlans: [
|
|
{ amountInCents: 1000, credits: 750, popular: false },
|
|
{ amountInCents: 2000, credits: 1500, popular: true },
|
|
],
|
|
creditBalance: 100,
|
|
selectedPlanIndex: 0,
|
|
setSelectedPlanIndex: jest.fn(),
|
|
isLoadingSubscriptions: false,
|
|
isStripePricingLoading: false,
|
|
createSubscription: jest.fn(),
|
|
upgradeSubscription: jest.fn(),
|
|
restoreSubscription: jest.fn(),
|
|
rechargeToken: jest.fn(),
|
|
activeAuthSubscription: null,
|
|
hasActiveSubscription: false,
|
|
stripePricingData: {
|
|
pricing_table_items: [
|
|
{ price_id: 'price-1', product_id: 'prod-1' },
|
|
{ price_id: 'price-2', product_id: 'prod-2' },
|
|
],
|
|
},
|
|
} as any)
|
|
})
|
|
|
|
it('应该在点击订阅按钮后显示loading状态', async () => {
|
|
const createSubscription = jest.fn().mockImplementation(() => new Promise(resolve => setTimeout(resolve, 100)))
|
|
mockUseMembership.mockReturnValue({
|
|
...mockUseMembership(),
|
|
createSubscription,
|
|
} as any)
|
|
|
|
const { getByText, getByTestId } = render(<MembershipScreen />)
|
|
|
|
const checkbox = getByText('membership.agreementText').parent?.parent
|
|
if (checkbox) fireEvent.press(checkbox)
|
|
|
|
const subscribeButton = getByText('membership.subscribeNow')
|
|
fireEvent.press(subscribeButton)
|
|
|
|
await waitFor(() => {
|
|
expect(createSubscription).toHaveBeenCalled()
|
|
})
|
|
})
|
|
|
|
it('应该在订阅过程中禁用按钮', async () => {
|
|
mockUseMembership.mockReturnValue({
|
|
...mockUseMembership(),
|
|
isLoadingSubscriptions: true,
|
|
} as any)
|
|
|
|
const { getByText } = render(<MembershipScreen />)
|
|
|
|
const subscribeButton = getByText('membership.subscribeNow').parent
|
|
expect(subscribeButton?.props.accessibilityState?.disabled).toBe(true)
|
|
})
|
|
|
|
it('应该在未同意协议时禁用按钮', () => {
|
|
const { getByText } = render(<MembershipScreen />)
|
|
|
|
const subscribeButton = getByText('membership.subscribeNow').parent
|
|
expect(subscribeButton?.props.accessibilityState?.disabled).toBe(true)
|
|
})
|
|
})
|