Add mobile accessibility and UI/UX improvements
- Add mobile card view for packages (replaces table on small screens) - Implement design tokens system for consistent styling - Add dark/light theme toggle with system preference support - Create reusable StatusBadge and EmptyState components - Add accessible form labels to package filters - Add compact mobile stats display in navigation - Add safe area insets for notched devices - Add reduced motion support for accessibility - Improve touch targets for WCAG compliance - Add unit tests for composables - Update Vuetify configuration and styling
This commit is contained in:
105
frontend/src/__tests__/composables/useAutoRefresh.spec.ts
Normal file
105
frontend/src/__tests__/composables/useAutoRefresh.spec.ts
Normal file
@@ -0,0 +1,105 @@
|
||||
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest'
|
||||
import { useAutoRefresh, useNowTimer } from '@/composables/useAutoRefresh'
|
||||
|
||||
// Mock Vue's onUnmounted
|
||||
vi.mock('vue', async () => {
|
||||
const actual = await vi.importActual('vue')
|
||||
return {
|
||||
...actual,
|
||||
onUnmounted: vi.fn(),
|
||||
}
|
||||
})
|
||||
|
||||
describe('useAutoRefresh', () => {
|
||||
beforeEach(() => {
|
||||
vi.useFakeTimers()
|
||||
})
|
||||
|
||||
afterEach(() => {
|
||||
vi.useRealTimers()
|
||||
})
|
||||
|
||||
describe('useAutoRefresh', () => {
|
||||
it('should call callback at specified interval', () => {
|
||||
const callback = vi.fn()
|
||||
const { start } = useAutoRefresh(callback, 1000)
|
||||
|
||||
start()
|
||||
expect(callback).not.toHaveBeenCalled()
|
||||
|
||||
vi.advanceTimersByTime(1000)
|
||||
expect(callback).toHaveBeenCalledTimes(1)
|
||||
|
||||
vi.advanceTimersByTime(1000)
|
||||
expect(callback).toHaveBeenCalledTimes(2)
|
||||
})
|
||||
|
||||
it('should stop calling callback after stop()', () => {
|
||||
const callback = vi.fn()
|
||||
const { start, stop } = useAutoRefresh(callback, 1000)
|
||||
|
||||
start()
|
||||
vi.advanceTimersByTime(1000)
|
||||
expect(callback).toHaveBeenCalledTimes(1)
|
||||
|
||||
stop()
|
||||
vi.advanceTimersByTime(2000)
|
||||
expect(callback).toHaveBeenCalledTimes(1) // Still 1
|
||||
})
|
||||
|
||||
it('should track running state', () => {
|
||||
const callback = vi.fn()
|
||||
const { start, stop, isRunning } = useAutoRefresh(callback, 1000)
|
||||
|
||||
expect(isRunning.value).toBe(false)
|
||||
|
||||
start()
|
||||
expect(isRunning.value).toBe(true)
|
||||
|
||||
stop()
|
||||
expect(isRunning.value).toBe(false)
|
||||
})
|
||||
|
||||
it('should restart interval on restart()', () => {
|
||||
const callback = vi.fn()
|
||||
const { start, restart } = useAutoRefresh(callback, 1000)
|
||||
|
||||
start()
|
||||
vi.advanceTimersByTime(500)
|
||||
|
||||
restart()
|
||||
vi.advanceTimersByTime(500)
|
||||
expect(callback).not.toHaveBeenCalled() // Timer was reset
|
||||
|
||||
vi.advanceTimersByTime(500)
|
||||
expect(callback).toHaveBeenCalledTimes(1)
|
||||
})
|
||||
})
|
||||
|
||||
describe('useNowTimer', () => {
|
||||
it('should update now value every second', () => {
|
||||
const { now, start } = useNowTimer()
|
||||
const initialValue = now.value
|
||||
|
||||
start()
|
||||
|
||||
vi.advanceTimersByTime(1000)
|
||||
expect(now.value).toBeGreaterThan(initialValue)
|
||||
|
||||
vi.advanceTimersByTime(1000)
|
||||
expect(now.value).toBeGreaterThan(initialValue + 1)
|
||||
})
|
||||
|
||||
it('should stop updating after stop()', () => {
|
||||
const { now, start, stop } = useNowTimer()
|
||||
|
||||
start()
|
||||
vi.advanceTimersByTime(1000)
|
||||
const valueAfterStart = now.value
|
||||
|
||||
stop()
|
||||
vi.advanceTimersByTime(2000)
|
||||
expect(now.value).toBe(valueAfterStart)
|
||||
})
|
||||
})
|
||||
})
|
||||
Reference in New Issue
Block a user