| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213 |
- import React from 'react'
- import { render } from '@testing-library/react'
- import { CartProvider, useCart, CartItem } from '@/contexts/CartContext'
- import { mockShowToast, mockGetStorageSync, mockSetStorageSync } from '~/__mocks__/taroMock'
- // Mock Taro API
- jest.mock('@tarojs/taro', () => jest.requireActual('~/__mocks__/taroMock'))
- // 测试组件用于访问购物车hook
- const TestComponent = ({ action, item }: { action: string; item?: CartItem }) => {
- const cart = useCart()
- React.useEffect(() => {
- if (action === 'add' && item) {
- cart.addToCart(item)
- }
- }, [action, item, cart])
- return (
- <div>
- <div data-testid="items-count">{cart.cart.items.length}</div>
- <div data-testid="total-count">{cart.cart.totalCount}</div>
- <div data-testid="total-amount">{cart.cart.totalAmount}</div>
- {cart.cart.items.map((item, index) => (
- <div key={index} data-testid={`item-${index}`}>
- <span data-testid={`item-${index}-id`}>{item.id}</span>
- <span data-testid={`item-${index}-name`}>{item.name}</span>
- <span data-testid={`item-${index}-spec`}>{item.spec || ''}</span>
- <span data-testid={`item-${index}-quantity`}>{item.quantity}</span>
- </div>
- ))}
- </div>
- )
- }
- describe('CartContext - 规格支持', () => {
- beforeEach(() => {
- mockGetStorageSync.mockReturnValue(null)
- mockSetStorageSync.mockClear()
- mockShowToast.mockClear()
- })
- it('应该支持添加父商品到购物车', () => {
- const parentGoods: CartItem = {
- id: 1001,
- name: '测试父商品',
- price: 99.9,
- image: 'parent.jpg',
- stock: 10,
- quantity: 2,
- }
- const { getByTestId } = render(
- <CartProvider>
- <TestComponent action="add" item={parentGoods} />
- </CartProvider>
- )
- expect(getByTestId('items-count').textContent).toBe('1')
- expect(getByTestId('item-0-id').textContent).toBe('1001')
- expect(getByTestId('item-0-name').textContent).toBe('测试父商品')
- expect(mockSetStorageSync).toHaveBeenCalled()
- })
- it('应该支持添加子商品(带规格)到购物车', () => {
- const childGoods: CartItem = {
- id: 2001, // 子商品ID
- name: '测试父商品 - 红色/M', // 包含规格信息的完整名称
- price: 109.9,
- image: 'child.jpg',
- stock: 5,
- quantity: 1,
- spec: '红色/M', // 规格信息
- }
- const { getByTestId } = render(
- <CartProvider>
- <TestComponent action="add" item={childGoods} />
- </CartProvider>
- )
- expect(getByTestId('items-count').textContent).toBe('1')
- expect(getByTestId('item-0-id').textContent).toBe('2001')
- expect(getByTestId('item-0-name').textContent).toBe('测试父商品 - 红色/M')
- expect(getByTestId('item-0-spec').textContent).toBe('红色/M')
- expect(mockSetStorageSync).toHaveBeenCalled()
- })
- it('应该支持添加同一子商品多次(数量累加)', () => {
- const childGoods1: CartItem = {
- id: 3001,
- name: '测试商品 - 蓝色/L',
- price: 89.9,
- image: 'goods.jpg',
- stock: 10,
- quantity: 1,
- spec: '蓝色/L',
- }
- const childGoods2: CartItem = {
- id: 3001, // 同一子商品ID
- name: '测试商品 - 蓝色/L',
- price: 89.9,
- image: 'goods.jpg',
- stock: 10,
- quantity: 3,
- spec: '蓝色/L',
- }
- const { getByTestId, rerender } = render(
- <CartProvider>
- <TestComponent action="add" item={childGoods1} />
- </CartProvider>
- )
- expect(getByTestId('items-count').textContent).toBe('1')
- expect(getByTestId('item-0-quantity').textContent).toBe('1')
- // 重新渲染添加更多数量
- rerender(
- <CartProvider>
- <TestComponent action="add" item={childGoods2} />
- </CartProvider>
- )
- expect(getByTestId('item-0-quantity').textContent).toBe('4') // 1 + 3
- })
- it('应该限制数量不超过库存', () => {
- const childGoods: CartItem = {
- id: 4001,
- name: '测试商品 - 黑色/XL',
- price: 129.9,
- image: 'goods.jpg',
- stock: 2, // 库存只有2
- quantity: 3, // 尝试购买3个
- spec: '黑色/XL',
- }
- const { getByTestId } = render(
- <CartProvider>
- <TestComponent action="add" item={childGoods} />
- </CartProvider>
- )
- // 应该显示库存不足提示
- expect(mockShowToast).toHaveBeenCalledWith(
- expect.objectContaining({ title: '库存不足' })
- )
- // 商品不应被添加
- expect(getByTestId('items-count').textContent).toBe('0')
- })
- it('应该支持同时添加父商品和不同子商品', () => {
- const parentGoods: CartItem = {
- id: 5001,
- name: '测试父商品',
- price: 199.9,
- image: 'parent.jpg',
- stock: 20,
- quantity: 1,
- }
- const childGoods1: CartItem = {
- id: 5002, // 子商品ID1
- name: '测试父商品 - 规格A',
- price: 219.9,
- image: 'child1.jpg',
- stock: 5,
- quantity: 2,
- spec: '规格A',
- }
- const childGoods2: CartItem = {
- id: 5003, // 子商品ID2
- name: '测试父商品 - 规格B',
- price: 229.9,
- image: 'child2.jpg',
- stock: 3,
- quantity: 1,
- spec: '规格B',
- }
- const { getByTestId, rerender } = render(
- <CartProvider>
- <TestComponent action="add" item={parentGoods} />
- </CartProvider>
- )
- expect(getByTestId('items-count').textContent).toBe('1')
- // 添加第一个子商品
- rerender(
- <CartProvider>
- <TestComponent action="add" item={childGoods1} />
- </CartProvider>
- )
- expect(getByTestId('items-count').textContent).toBe('2')
- // 添加第二个子商品
- rerender(
- <CartProvider>
- <TestComponent action="add" item={childGoods2} />
- </CartProvider>
- )
- expect(getByTestId('items-count').textContent).toBe('3')
- expect(getByTestId('item-0-id').textContent).toBe('5001')
- expect(getByTestId('item-1-id').textContent).toBe('5002')
- expect(getByTestId('item-2-id').textContent).toBe('5003')
- })
- })
|