import { describe, it, expect } from 'vitest' import { z } from 'zod' // Define schemas directly in test to avoid import issues with Vitest const bikeSchema = z.object({ name: z.string().min(1, 'Name ist erforderlich'), brand: z.string().optional(), model: z.string().optional(), purchaseDate: z.string().datetime().optional().or(z.date().optional()), notes: z.string().optional(), }) const WearPartType = z.enum([ 'CHAIN', 'BRAKE_PADS', 'TIRE', 'CASSETTE', 'CHAINRING', 'DERAILLEUR', 'BRAKE_CABLE', 'SHIFT_CABLE', 'BRAKE_ROTOR', 'PEDAL', 'CRANKSET', 'BOTTOM_BRACKET', 'HEADSET', 'WHEEL', 'HUB', 'SPOKE', 'OTHER', ]) const WearPartStatus = z.enum([ 'ACTIVE', 'NEEDS_SERVICE', 'REPLACED', 'INACTIVE', ]) const wearPartSchema = z.object({ bikeId: z.string().min(1, 'Fahrrad-ID ist erforderlich'), type: WearPartType, brand: z.string().optional(), model: z.string().optional(), installDate: z.string().datetime().or(z.date()), installMileage: z.number().int().min(0).default(0), serviceInterval: z.number().int().min(1, 'Service-Intervall muss mindestens 1 km sein'), status: WearPartStatus.default('ACTIVE'), cost: z.number().positive().optional(), notes: z.string().optional(), }) const MaintenanceAction = z.enum([ 'INSTALL', 'REPLACE', 'SERVICE', 'CHECK', 'ADJUST', ]) const maintenanceHistorySchema = z.object({ wearPartId: z.string().min(1, 'Verschleißteil-ID ist erforderlich'), date: z.string().datetime().or(z.date()), mileage: z.number().int().min(0), action: MaintenanceAction, notes: z.string().optional(), cost: z.number().positive().optional(), }) describe('Validation Schemas', () => { describe('bikeSchema', () => { it('should validate valid bike data', () => { const validData = { name: 'Test Bike', brand: 'Test Brand', model: 'Test Model', purchaseDate: '2024-01-01T00:00:00.000Z', notes: 'Test notes', } const result = bikeSchema.safeParse(validData) expect(result.success).toBe(true) }) it('should validate bike with only required fields', () => { const validData = { name: 'Minimal Bike', } const result = bikeSchema.safeParse(validData) expect(result.success).toBe(true) }) it('should reject bike without name', () => { const invalidData = { brand: 'Test Brand', } const result = bikeSchema.safeParse(invalidData) expect(result.success).toBe(false) }) }) describe('wearPartSchema', () => { it('should validate valid wear part data', () => { const validData = { bikeId: 'test-bike-id', type: 'CHAIN', installDate: '2024-01-01T00:00:00.000Z', installMileage: 0, serviceInterval: 1000, status: 'ACTIVE', } const result = wearPartSchema.safeParse(validData) expect(result.success).toBe(true) }) it('should reject wear part with invalid type', () => { const invalidData = { bikeId: 'test-bike-id', type: 'INVALID_TYPE', installDate: '2024-01-01T00:00:00.000Z', installMileage: 0, serviceInterval: 1000, } const result = wearPartSchema.safeParse(invalidData) expect(result.success).toBe(false) }) it('should reject wear part with serviceInterval less than 1', () => { const invalidData = { bikeId: 'test-bike-id', type: 'CHAIN', installDate: '2024-01-01T00:00:00.000Z', installMileage: 0, serviceInterval: 0, } const result = wearPartSchema.safeParse(invalidData) expect(result.success).toBe(false) }) it('should reject wear part with negative installMileage', () => { const invalidData = { bikeId: 'test-bike-id', type: 'CHAIN', installDate: '2024-01-01T00:00:00.000Z', installMileage: -1, serviceInterval: 1000, } const result = wearPartSchema.safeParse(invalidData) expect(result.success).toBe(false) }) }) describe('maintenanceHistorySchema', () => { it('should validate valid maintenance history data', () => { const validData = { wearPartId: 'test-part-id', date: '2024-01-01T00:00:00.000Z', mileage: 500, action: 'SERVICE', notes: 'Regular service', cost: 50.0, } const result = maintenanceHistorySchema.safeParse(validData) expect(result.success).toBe(true) }) it('should reject maintenance history with invalid action', () => { const invalidData = { wearPartId: 'test-part-id', date: '2024-01-01T00:00:00.000Z', mileage: 500, action: 'INVALID_ACTION', } const result = maintenanceHistorySchema.safeParse(invalidData) expect(result.success).toBe(false) }) it('should reject maintenance history with negative mileage', () => { const invalidData = { wearPartId: 'test-part-id', date: '2024-01-01T00:00:00.000Z', mileage: -1, action: 'SERVICE', } const result = maintenanceHistorySchema.safeParse(invalidData) expect(result.success).toBe(false) }) }) })