Fix: Leerzeichen-Validierung für Fahrrad-Namen

- Trimmen von Leerzeichen am Anfang und Ende des Namens
- Validierung verhindert Namen, die nur aus Leerzeichen bestehen
- Optional-Felder (brand, model, notes) werden ebenfalls getrimmt
- Leere optionale Strings werden zu undefined konvertiert
- Erweiterte Testfälle für Leerzeichen-Validierung hinzugefügt
This commit is contained in:
Denis Urs Rudolph
2025-12-05 22:18:25 +01:00
parent de193bc783
commit b525c07ccc
3 changed files with 131 additions and 8 deletions

View File

@@ -3,11 +3,15 @@ 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(),
name: z
.string()
.min(1, 'Name ist erforderlich')
.trim()
.min(1, 'Name darf nicht nur aus Leerzeichen bestehen'),
brand: z.string().optional().transform((val) => val?.trim() || undefined),
model: z.string().optional().transform((val) => val?.trim() || undefined),
purchaseDate: z.string().datetime().optional().or(z.date().optional()),
notes: z.string().optional(),
notes: z.string().optional().transform((val) => val?.trim() || undefined),
})
const WearPartType = z.enum([
@@ -99,6 +103,76 @@ describe('Validation Schemas', () => {
const result = bikeSchema.safeParse(invalidData)
expect(result.success).toBe(false)
})
it('should reject bike with only whitespace in name', () => {
const invalidData = {
name: ' ',
}
const result = bikeSchema.safeParse(invalidData)
expect(result.success).toBe(false)
if (!result.success) {
expect(result.error.errors[0].message).toContain('Leerzeichen')
}
})
it('should trim whitespace from name', () => {
const validData = {
name: ' Mein Fahrrad ',
}
const result = bikeSchema.safeParse(validData)
expect(result.success).toBe(true)
if (result.success) {
expect(result.data.name).toBe('Mein Fahrrad')
}
})
it('should accept name with spaces in the middle', () => {
const validData = {
name: 'Mein Fahrrad',
}
const result = bikeSchema.safeParse(validData)
expect(result.success).toBe(true)
if (result.success) {
expect(result.data.name).toBe('Mein Fahrrad')
}
})
it('should trim whitespace from optional fields', () => {
const validData = {
name: 'Test Bike',
brand: ' Test Brand ',
model: ' Test Model ',
notes: ' Test Notes ',
}
const result = bikeSchema.safeParse(validData)
expect(result.success).toBe(true)
if (result.success) {
expect(result.data.brand).toBe('Test Brand')
expect(result.data.model).toBe('Test Model')
expect(result.data.notes).toBe('Test Notes')
}
})
it('should convert empty optional strings to undefined', () => {
const validData = {
name: 'Test Bike',
brand: ' ',
model: ' ',
notes: ' ',
}
const result = bikeSchema.safeParse(validData)
expect(result.success).toBe(true)
if (result.success) {
expect(result.data.brand).toBeUndefined()
expect(result.data.model).toBeUndefined()
expect(result.data.notes).toBeUndefined()
}
})
})
describe('wearPartSchema', () => {