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.
169 lines
4.7 KiB
TypeScript
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()
|
|
})
|
|
})
|
|
})
|