test(jobs-time-filter): voeg unit-tests toe voor isWithinTimeWindow en UserSettings-schema

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Scrum4Me Agent 2026-05-14 20:33:11 +02:00
parent fc87729597
commit d30662ad1e
2 changed files with 69 additions and 0 deletions

View file

@ -0,0 +1,57 @@
import { describe, expect, it } from 'vitest'
import { isWithinTimeWindow } from '@/lib/jobs-time-filter'
const HOUR_MS = 60 * 60 * 1000
describe('isWithinTimeWindow', () => {
it("returns true for filter='all' regardless of age", () => {
const old = new Date(0)
expect(isWithinTimeWindow(old, 'all')).toBe(true)
})
describe("filter='1h'", () => {
const now = Date.now()
it('returns true for a job created 30 minutes ago', () => {
const createdAt = new Date(now - 30 * 60 * 1000)
expect(isWithinTimeWindow(createdAt, '1h', now)).toBe(true)
})
it('returns false for a job created 90 minutes ago', () => {
const createdAt = new Date(now - 90 * 60 * 1000)
expect(isWithinTimeWindow(createdAt, '1h', now)).toBe(false)
})
})
describe("filter='24h'", () => {
const now = Date.now()
it('returns true for a job created 23 hours ago', () => {
const createdAt = new Date(now - 23 * HOUR_MS)
expect(isWithinTimeWindow(createdAt, '24h', now)).toBe(true)
})
it('returns false for a job created 25 hours ago', () => {
const createdAt = new Date(now - 25 * HOUR_MS)
expect(isWithinTimeWindow(createdAt, '24h', now)).toBe(false)
})
})
describe('accepts both Date and ISO string for createdAt', () => {
const now = Date.now()
const recent = new Date(now - 30 * 60 * 1000)
it('accepts a Date object', () => {
expect(isWithinTimeWindow(recent, '1h', now)).toBe(true)
})
it('accepts an ISO string', () => {
expect(isWithinTimeWindow(recent.toISOString(), '1h', now)).toBe(true)
})
})
it('returns true for an invalid date string (fail-open)', () => {
expect(isWithinTimeWindow('not-a-date', '1h')).toBe(true)
})
})

View file

@ -107,6 +107,7 @@ describe('UserSettingsSchema', () => {
pbiList: { sort: 'priority', filterPriority: 'all', filterStatus: 'ready', sortDir: 'desc' }, pbiList: { sort: 'priority', filterPriority: 'all', filterStatus: 'ready', sortDir: 'desc' },
storyPanel: { sort: 'date' }, storyPanel: { sort: 'date' },
jobsColumns: { 'queue:active': { kinds: ['TASK_IMPLEMENTATION'], statuses: [] } }, jobsColumns: { 'queue:active': { kinds: ['TASK_IMPLEMENTATION'], statuses: [] } },
jobs: { timeFilter: '24h' },
}, },
devTools: { debugMode: true }, devTools: { debugMode: true },
layout: { layout: {
@ -117,6 +118,17 @@ describe('UserSettingsSchema', () => {
expect(result.success).toBe(true) expect(result.success).toBe(true)
}) })
it('accepts views.jobs.timeFilter and returns it via parseUserSettings', () => {
const input = { views: { jobs: { timeFilter: '1h' as const } } }
const result = parseUserSettings(input)
expect(result).toEqual(input)
})
it('rejects an invalid views.jobs.timeFilter value', () => {
const result = UserSettingsSchema.safeParse({ views: { jobs: { timeFilter: 'BOGUS' } } })
expect(result.success).toBe(false)
})
it('accepts layout-only settings', () => { it('accepts layout-only settings', () => {
expect(UserSettingsSchema.safeParse({ expect(UserSettingsSchema.safeParse({
layout: { splitPanePositions: { x: [50, 50] }, activeSprints: { p: 's' } }, layout: { splitPanePositions: { x: [50, 50] }, activeSprints: { p: 's' } },