Fork channel

Create a new channel as a copy of main.

Rename channel

Rename main to:

Delete channel

Delete main? This cannot be undone.

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)
		}
	}
}