import { describe, it, expect, vi, beforeEach } from 'vitest' import { mount } from '@vue/test-utils' import ElementPlus from 'element-plus' import { 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(), })) function mountLogin() { return mount(Login, { shallow: true, global: { plugins: [ElementPlus, router], }, }) } function createForm(valid = true) { return { validate: (callback: (valid: boolean) => void) => callback(valid), } as any } describe('Login.vue', () => { beforeEach(async () => { vi.clearAllMocks() localStorage.clear() await router.push('/login') await router.isReady() }) it('isNotEmpty validator reports empty value and accepts filled value', () => { const wrapper = mountLogin() const callback = vi.fn() wrapper.vm.isNotEmpty({ message: '请输入账号!' } as any, '', callback) expect(callback).toHaveBeenCalledWith('请输入账号!') wrapper.vm.isNotEmpty({ message: '请输入账号!' } as any, 'admin', callback) expect(callback).toHaveBeenCalledWith() }) it('sets localStorage and navigates on successful login', async () => { vi.mocked(login).mockResolvedValue({ code: 200, message: '登录成功' } as any) const wrapper = mountLogin() wrapper.vm.registerData.username = 'admin' wrapper.vm.registerData.password = '123456' await wrapper.vm.submitForm(createForm(true)) expect(localStorage.getItem('isLoggedIn')).toBe('true') expect(ElMessage.success).toHaveBeenCalledWith('登录成功') expect(router.currentRoute.value.path).toBe('/welcome') }) it('shows error message on failed login', async () => { vi.mocked(login).mockResolvedValue({ code: 401, message: '密码错误' } as any) const wrapper = mountLogin() wrapper.vm.registerData.username = 'admin' wrapper.vm.registerData.password = 'wrong' await wrapper.vm.submitForm(createForm(true)) expect(ElMessage.error).toHaveBeenCalledWith('密码错误') expect(localStorage.getItem('isLoggedIn')).toBeNull() expect(router.currentRoute.value.path).toBe('/login') }) it('does not submit again while loading', async () => { let resolveLogin!: (value: any) => void vi.mocked(login).mockImplementation( () => new Promise((resolve) => { resolveLogin = resolve }), ) const wrapper = mountLogin() const firstSubmit = wrapper.vm.submitForm(createForm(true)) const secondSubmit = wrapper.vm.submitForm(createForm(true)) await Promise.resolve() expect(login).toHaveBeenCalledTimes(1) resolveLogin({ code: 200, message: '登录成功' }) await Promise.all([firstSubmit, secondSubmit]) expect(localStorage.getItem('isLoggedIn')).toBe('true') }) })