107 lines
3.3 KiB
TypeScript
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('已退出登录')
|
|
})
|
|
})
|
|
})
|