Files
Ars-Font/tests/session-sidebar.spec.js
ROOG b107a5e680 master: 添加会话模块及界面改进
- 新增 ChatView 页面及其逻辑设计
- 修改 App.vue 以支持动态会话标题
- 调整 Sidebar 为固定高度及改进滚动样式
- 优化会话分页,添加 lastPage 逻辑
- 在 SessionSidebar 中实现刷新操作和路由同步
- 更新路由配置,添加 chat 相关路径
- 添加单元测试以覆盖新逻辑
2025-12-14 20:22:06 +08:00

138 lines
3.8 KiB
JavaScript

import { describe, it, expect, vi, beforeEach } from 'vitest'
import { mount, flushPromises } from '@vue/test-utils'
import { createRouter, createMemoryHistory } from 'vue-router'
import ElementPlus from 'element-plus'
import SessionSidebar from '../src/components/SessionSidebar.vue'
import LoginView from '../src/views/LoginView.vue'
import axios from 'axios'
vi.mock('axios', () => ({
default: {
get: vi.fn(),
},
}))
const mockedAxios = axios
const makeRouter = () =>
createRouter({
history: createMemoryHistory(),
routes: [
{ path: '/', name: 'login', component: LoginView },
{ path: '/welcome', name: 'welcome', component: LoginView },
{ path: '/chat/:id', name: 'chat', component: LoginView },
],
})
describe('SessionSidebar', () => {
beforeEach(() => {
localStorage.clear()
vi.clearAllMocks()
})
it('redirects to login without token', async () => {
const router = makeRouter()
router.push('/welcome')
await router.isReady()
mount(SessionSidebar, {
global: {
plugins: [router, ElementPlus],
},
})
await flushPromises()
expect(router.currentRoute.value.name).toBe('login')
})
it('renders sessions and selects one', async () => {
localStorage.setItem('ars-token', 'jwt-token')
mockedAxios.get.mockResolvedValue({
data: {
data: [
{
session_id: 's1',
session_name: 'Demo',
status: 'OPEN',
last_message_preview: 'Hi there',
last_seq: 3,
updated_at: '2025-02-14T10:00:00Z',
},
],
total: 1,
current_page: 1,
per_page: 20,
last_page: 1,
},
})
const router = makeRouter()
router.push('/welcome')
await router.isReady()
const wrapper = mount(SessionSidebar, {
global: {
plugins: [router, ElementPlus],
},
})
await flushPromises()
expect(mockedAxios.get).toHaveBeenCalledWith(
'http://localhost:8000/api/sessions',
expect.any(Object)
)
expect(wrapper.text()).toContain('Demo')
await wrapper.find('.session-item').trigger('click')
await flushPromises()
expect(localStorage.getItem('ars-current-session')).toBe('s1')
expect(router.currentRoute.value.name).toBe('chat')
})
it('resets page when refreshing after loading more', async () => {
localStorage.setItem('ars-token', 'jwt-token')
mockedAxios.get
.mockResolvedValueOnce({
data: {
data: [{ session_id: 's1', session_name: 'P1', status: 'OPEN' }],
meta: { total: 2, current_page: 1, per_page: 10, last_page: 2 },
},
})
.mockResolvedValueOnce({
data: {
data: [{ session_id: 's2', session_name: 'P2', status: 'OPEN' }],
meta: { total: 2, current_page: 2, per_page: 10, last_page: 2 },
},
})
.mockResolvedValueOnce({
data: {
data: [{ session_id: 's1', session_name: 'Refreshed', status: 'OPEN' }],
meta: { total: 1, current_page: 1, per_page: 10, last_page: 1 },
},
})
const router = makeRouter()
router.push('/welcome')
await router.isReady()
const wrapper = mount(SessionSidebar, {
global: {
plugins: [router, ElementPlus],
},
})
await flushPromises()
expect(wrapper.findAll('.session-item')).toHaveLength(1)
await wrapper.find('.load-more').trigger('click')
await flushPromises()
expect(mockedAxios.get.mock.calls[1][1].params.page).toBe(2)
expect(wrapper.findAll('.session-item')).toHaveLength(2)
await wrapper.find('[data-testid="refresh-btn"]').trigger('click')
await flushPromises()
expect(mockedAxios.get.mock.calls[2][1].params.page).toBe(1)
expect(wrapper.findAll('.session-item')).toHaveLength(1)
expect(wrapper.text()).toContain('Refreshed')
})
})