| 1 | import { describe, it, expect } from 'vitest'
|
| 2 | import { CreateMoodSchema } from '@app/schemas/mood.schema'
|
| 3 | import { CreateSleepRecordSchema } from '@app/schemas/sleepRecord.schema'
|
| 4 | import { UpdateUserPreferencesSchema } from '@app/schemas/user.schema'
|
| 5 | import { ActivateUserSchema } from '@app/schemas/auth.schema'
|
| 6 | import { InsightsQuerySchema } from '@app/schemas/insight.schema'
|
| 7 | import { LinkMoodSchema } from '@app/schemas/triggerMoodLink.schema'
|
| 8 |
|
| 9 | const moodEntry = {
|
| 10 | moment: '2026-10-17T12:00:00.000Z',
|
| 11 | selectedMood: 'GOOD',
|
| 12 | anxietyLevel: 5,
|
| 13 | stressLevel: 5,
|
| 14 | energyLevel: 5,
|
| 15 | moodComponents: [{ component: 'JOY', intensity: 'LIGHT' }],
|
| 16 | }
|
| 17 |
|
| 18 | const sleepRecord = { date: '2026-10-17T00:00:00.000Z', average: 7 }
|
| 19 |
|
| 20 | describe('mood level bounds', () => {
|
| 21 | it('accepts zero and ten on every level', () => {
|
| 22 | for (const level of ['anxietyLevel', 'stressLevel', 'energyLevel'] as const) {
|
| 23 | expect(CreateMoodSchema.safeParse({ ...moodEntry, [level]: 0 }).success).toBe(true)
|
| 24 | expect(CreateMoodSchema.safeParse({ ...moodEntry, [level]: 10 }).success).toBe(true)
|
| 25 | }
|
| 26 | })
|
| 27 |
|
| 28 | it('rejects a level above ten or below zero', () => {
|
| 29 | expect(CreateMoodSchema.safeParse({ ...moodEntry, energyLevel: 11 }).success).toBe(false)
|
| 30 | expect(CreateMoodSchema.safeParse({ ...moodEntry, energyLevel: -1 }).success).toBe(false)
|
| 31 | })
|
| 32 | })
|
| 33 |
|
| 34 | describe('sleep record average bounds', () => {
|
| 35 | it('accepts zero and fifteen hours', () => {
|
| 36 | expect(CreateSleepRecordSchema.safeParse({ ...sleepRecord, average: 0 }).success).toBe(true)
|
| 37 | expect(CreateSleepRecordSchema.safeParse({ ...sleepRecord, average: 15 }).success).toBe(true)
|
| 38 | })
|
| 39 |
|
| 40 | it('rejects an average outside the range', () => {
|
| 41 | expect(CreateSleepRecordSchema.safeParse({ ...sleepRecord, average: -0.5 }).success).toBe(false)
|
| 42 | expect(CreateSleepRecordSchema.safeParse({ ...sleepRecord, average: 15.5 }).success).toBe(false)
|
| 43 | })
|
| 44 | })
|
| 45 |
|
| 46 | describe('daily reminder time format', () => {
|
| 47 | it('accepts a two-digit hour and minute, and null to clear it', () => {
|
| 48 | expect(UpdateUserPreferencesSchema.safeParse({ dailyReminderTime: '08:30' }).success).toBe(true)
|
| 49 | expect(UpdateUserPreferencesSchema.safeParse({ dailyReminderTime: null }).success).toBe(true)
|
| 50 | })
|
| 51 |
|
| 52 | it('rejects a one-digit hour or a trailing seconds segment', () => {
|
| 53 | expect(UpdateUserPreferencesSchema.safeParse({ dailyReminderTime: '8:30' }).success).toBe(false)
|
| 54 | expect(
|
| 55 | UpdateUserPreferencesSchema.safeParse({ dailyReminderTime: '08:30:00' })
|
| 56 | .success,
|
| 57 | ).toBe(false)
|
| 58 | })
|
| 59 | })
|
| 60 |
|
| 61 | describe('activation code format', () => {
|
| 62 | it('accepts exactly six digits', () => {
|
| 63 | expect(ActivateUserSchema.safeParse({ code: '000123' }).success).toBe(true)
|
| 64 | })
|
| 65 |
|
| 66 | it('rejects the wrong length or non-digits', () => {
|
| 67 | for (const code of ['12345', '1234567', '12345a', 'abcdef']) {
|
| 68 | expect(ActivateUserSchema.safeParse({ code }).success).toBe(false)
|
| 69 | }
|
| 70 | })
|
| 71 | })
|
| 72 |
|
| 73 | describe('insights day string', () => {
|
| 74 | it('accepts a real yyyy-MM-dd day', () => {
|
| 75 | expect(InsightsQuerySchema.safeParse({ day: '2026-10-17' }).success).toBe(true)
|
| 76 | })
|
| 77 |
|
| 78 | it('rejects an unpadded, month-out-of-range, or impossible day', () => {
|
| 79 | expect(InsightsQuerySchema.safeParse({ day: '2026-10-7' }).success).toBe(false)
|
| 80 | expect(InsightsQuerySchema.safeParse({ day: '2026-13-01' }).success).toBe(false)
|
| 81 | expect(InsightsQuerySchema.safeParse({ day: '2026-02-30' }).success).toBe(false)
|
| 82 | })
|
| 83 | })
|
| 84 |
|
| 85 | describe('trigger link perceived impact', () => {
|
| 86 | it('accepts the one-to-five boundaries', () => {
|
| 87 | expect(LinkMoodSchema.safeParse({ moodId: 1, perceivedImpact: 1 }).success).toBe(true)
|
| 88 | expect(LinkMoodSchema.safeParse({ moodId: 1, perceivedImpact: 5 }).success).toBe(true)
|
| 89 | })
|
| 90 |
|
| 91 | it('rejects an impact off the scale or a non-positive mood', () => {
|
| 92 | expect(LinkMoodSchema.safeParse({ moodId: 1, perceivedImpact: 0 }).success).toBe(false)
|
| 93 | expect(LinkMoodSchema.safeParse({ moodId: 1, perceivedImpact: 6 }).success).toBe(false)
|
| 94 | expect(LinkMoodSchema.safeParse({ moodId: 0, perceivedImpact: 3 }).success).toBe(false)
|
| 95 | })
|
| 96 | })
|