72 lines
2.9 KiB
TypeScript
72 lines
2.9 KiB
TypeScript
import { describe, it, expect, vi, beforeEach } from 'vitest'
|
|
import { flushPromises, mount } from '@vue/test-utils'
|
|
import ElementPlus, { ElMessage } from 'element-plus'
|
|
import Login from '@/components/Login.vue'
|
|
import router from '@/router'
|
|
import { login } from '@/api/login'
|
|
|
|
vi.mock('@/api/login', () => ({
|
|
login: vi.fn(),
|
|
logout: vi.fn(),
|
|
}))
|
|
|
|
/**
|
|
* 交互式集成测试:真实挂载 Login,通过 setValue / trigger('click') 模拟用户行为,
|
|
* 断言提交链路(凭证传递、成功/失败分支、localStorage 与路由结果)。
|
|
*
|
|
* 注意:jsdom 下 Element Plus 的 callback 式表单校验不可靠(空表单也可能判有效),
|
|
* “空账号被校验拦截”这类行为由 e2e/login.spec 在真实浏览器中覆盖,此处不重复断言。
|
|
*/
|
|
describe('Login 交互流程(集成)', () => {
|
|
beforeEach(async () => {
|
|
vi.clearAllMocks()
|
|
localStorage.clear()
|
|
await router.push('/login')
|
|
await router.isReady()
|
|
})
|
|
|
|
const mountLogin = async () => {
|
|
const wrapper = mount(Login, {
|
|
global: { plugins: [ElementPlus, router] },
|
|
})
|
|
await flushPromises()
|
|
return wrapper
|
|
}
|
|
|
|
const findSubmitButton = (wrapper: ReturnType<typeof mount> extends Promise<infer T> ? T : never) =>
|
|
wrapper.findAll('button').find((b) => b.text().includes('进入系统'))!
|
|
|
|
it('填写账号密码后点击“进入系统”,提交凭证并跳转 /welcome', async () => {
|
|
vi.mocked(login).mockResolvedValue({ code: 200, message: '登录成功' } as any)
|
|
const wrapper = await mountLogin()
|
|
|
|
await wrapper.find('input[placeholder="请输入账号"]').setValue('admin')
|
|
await wrapper.find('input[placeholder="请输入密码"]').setValue('123456')
|
|
await findSubmitButton(wrapper).trigger('click')
|
|
// /welcome 是懒加载路由,动态 import 需要宏任务,用 waitFor 轮询等待到达
|
|
await vi.waitFor(() => expect(router.currentRoute.value.path).toBe('/welcome'))
|
|
|
|
expect(login).toHaveBeenCalledWith('admin', '123456')
|
|
expect(localStorage.getItem('isLoggedIn')).toBe('true')
|
|
expect(ElMessage.success).toHaveBeenCalledWith('登录成功')
|
|
wrapper.unmount()
|
|
})
|
|
|
|
it('后端返回失败时提示错误、不写登录标记、不跳转', async () => {
|
|
vi.mocked(login).mockResolvedValue({ code: 500, message: '账号或密码错误' } as any)
|
|
const wrapper = await mountLogin()
|
|
|
|
await wrapper.find('input[placeholder="请输入账号"]').setValue('admin')
|
|
await wrapper.find('input[placeholder="请输入密码"]').setValue('wrong-pass')
|
|
await findSubmitButton(wrapper).trigger('click')
|
|
await flushPromises()
|
|
await flushPromises()
|
|
|
|
expect(login).toHaveBeenCalledWith('admin', 'wrong-pass')
|
|
expect(ElMessage.error).toHaveBeenCalledWith('账号或密码错误')
|
|
expect(localStorage.getItem('isLoggedIn')).toBeNull()
|
|
expect(router.currentRoute.value.path).toBe('/login')
|
|
wrapper.unmount()
|
|
})
|
|
})
|