import { describe, it, expect, vi } from 'vitest'
import { render, screen, waitFor } from '@testing-library/react'
import userEvent from '@testing-library/user-event'
import { Provider } from 'react-redux'
import { MemoryRouter, Routes, Route } from 'react-router-dom'
import { configureStore } from '@reduxjs/toolkit'
import authReducer from '../store/slices/authSlice'
import tabsReducer, { openTab } from '../store/slices/tabsSlice'
import AppShell from '../components/AppShell'
vi.mock('../components/NavOverlay', () => ({
default: ({ onClose }: { onClose: () => void }) => (
NavOverlay
),
}))
function makeStore(extraTabs = false) {
const store = configureStore({ reducer: { auth: authReducer, tabs: tabsReducer } })
store.dispatch({
type: 'auth/setCredentials',
payload: { accessToken: 'tok', refreshToken: 'ref', userInfo: { userId: 'u0', username: 'admin', userType: '超级管理员', language: '中文', brandId: 'b1' } },
})
if (extraTabs) {
store.dispatch(openTab({ id: 'userlist', title: '用户列表', path: '/usr/users', closable: true }))
}
return store
}
function renderShell(path = '/', extraTabs = false) {
const store = makeStore(extraTabs)
return {
store,
...render(
}>
MainPage} />
UserListPage} />
),
}
}
describe('AppShell', () => {
it('renders_mainTabAndUserInfo', () => {
renderShell()
expect(screen.getByText('主页')).toBeInTheDocument()
expect(screen.getByText(/admin/)).toBeInTheDocument()
})
it('renders_openTabs', () => {
renderShell('/', true)
expect(screen.getByText('用户列表')).toBeInTheDocument()
})
it('clickTab_navigatesToTabPath', async () => {
renderShell('/', true)
await userEvent.click(screen.getByText('用户列表'))
await waitFor(() => expect(screen.getByText('UserListPage')).toBeInTheDocument())
})
it('closeTab_removesTabAndNavigates', async () => {
renderShell('/usr/users', true)
await userEvent.click(screen.getByRole('button', { name: '关闭 用户列表' }))
await waitFor(() => expect(screen.queryByText('用户列表')).not.toBeInTheDocument())
expect(screen.getByText('MainPage')).toBeInTheDocument()
})
it('navToggle_showsNavOverlay', async () => {
renderShell()
await userEvent.click(screen.getByRole('button', { name: /全部导航/ }))
expect(screen.getByTestId('nav-overlay')).toBeInTheDocument()
})
it('navToggle_secondClick_hidesOverlay', async () => {
renderShell()
await userEvent.click(screen.getByRole('button', { name: /全部导航/ }))
await userEvent.click(screen.getByRole('button', { name: /全部导航/ }))
expect(screen.queryByTestId('nav-overlay')).not.toBeInTheDocument()
})
})