package telemetry import ( "testing" "time" ) func TestParseReading_Valid(t *testing.T) { receivedAt := time.Date(2026, 7, 26, 12, 0, 5, 0, time.UTC) raw := []byte(`{ "device_id": "esp32-abc123", "zone_id": "growbox-1", "sensor_type": "temperature", "value": 24.5, "timestamp": "2026-07-26T12:00:00Z" }`) got, err := ParseReading(raw, receivedAt) if err != nil { t.Fatalf("unexpected error: %v", err) } want := Reading{ DeviceID: "esp32-abc123", ZoneID: "growbox-1", SensorType: "temperature", Value: 24.5, RecordedAt: time.Date(2026, 7, 26, 12, 0, 0, 0, time.UTC), ReceivedAt: receivedAt, } if got != want { t.Fatalf("got %+v, want %+v", got, want) } } func TestParseReading_Invalid(t *testing.T) { receivedAt := time.Now() cases := map[string]string{ "malformed json": `{not json`, "missing device_id": `{ "zone_id": "growbox-1", "sensor_type": "temperature", "value": 1, "timestamp": "2026-07-26T12:00:00Z" }`, "missing zone_id": `{ "device_id": "esp32-1", "sensor_type": "temperature", "value": 1, "timestamp": "2026-07-26T12:00:00Z" }`, "missing sensor_type": `{ "device_id": "esp32-1", "zone_id": "growbox-1", "value": 1, "timestamp": "2026-07-26T12:00:00Z" }`, "missing timestamp": `{ "device_id": "esp32-1", "zone_id": "growbox-1", "sensor_type": "temperature", "value": 1 }`, "invalid timestamp format": `{ "device_id": "esp32-1", "zone_id": "growbox-1", "sensor_type": "temperature", "value": 1, "timestamp": "not-a-date" }`, "value wrong type": `{ "device_id": "esp32-1", "zone_id": "growbox-1", "sensor_type": "temperature", "value": "not-a-number", "timestamp": "2026-07-26T12:00:00Z" }`, } for name, raw := range cases { t.Run(name, func(t *testing.T) { if _, err := ParseReading([]byte(raw), receivedAt); err == nil { t.Fatalf("expected error, got nil") } }) } }