LoginPage.test.tsx 2.39 KB
import { describe, it, expect, vi, beforeEach } from 'vitest'
import { render, screen, waitFor, act } from '@testing-library/react'
import userEvent from '@testing-library/user-event'
import { Provider } from 'react-redux'
import { MemoryRouter } from 'react-router-dom'
import { configureStore } from '@reduxjs/toolkit'
import authReducer, { UserInfoVO } from '../store/slices/authSlice'
import LoginPage from '../pages/usr/LoginPage'
import * as authApi from '../api/auth'

vi.mock('../api/auth', () => ({
  getBrands: vi.fn(),
  login: vi.fn()
}))

vi.mock('../api/request', () => ({
  default: { get: vi.fn(), post: vi.fn() }
}))

function makeStore() {
  return configureStore({ reducer: { auth: authReducer } })
}

function renderLoginPage(store = makeStore()) {
  return {
    store,
    ...render(
      <Provider store={store}>
        <MemoryRouter>
          <LoginPage />
        </MemoryRouter>
      </Provider>
    )
  }
}

describe('LoginPage', () => {
  beforeEach(() => {
    vi.mocked(authApi.getBrands).mockResolvedValue([
      { sNo: 'STD', sName: '标准版' }
    ])
  })

  it('renders_brandSelect_username_and_password_fields', async () => {
    renderLoginPage()
    await waitFor(() => expect(screen.getByText('公司/版本')).toBeInTheDocument())
    expect(screen.getByText('用户名')).toBeInTheDocument()
    expect(screen.getByText('密码')).toBeInTheDocument()
    expect(screen.getByRole('button', { name: /登\s*录/ })).toBeInTheDocument()
  })

  it('submit_withValidCredentials_dispatchesSetCredentials', async () => {
    const mockUserInfo: UserInfoVO = {
      userId: 'u1', username: 'admin', userType: '超级管理员', language: '中文', brandId: 'b1'
    }
    vi.mocked(authApi.login).mockResolvedValue({
      accessToken: 'at',
      refreshToken: 'rt',
      expiresIn: 86400,
      userInfo: mockUserInfo
    })

    const { store } = renderLoginPage()
    // Flush getBrands().then() callback so form.setFieldValue('brandNo') runs before submit
    await act(async () => { await Promise.resolve() })

    await userEvent.type(screen.getByPlaceholderText('请输入用户名'), 'admin')
    await userEvent.type(screen.getByPlaceholderText('请输入密码'), '666666')
    await userEvent.click(screen.getByRole('button', { name: /登\s*录/ }))

    await waitFor(() => expect(store.getState().auth.accessToken).toBe('at'))
    expect(store.getState().auth.userInfo?.userId).toBe('u1')
  })
})