package model import ( "testing" "time" "gopkg.in/yaml.v3" ) func TestTime_UnmarshalPythonISOFormat(t *testing.T) { // Exact reproduction of the reported bug: a subscriptions.yaml written // by the original Python implementation (datetime.now().isoformat(), // no timezone) failed to parse under Go's strict RFC3339 decoding. data := []byte(`last_refresh: 2026-03-19T18:21:47.740090 `) var out struct { LastRefresh *Time `yaml:"last_refresh"` } if err := yaml.Unmarshal(data, &out); err != nil { t.Fatalf("Unmarshal() error = %v", err) } if out.LastRefresh == nil { t.Fatal("expected non-nil LastRefresh") } want := time.Date(2026, 3, 19, 18, 21, 47, 740090000, time.UTC) if !out.LastRefresh.Time.Equal(want) { t.Fatalf("got %v, want %v", out.LastRefresh.Time, want) } } func TestTime_UnmarshalPythonISOFormatNoMicroseconds(t *testing.T) { data := []byte(`last_refresh: 2026-03-19T18:21:47 `) var out struct { LastRefresh *Time `yaml:"last_refresh"` } if err := yaml.Unmarshal(data, &out); err != nil { t.Fatalf("Unmarshal() error = %v", err) } want := time.Date(2026, 3, 19, 18, 21, 47, 0, time.UTC) if !out.LastRefresh.Time.Equal(want) { t.Fatalf("got %v, want %v", out.LastRefresh.Time, want) } } func TestTime_UnmarshalRFC3339(t *testing.T) { // What this Go implementation itself writes. data := []byte(`last_refresh: 2026-03-19T18:21:47.74009+08:00 `) var out struct { LastRefresh *Time `yaml:"last_refresh"` } if err := yaml.Unmarshal(data, &out); err != nil { t.Fatalf("Unmarshal() error = %v", err) } if out.LastRefresh.Time.IsZero() { t.Fatal("expected non-zero time") } } func TestTime_RoundTrip(t *testing.T) { original := Time{Time: time.Date(2026, 3, 19, 18, 21, 47, 740090000, time.UTC)} out, err := yaml.Marshal(map[string]interface{}{"last_refresh": original}) if err != nil { t.Fatalf("Marshal() error = %v", err) } var roundTripped struct { LastRefresh Time `yaml:"last_refresh"` } if err := yaml.Unmarshal(out, &roundTripped); err != nil { t.Fatalf("Unmarshal() error = %v", err) } if !roundTripped.LastRefresh.Time.Equal(original.Time) { t.Fatalf("round trip mismatch: got %v, want %v", roundTripped.LastRefresh.Time, original.Time) } } func TestTime_UnmarshalEmpty(t *testing.T) { data := []byte(`last_refresh: "" `) var out struct { LastRefresh Time `yaml:"last_refresh"` } if err := yaml.Unmarshal(data, &out); err != nil { t.Fatalf("Unmarshal() error = %v", err) } if !out.LastRefresh.Time.IsZero() { t.Fatalf("expected zero time, got %v", out.LastRefresh.Time) } }