SEC_Warehouse/tests/unit/utils/auth.spec.ts

103 lines
3.7 KiB
TypeScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { describe, it, expect, beforeEach, vi } from 'vitest'
// navigation → Taro 只透传最终参数,mock 记录调用
const mockNavigateTo = vi.hoisted(() => vi.fn())
const mockReLaunch = vi.hoisted(() => vi.fn())
const mockRedirectTo = vi.hoisted(() => vi.fn())
const mockSwitchTab = vi.hoisted(() => vi.fn())
vi.mock('@tarojs/taro', () => ({
default: {
navigateTo: mockNavigateTo,
reLaunch: mockReLaunch,
redirectTo: mockRedirectTo,
switchTab: mockSwitchTab,
navigateBack: vi.fn()
}
}))
// store mock:authState 可变,支持模拟已登录/未登录两种状态
const authState = vi.hoisted(() => ({ token: null as string | null }))
vi.mock('@/store', () => ({
store: {
getState: () => ({ auth: { token: authState.token } })
}
}))
// storage mock:内存 Map,用于验证 store 未恢复时的兜底读取
const mem = vi.hoisted(() => new Map<string, unknown>())
vi.mock('@/utils/storage', () => ({
storage: {
get: <T>(key: string): T | null => (mem.has(key) ? (mem.get(key) as T) : null),
set: <T>(key: string, value: T): void => { mem.set(key, value) },
remove: (key: string): void => { mem.delete(key) }
}
}))
import { navigateTo, reLaunch, redirectTo, switchTab } from '@/utils/navigation'
import { isProtectedPage } from '@/utils/auth'
import { ROUTES } from '@/constants/routes'
beforeEach(() => {
authState.token = null
mem.clear()
mockNavigateTo.mockClear()
mockReLaunch.mockClear()
mockRedirectTo.mockClear()
mockSwitchTab.mockClear()
})
describe('navigation 登录守卫', () => {
it('未登录 navigateTo 受保护页:url 被改写为登录页', () => {
navigateTo(ROUTES.FAMILY)
expect(mockNavigateTo).toHaveBeenCalledWith({ url: ROUTES.LOGIN })
})
it('未登录 reLaunch/redirectTo 到受保护页被守卫(tab 页在游客白名单放行)', () => {
reLaunch(ROUTES.DEVICE_ADD)
redirectTo(ROUTES.FAMILY)
expect(mockReLaunch).toHaveBeenCalledWith({ url: ROUTES.LOGIN })
expect(mockRedirectTo).toHaveBeenCalledWith({ url: ROUTES.LOGIN })
})
it('未登录 switchTab 到 tab 页:放行(游客模式白名单,微信审核要求)', () => {
switchTab(ROUTES.EVENT)
expect(mockSwitchTab).toHaveBeenCalledWith({ url: ROUTES.EVENT })
})
it('已登录 navigateTo:原样放行', () => {
authState.token = 'tk-1'
navigateTo(ROUTES.FAMILY)
expect(mockNavigateTo).toHaveBeenCalledWith({ url: ROUTES.FAMILY })
})
it('未登录访问登录页:放行(登录页在公开名单)', () => {
navigateTo(ROUTES.LOGIN)
expect(mockNavigateTo).toHaveBeenCalledWith({ url: ROUTES.LOGIN })
})
it('带 query 的受保护页:跳登录页不带残留参数', () => {
navigateTo(`${ROUTES.FAMILY_DETAIL}?id=3`)
expect(mockNavigateTo).toHaveBeenCalledWith({ url: ROUTES.LOGIN })
})
it('store 无 token 但 storage 有(冷启动兜底):放行', () => {
mem.set('auth_token', 'tk-saved')
navigateTo(ROUTES.HOME)
expect(mockNavigateTo).toHaveBeenCalledWith({ url: ROUTES.HOME })
})
})
describe('isProtectedPage', () => {
it('登录页、四个 tab 页与协议/BLE 配网页返回 false(游客可浏览),其余页面返回 true', () => {
expect(isProtectedPage(ROUTES.LOGIN)).toBe(false)
expect(isProtectedPage(ROUTES.HOME)).toBe(false)
expect(isProtectedPage(ROUTES.DEVICE_LIST)).toBe(false)
expect(isProtectedPage(ROUTES.EVENT)).toBe(false)
expect(isProtectedPage(ROUTES.MINE)).toBe(false)
expect(isProtectedPage(ROUTES.AGREEMENT)).toBe(false)
expect(isProtectedPage(ROUTES.DEVICE_BLE_CONFIG)).toBe(false)
expect(isProtectedPage(ROUTES.FAMILY)).toBe(true)
expect(isProtectedPage(`${ROUTES.LOGIN}?from=xxx`)).toBe(false)
})
})