import { describe, expect, it } from 'vitest' import { lotDefaults, newPlantDefaults, packetProposalSchema, seedPacketSchema, PACKET_PLANT_COLOR, PACKET_PLANT_ICON, } from './seedPacket' // A full proposal as the backend sends it, for the schema + prefill tests. const proposal = { packet: { species: 'garlic', variety: 'Music', category: 'vegetable', vendor: "Johnny's", sku: 'G-123', lotCode: 'L9', packedForYear: 2026, daysToMaturity: 90, spacingCm: 15, seedCount: 12, }, candidates: [ { plant: { id: 7, name: 'Music', category: 'vegetable', spacingCm: 15, color: '#fff', icon: '🧄', notes: '', version: 1, createdAt: '2026-01-01T00:00:00Z', updatedAt: '2026-01-01T00:00:00Z', }, reason: 'exact name', }, ], suggestedName: 'Music', suggestedCategory: 'vegetable', } describe('seedPacketSchema', () => { it('fills defaults for a sparse packet (only what was printed)', () => { // A packet where the model only read a species — everything else absent. const p = seedPacketSchema.parse({ species: 'basil' }) expect(p.species).toBe('basil') expect(p.variety).toBe('') expect(p.spacingCm).toBeNull() expect(p.seedCount).toBeNull() expect(p.packedForYear).toBeNull() }) }) describe('packetProposalSchema', () => { it('parses a full proposal including candidates', () => { const p = packetProposalSchema.parse(proposal) expect(p.candidates).toHaveLength(1) expect(p.candidates[0].plant.id).toBe(7) expect(p.candidates[0].reason).toBe('exact name') expect(p.suggestedName).toBe('Music') }) it('defaults candidates to empty when absent', () => { const p = packetProposalSchema.parse({ packet: { species: 'kale' } }) expect(p.candidates).toEqual([]) expect(p.suggestedName).toBe('') }) }) describe('newPlantDefaults', () => { it('prefills name/category/spacing/days/vendor from the proposal', () => { const np = newPlantDefaults(packetProposalSchema.parse(proposal)) expect(np.name).toBe('Music') expect(np.category).toBe('vegetable') expect(np.spacingCm).toBe(15) expect(np.daysToMaturity).toBe(90) expect(np.vendor).toBe("Johnny's") // No icon/color on a packet — placeholders the user can change later. expect(np.icon).toBe(PACKET_PLANT_ICON) expect(np.color).toBe(PACKET_PLANT_COLOR) }) it('falls back to a safe category and default spacing when the packet lacks them', () => { const np = newPlantDefaults( packetProposalSchema.parse({ packet: { species: 'mystery' }, suggestedName: 'mystery', suggestedCategory: 'not-a-real-category', }), ) // An unknown category must not leak through — CreatePlant would reject it. expect(np.category).toBe('vegetable') // No printed spacing → the same default the manual form uses. expect(np.spacingCm).toBe(30) expect(np.daysToMaturity).toBeNull() }) }) describe('lotDefaults', () => { it('reads a seed count as " seeds"', () => { const lot = lotDefaults(seedPacketSchema.parse(proposal.packet)) expect(lot.quantity).toBe(12) expect(lot.unit).toBe('seeds') expect(lot.vendor).toBe("Johnny's") expect(lot.sku).toBe('G-123') expect(lot.lotCode).toBe('L9') expect(lot.packedForYear).toBe(2026) }) it('defaults to one packet when no seed count is printed', () => { const lot = lotDefaults(seedPacketSchema.parse({ species: 'basil' })) expect(lot.quantity).toBe(1) expect(lot.unit).toBe('packets') expect(lot.packedForYear).toBeNull() }) })