Files
user-system/frontend/admin/src/lib/storage/index.test.ts
long-agent 40d146b6aa test: add Stage 1 lib and Stage 2 services test coverage
Add comprehensive unit tests for:
- lib layer: config, device-fingerprint, errors, storage, hooks/useBreadcrumbs, http
- services layer: devices, login-logs, operation-logs, permissions, profile, roles, settings, stats, import-export

All 491 tests pass across 74 test files.
2026-04-17 23:59:15 +08:00

169 lines
4.7 KiB
TypeScript

import { describe, expect, it, beforeEach, afterEach, vi } from 'vitest'
import {
getRefreshToken,
setRefreshToken,
clearRefreshToken,
hasRefreshToken,
hasSessionPresenceCookie,
} from './token-storage'
describe('lib/storage/token-storage', () => {
beforeEach(() => {
clearRefreshToken()
vi.clearAllMocks()
})
afterEach(() => {
clearRefreshToken()
})
describe('getRefreshToken', () => {
it('should return null initially', () => {
expect(getRefreshToken()).toBeNull()
})
it('should return the token after setting', () => {
setRefreshToken('test-token')
expect(getRefreshToken()).toBe('test-token')
})
it('should return null after clearing', () => {
setRefreshToken('test-token')
clearRefreshToken()
expect(getRefreshToken()).toBeNull()
})
})
describe('setRefreshToken', () => {
it('should set a valid token', () => {
setRefreshToken('valid-token')
expect(getRefreshToken()).toBe('valid-token')
})
it('should handle null input', () => {
setRefreshToken('existing-token')
setRefreshToken(null)
expect(getRefreshToken()).toBeNull()
})
it('should handle undefined input', () => {
setRefreshToken('existing-token')
setRefreshToken(undefined)
expect(getRefreshToken()).toBeNull()
})
it('should handle empty string', () => {
setRefreshToken('existing-token')
setRefreshToken('')
expect(getRefreshToken()).toBeNull()
})
it('should handle whitespace-only string', () => {
setRefreshToken('existing-token')
setRefreshToken(' ')
expect(getRefreshToken()).toBeNull()
})
it('should trim whitespace from token', () => {
setRefreshToken(' trimmed-token ')
expect(getRefreshToken()).toBe('trimmed-token')
})
})
describe('clearRefreshToken', () => {
it('should clear the token', () => {
setRefreshToken('test-token')
clearRefreshToken()
expect(getRefreshToken()).toBeNull()
})
it('should be safe to call multiple times', () => {
clearRefreshToken()
clearRefreshToken()
clearRefreshToken()
expect(getRefreshToken()).toBeNull()
})
})
describe('hasRefreshToken', () => {
it('should return false initially', () => {
expect(hasRefreshToken()).toBe(false)
})
it('should return true after setting token', () => {
setRefreshToken('test-token')
expect(hasRefreshToken()).toBe(true)
})
it('should return false after clearing token', () => {
setRefreshToken('test-token')
clearRefreshToken()
expect(hasRefreshToken()).toBe(false)
})
it('should return false for empty token', () => {
setRefreshToken('')
expect(hasRefreshToken()).toBe(false)
})
})
describe('hasSessionPresenceCookie', () => {
it('should return false when cookie is not set', () => {
// In test environment, document.cookie may be empty
const result = hasSessionPresenceCookie()
expect(typeof result).toBe('boolean')
})
it('should detect session presence cookie', () => {
// Set the cookie
document.cookie = 'ums_session_present=1'
expect(hasSessionPresenceCookie()).toBe(true)
// Clean up
document.cookie = 'ums_session_present=; expires=Thu, 01 Jan 1970 00:00:00 GMT'
})
it('should return false when other cookies exist but not session cookie', () => {
document.cookie = 'other_cookie=value'
expect(hasSessionPresenceCookie()).toBe(false)
// Clean up
document.cookie = 'other_cookie=; expires=Thu, 01 Jan 1970 00:00:00 GMT'
})
it('should handle multiple cookies', () => {
document.cookie = 'cookie1=value1'
document.cookie = 'ums_session_present=1'
document.cookie = 'cookie2=value2'
expect(hasSessionPresenceCookie()).toBe(true)
// Clean up
document.cookie = 'cookie1=; expires=Thu, 01 Jan 1970 00:00:00 GMT'
document.cookie = 'ums_session_present=; expires=Thu, 01 Jan 1970 00:00:00 GMT'
document.cookie = 'cookie2=; expires=Thu, 01 Jan 1970 00:00:00 GMT'
})
})
describe('security considerations', () => {
it('should not store token in localStorage', () => {
setRefreshToken('test-token')
// Token should not be in localStorage
expect(localStorage.getItem('refreshToken')).toBeFalsy()
expect(localStorage.getItem('refresh_token')).toBeFalsy()
})
it('should not store token in sessionStorage', () => {
setRefreshToken('test-token')
// Token should not be in sessionStorage
expect(sessionStorage.getItem('refreshToken')).toBeFalsy()
expect(sessionStorage.getItem('refresh_token')).toBeFalsy()
})
})
})