197 lines
6.3 KiB
TypeScript
197 lines
6.3 KiB
TypeScript
import { describe, it, expect, vi, beforeEach } from 'vitest'
|
|
import { setActivePinia, createPinia } from 'pinia'
|
|
import { useUserStore } from '../user'
|
|
|
|
// Mock the api module
|
|
vi.mock('@/utils/request', () => ({
|
|
api: {
|
|
get: vi.fn(),
|
|
post: vi.fn(),
|
|
},
|
|
}))
|
|
|
|
describe('useUserStore', () => {
|
|
beforeEach(() => {
|
|
setActivePinia(createPinia())
|
|
localStorage.clear()
|
|
vi.restoreAllMocks()
|
|
})
|
|
|
|
describe('initial state', () => {
|
|
it('starts with null values when localStorage is empty', () => {
|
|
const store = useUserStore()
|
|
|
|
expect(store.token).toBeNull()
|
|
expect(store.refreshToken).toBeNull()
|
|
expect(store.user).toBeNull()
|
|
expect(store.isLoggedIn).toBe(false)
|
|
expect(store.username).toBe('')
|
|
})
|
|
|
|
it('restores token from localStorage', () => {
|
|
localStorage.setItem('access_token', 'header.payload.signature')
|
|
localStorage.setItem('refresh_token', 'rh.rp.rs')
|
|
|
|
const store = useUserStore()
|
|
|
|
expect(store.token).toBe('header.payload.signature')
|
|
expect(store.refreshToken).toBe('rh.rp.rs')
|
|
expect(store.isLoggedIn).toBe(true)
|
|
})
|
|
|
|
it('restores user info from localStorage', () => {
|
|
const savedUser = { id: 1, username: 'admin', email: 'a@b.com', role: 'admin', status: 1 }
|
|
localStorage.setItem('user', JSON.stringify(savedUser))
|
|
|
|
const store = useUserStore()
|
|
|
|
expect(store.user).toEqual(savedUser)
|
|
expect(store.username).toBe('admin')
|
|
expect(store.isAdmin).toBe(true)
|
|
})
|
|
|
|
it('handles corrupted user data in localStorage', () => {
|
|
localStorage.setItem('user', 'invalid-json{')
|
|
|
|
const store = useUserStore()
|
|
|
|
expect(store.user).toBeNull()
|
|
})
|
|
})
|
|
|
|
describe('setToken', () => {
|
|
it('sets tokens in store and localStorage', () => {
|
|
const store = useUserStore()
|
|
|
|
store.setToken('header.payload.signature', 'rh.rp.rs')
|
|
|
|
expect(store.token).toBe('header.payload.signature')
|
|
expect(store.refreshToken).toBe('rh.rp.rs')
|
|
expect(localStorage.getItem('access_token')).toBe('header.payload.signature')
|
|
expect(localStorage.getItem('refresh_token')).toBe('rh.rp.rs')
|
|
expect(store.isLoggedIn).toBe(true)
|
|
})
|
|
})
|
|
|
|
describe('setToken with remember=false', () => {
|
|
it('does not persist tokens to localStorage', () => {
|
|
const store = useUserStore()
|
|
|
|
store.setToken('h.p.s', 'r.p.s', false)
|
|
|
|
expect(store.token).toBe('h.p.s')
|
|
expect(store.refreshToken).toBe('r.p.s')
|
|
expect(localStorage.getItem('access_token')).toBeNull()
|
|
expect(localStorage.getItem('refresh_token')).toBeNull()
|
|
})
|
|
|
|
it('clears existing user from localStorage', () => {
|
|
localStorage.setItem('user', JSON.stringify({ id: 1, username: 'old' }))
|
|
|
|
const store = useUserStore()
|
|
store.setToken('h.p.s', 'r.p.s', false)
|
|
|
|
expect(localStorage.getItem('user')).toBeNull()
|
|
})
|
|
})
|
|
|
|
describe('setUser', () => {
|
|
it('persists to localStorage when remember=true', () => {
|
|
const store = useUserStore()
|
|
store.setToken('h.p.s', 'r.p.s', true)
|
|
const userInfo = { id: 1, username: 'test', email: 't@t.com', role: 'user', status: 1 }
|
|
|
|
store.setUser(userInfo)
|
|
|
|
expect(store.user).toEqual(userInfo)
|
|
expect(store.username).toBe('test')
|
|
expect(store.isAdmin).toBe(false)
|
|
expect(JSON.parse(localStorage.getItem('user')!)).toEqual(userInfo)
|
|
})
|
|
|
|
it('does not persist to localStorage by default (remember=false)', () => {
|
|
const store = useUserStore()
|
|
const userInfo = { id: 1, username: 'test', email: 't@t.com', role: 'user', status: 1 }
|
|
|
|
store.setUser(userInfo)
|
|
|
|
expect(store.user).toEqual(userInfo)
|
|
expect(localStorage.getItem('user')).toBeNull()
|
|
})
|
|
|
|
it('does not write to localStorage after setToken(remember=false)', () => {
|
|
const store = useUserStore()
|
|
store.setToken('h.p.s', 'r.p.s', false)
|
|
|
|
const userInfo = { id: 1, username: 'test', email: 't@t.com', role: 'user', status: 1 }
|
|
store.setUser(userInfo)
|
|
|
|
expect(store.user).toEqual(userInfo)
|
|
expect(localStorage.getItem('user')).toBeNull()
|
|
})
|
|
})
|
|
|
|
describe('logout', () => {
|
|
it('clears all state and localStorage', () => {
|
|
const store = useUserStore()
|
|
store.setToken('h.p.s', 'r.p.s')
|
|
store.setUser({ id: 1, username: 'a', email: 'a@a.com', role: 'admin', status: 1 })
|
|
|
|
store.logout()
|
|
|
|
expect(store.token).toBeNull()
|
|
expect(store.refreshToken).toBeNull()
|
|
expect(store.user).toBeNull()
|
|
expect(store.isLoggedIn).toBe(false)
|
|
expect(localStorage.getItem('access_token')).toBeNull()
|
|
expect(localStorage.getItem('refresh_token')).toBeNull()
|
|
expect(localStorage.getItem('user')).toBeNull()
|
|
})
|
|
|
|
it('resets _remember so subsequent setUser does not persist', () => {
|
|
const store = useUserStore()
|
|
store.setToken('h.p.s', 'r.p.s', true)
|
|
store.setUser({ id: 1, username: 'a', email: 'a@a.com', role: 'admin', status: 1 })
|
|
expect(localStorage.getItem('user')).not.toBeNull()
|
|
|
|
store.logout()
|
|
store.setUser({ id: 2, username: 'b', email: 'b@b.com', role: 'user', status: 1 })
|
|
|
|
expect(store.user?.username).toBe('b')
|
|
expect(localStorage.getItem('user')).toBeNull()
|
|
})
|
|
})
|
|
|
|
describe('fetchCurrentUser', () => {
|
|
it('fetches user from API and updates store', async () => {
|
|
const { api } = await import('@/utils/request')
|
|
const mockUser = { id: 1, username: 'fetched', email: 'f@f.com', role: 'admin', status: 1 }
|
|
vi.mocked(api.get).mockResolvedValueOnce(mockUser)
|
|
|
|
const store = useUserStore()
|
|
const result = await store.fetchCurrentUser()
|
|
|
|
expect(api.get).toHaveBeenCalledWith('/api/v1/me')
|
|
expect(result).toEqual(mockUser)
|
|
expect(store.user).toEqual(mockUser)
|
|
expect(store.isAdmin).toBe(true)
|
|
})
|
|
})
|
|
|
|
describe('computed properties', () => {
|
|
it('isAdmin returns true for admin role', () => {
|
|
const store = useUserStore()
|
|
store.setUser({ id: 1, username: 'a', email: 'a@a.com', role: 'admin', status: 1 })
|
|
|
|
expect(store.isAdmin).toBe(true)
|
|
})
|
|
|
|
it('isAdmin returns false for non-admin role', () => {
|
|
const store = useUserStore()
|
|
store.setUser({ id: 1, username: 'u', email: 'u@u.com', role: 'user', status: 1 })
|
|
|
|
expect(store.isAdmin).toBe(false)
|
|
})
|
|
})
|
|
})
|