import { describe, it, expect, vi, beforeEach } from 'vitest' import { mount } from '@vue/test-utils' import { createRouter, createMemoryHistory } from 'vue-router' import { reactive, ref } from 'vue' // Mock API vi.mock('@/api/login', () => ({ login: vi.fn(), logout: vi.fn(), })) // Mock Element Plus vi.mock('element-plus', () => ({ ElMessage: { success: vi.fn(), error: vi.fn(), warning: vi.fn(), info: vi.fn(), }, })) import { login } from '@/api/login' import { ElMessage } from 'element-plus' function createTestRouter() { return createRouter({ history: createMemoryHistory(), routes: [ { path: '/login', component: { template: '
' } }, { path: '/welcome', component: { template: '' } }, ], }) } describe('Login.vue logic', () => { beforeEach(() => { vi.clearAllMocks() localStorage.clear() }) describe('isNotEmpty validator', () => { it('calls callback with error message when value is empty', () => { const callback = vi.fn() const rule = { message: '请输入账号!' } // isNotEmpty logic const value = '' if (!value) { callback(rule.message) } else { callback() } expect(callback).toHaveBeenCalledWith('请输入账号!') }) it('calls callback without error when value is present', () => { const callback = vi.fn() const rule = { message: '请输入账号!' } const value = 'admin' if (!value) { callback(rule.message) } else { callback() } expect(callback).toHaveBeenCalledWith() }) }) describe('submitForm logic', () => { it('sets localStorage and navigates on successful login', async () => { vi.mocked(login).mockResolvedValue({ code: 200, message: '登录成功' } as any) const router = createTestRouter() await router.push('/login') await router.isReady() // Simulate submitForm logic const username = 'admin' const password = '123456' const result = await login(username, password) if (result.code === 200) { localStorage.setItem('isLoggedIn', 'true') ElMessage.success(result.message) await router.push('/welcome') } 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 result = await login('admin', 'wrong') if (result.code !== 200) { ElMessage.error(result.message) } expect(ElMessage.error).toHaveBeenCalledWith('密码错误') expect(localStorage.getItem('isLoggedIn')).toBeNull() }) it('does not submit when already loading', async () => { const loading = ref(true) // Simulate guard: if (!formEl || loading.value) return; if (loading.value) { // Early return - no API call } expect(login).not.toHaveBeenCalled() }) }) })