Files
lpt-fe/src/__tests__/components/MyHead.spec.ts
T

107 lines
3.3 KiB
TypeScript

import { describe, it, expect, vi, beforeEach } from 'vitest'
import { computed, ref } from 'vue'
vi.mock('@/api/login', () => ({
login: vi.fn(),
logout: vi.fn().mockResolvedValue({ code: 200 }),
}))
vi.mock('element-plus', () => ({
ElMessage: {
success: vi.fn(),
error: vi.fn(),
warning: vi.fn(),
info: vi.fn(),
},
}))
import { logout } from '@/api/login'
import { ElMessage } from 'element-plus'
describe('MyHead.vue logic', () => {
beforeEach(() => {
vi.clearAllMocks()
localStorage.clear()
})
describe('route-based computed properties', () => {
it('isLoginRoute is true when path is /login', () => {
const routePath = ref('/login')
const isLoginRoute = computed(() => routePath.value === '/login')
expect(isLoginRoute.value).toBe(true)
})
it('isLoginRoute is false for other paths', () => {
const routePath = ref('/welcome')
const isLoginRoute = computed(() => routePath.value === '/login')
expect(isLoginRoute.value).toBe(false)
})
it('showBackButton is true for non-login, non-welcome routes', () => {
const routePath = ref('/study')
const showBackButton = computed(() => routePath.value !== '/login' && routePath.value !== '/welcome')
expect(showBackButton.value).toBe(true)
})
it('showBackButton is false on welcome route', () => {
const routePath = ref('/welcome')
const showBackButton = computed(() => routePath.value !== '/login' && routePath.value !== '/welcome')
expect(showBackButton.value).toBe(false)
})
it('showBackButton is false on login route', () => {
const routePath = ref('/login')
const showBackButton = computed(() => routePath.value !== '/login' && routePath.value !== '/welcome')
expect(showBackButton.value).toBe(false)
})
it('pageTitle is derived from route meta', () => {
const meta = { title: '学习任务' }
const pageTitle = computed(() => meta?.title as string | undefined)
expect(pageTitle.value).toBe('学习任务')
})
it('pageTitle is undefined when no meta title', () => {
const meta = {}
const pageTitle = computed(() => meta?.title as string | undefined)
expect(pageTitle.value).toBeUndefined()
})
})
describe('handleLogout logic', () => {
it('clears login state and navigates to login', async () => {
localStorage.setItem('isLoggedIn', 'true')
// Simulate handleLogout
try {
await logout()
} catch {
// Backend failure shouldn't block logout
} finally {
localStorage.removeItem('isLoggedIn')
ElMessage.success('已退出登录')
}
expect(localStorage.getItem('isLoggedIn')).toBeNull()
expect(ElMessage.success).toHaveBeenCalledWith('已退出登录')
})
it('clears login state even when API call fails', async () => {
vi.mocked(logout).mockRejectedValue(new Error('Network error'))
localStorage.setItem('isLoggedIn', 'true')
try {
await logout()
} catch {
// Expected
} finally {
localStorage.removeItem('isLoggedIn')
ElMessage.success('已退出登录')
}
expect(localStorage.getItem('isLoggedIn')).toBeNull()
expect(ElMessage.success).toHaveBeenCalledWith('已退出登录')
})
})
})