types_json_test.go
package db
import (
"encoding/json"
"testing"
"time"
)
func TestJSONTimeMarshalJSON(t *testing.T) {
ts := time.Date(2025, 3, 14, 9, 26, 53, 0, time.UTC)
jt := JSONTime(ts)
b, err := json.Marshal(jt)
if err != nil {
t.Fatalf("MarshalJSON error: %v", err)
}
want := `"2025-03-14T09:26:53Z"`
if string(b) != want {
t.Errorf("got %s, want %s", string(b), want)
}
}
func TestJt(t *testing.T) {
ts := time.Date(2025, 1, 1, 0, 0, 0, 0, time.UTC)
result := jt(ts)
if time.Time(result) != ts {
t.Errorf("jt() did not preserve time: got %v, want %v", time.Time(result), ts)
}
}
func TestDatasetMarshalJSON(t *testing.T) {
desc := "test description"
d := Dataset{
ID: "ds_abc1234567",
Name: "Test Dataset",
Description: &desc,
CreatedAt: time.Date(2025, 1, 1, 0, 0, 0, 0, time.UTC),
LastModified: time.Date(2025, 6, 1, 0, 0, 0, 0, time.UTC),
Active: true,
Type: DatasetTypeStructured,
}
b, err := json.Marshal(d)
if err != nil {
t.Fatalf("MarshalJSON error: %v", err)
}
var m map[string]any
if err := json.Unmarshal(b, &m); err != nil {
t.Fatalf("unmarshal error: %v", err)
}
if m["id"] != "ds_abc1234567" {
t.Errorf("id = %v, want ds_abc1234567", m["id"])
}
if m["name"] != "Test Dataset" {
t.Errorf("name = %v", m["name"])
}
if m["description"] != "test description" {
t.Errorf("description = %v", m["description"])
}
if m["type"] != "structured" {
t.Errorf("type = %v", m["type"])
}
if m["active"] != true {
t.Errorf("active = %v", m["active"])
}
// Timestamps should be RFC3339 strings, not raw numbers
if _, ok := m["created_at"].(string); !ok {
t.Errorf("created_at should be string, got %T", m["created_at"])
}
}
func TestDatasetMarshalJSON_NilDescription(t *testing.T) {
d := Dataset{
ID: "ds_nil0000000",
Name: "No Desc",
Description: nil,
CreatedAt: time.Date(2025, 1, 1, 0, 0, 0, 0, time.UTC),
LastModified: time.Date(2025, 1, 1, 0, 0, 0, 0, time.UTC),
Active: true,
Type: DatasetTypeUnstructured,
}
b, err := json.Marshal(d)
if err != nil {
t.Fatalf("MarshalJSON error: %v", err)
}
var m map[string]any
if err := json.Unmarshal(b, &m); err != nil {
t.Fatalf("unmarshal error: %v", err)
}
if m["description"] != nil {
t.Errorf("expected nil description, got %v", m["description"])
}
}
func TestLocationMarshalJSON(t *testing.T) {
desc := "loc desc"
l := Location{
ID: "loc_test12345",
DatasetID: "ds_abc1234567",
Name: "Test Location",
Latitude: -36.8485,
Longitude: 174.7633,
Description: &desc,
CreatedAt: time.Date(2025, 2, 1, 0, 0, 0, 0, time.UTC),
LastModified: time.Date(2025, 2, 1, 0, 0, 0, 0, time.UTC),
Active: true,
TimezoneID: "Pacific/Auckland",
}
b, err := json.Marshal(l)
if err != nil {
t.Fatalf("MarshalJSON error: %v", err)
}
var m map[string]any
if err := json.Unmarshal(b, &m); err != nil {
t.Fatalf("unmarshal error: %v", err)
}
if m["latitude"] != -36.8485 {
t.Errorf("latitude = %v", m["latitude"])
}
if m["timezone_id"] != "Pacific/Auckland" {
t.Errorf("timezone_id = %v", m["timezone_id"])
}
}
func TestClusterMarshalJSON(t *testing.T) {
desc := "cluster desc"
patternID := "pat_test12345"
c := Cluster{
ID: "cl_test12345",
DatasetID: "ds_abc1234567",
LocationID: "loc_test12345",
Name: "Test Cluster",
Description: &desc,
CreatedAt: time.Date(2025, 3, 1, 0, 0, 0, 0, time.UTC),
LastModified: time.Date(2025, 3, 1, 0, 0, 0, 0, time.UTC),
Active: true,
CyclicRecordingPatternID: &patternID,
SampleRate: 48000,
}
b, err := json.Marshal(c)
if err != nil {
t.Fatalf("MarshalJSON error: %v", err)
}
var m map[string]any
if err := json.Unmarshal(b, &m); err != nil {
t.Fatalf("unmarshal error: %v", err)
}
if m["sample_rate"] != float64(48000) {
t.Errorf("sample_rate = %v", m["sample_rate"])
}
if m["cyclic_recording_pattern_id"] != "pat_test12345" {
t.Errorf("cyclic_recording_pattern_id = %v", m["cyclic_recording_pattern_id"])
}
}
func TestClusterMarshalJSON_NilFields(t *testing.T) {
c := Cluster{
ID: "cl_nil0000000",
DatasetID: "ds_abc1234567",
LocationID: "loc_test12345",
Name: "No Desc",
Description: nil,
CreatedAt: time.Date(2025, 1, 1, 0, 0, 0, 0, time.UTC),
LastModified: time.Date(2025, 1, 1, 0, 0, 0, 0, time.UTC),
Active: true,
CyclicRecordingPatternID: nil,
SampleRate: 48000,
}
b, err := json.Marshal(c)
if err != nil {
t.Fatalf("MarshalJSON error: %v", err)
}
var m map[string]any
if err := json.Unmarshal(b, &m); err != nil {
t.Fatalf("unmarshal error: %v", err)
}
if m["description"] != nil {
t.Errorf("expected nil description, got %v", m["description"])
}
if m["cyclic_recording_pattern_id"] != nil {
t.Errorf("expected nil pattern_id, got %v", m["cyclic_recording_pattern_id"])
}
}
func TestCyclicRecordingPatternMarshalJSON(t *testing.T) {
p := CyclicRecordingPattern{
ID: "pat_test12345",
RecordS: 300,
SleepS: 600,
CreatedAt: time.Date(2025, 4, 1, 0, 0, 0, 0, time.UTC),
LastModified: time.Date(2025, 4, 1, 0, 0, 0, 0, time.UTC),
Active: true,
}
b, err := json.Marshal(p)
if err != nil {
t.Fatalf("MarshalJSON error: %v", err)
}
var m map[string]any
if err := json.Unmarshal(b, &m); err != nil {
t.Fatalf("unmarshal error: %v", err)
}
if m["record_s"] != float64(300) {
t.Errorf("record_s = %v", m["record_s"])
}
if m["sleep_s"] != float64(600) {
t.Errorf("sleep_s = %v", m["sleep_s"])
}
}
func TestDatasetTypeConstants(t *testing.T) {
tests := []struct {
dt DatasetType
want string
}{
{DatasetTypeStructured, "structured"},
{DatasetTypeUnstructured, "unstructured"},
{DatasetTypeTest, "test"},
{DatasetTypeTrain, "train"},
}
for _, tt := range tests {
if string(tt.dt) != tt.want {
t.Errorf("DatasetType constant = %q, want %q", tt.dt, tt.want)
}
}
}