package wire import ( "encoding/json" "net/http" "net/http/httptest" "testing" "time" ) // Gap (e): Time.UnmarshalJSON round-trips both +00:00 and Z. The happy // path already lives in TestTimeUnmarshalJSONAcceptsOffsetAndZ; this // file covers null, invalid JSON, and a non-nil empty slice. func TestTimeUnmarshalJSONNullAndInvalid(t *testing.T) { var tm Time if err := json.Unmarshal([]byte("null"), &tm); err != nil { t.Fatal(err) } if !tm.IsZero() { t.Fatalf("null must decode to zero Time, got %v", tm.Time) } if err := json.Unmarshal([]byte(`"not-a-time"`), &tm); err == nil { t.Fatal("invalid timestamp must fail") } if err := json.Unmarshal([]byte(`42`), &tm); err == nil { t.Fatal("non-string must fail") } var nilT *Time if err := nilT.UnmarshalJSON([]byte(`"2024-01-02T03:04:05Z"`)); err != nil { t.Fatalf("nil receiver: %v", err) } } func TestTimeUnmarshalJSONOffsetAndZRoundTrip(t *testing.T) { want := time.Date(2024, 1, 2, 3, 4, 5, 0, time.UTC) for _, raw := range []string{`"2024-01-02T03:04:05+00:00"`, `"2024-01-02T03:04:05Z"`} { var tm Time if err := json.Unmarshal([]byte(raw), &tm); err != nil { t.Fatalf("%s: %v", raw, err) } if !tm.Equal(want) { t.Fatalf("%s = %v", raw, tm.Time) } b, err := json.Marshal(tm) if err != nil { t.Fatal(err) } if string(b) != `"2024-01-02T03:04:05+00:00"` { t.Fatalf("marshal %s -> %s", raw, b) } } } func TestWriteJSONEncodeErrorWritesOpaque500(t *testing.T) { rec := httptest.NewRecorder() WriteJSON(rec, http.StatusOK, make(chan int)) if rec.Code != http.StatusInternalServerError { t.Fatalf("status = %d", rec.Code) } if rec.Body.String() != `{"error":true,"message":"Internal server error"}` { t.Fatalf("body = %q", rec.Body.String()) } } func TestSliceNonNilUnchanged(t *testing.T) { in := []int{1, 2} got := Slice(in) if len(got) != 2 || got[0] != 1 || got[1] != 2 { t.Fatalf("got %v", got) } }