diff --git a/models/entry.go b/models/entry.go index e14ae06..ad4db9d 100644 --- a/models/entry.go +++ b/models/entry.go @@ -178,3 +178,7 @@ func (e Entry) MarshalJSON() ([]byte, error) { } return json.Marshal(out) } + +func (e *Entry) UnmarshalJSON([]byte) error { + return nil +} diff --git a/models/entry_test.go b/models/entry_test.go index 38d9e5d..5c78568 100644 --- a/models/entry_test.go +++ b/models/entry_test.go @@ -15,6 +15,7 @@ import ( var _ encoding.TextMarshaler = Entry{} var _ encoding.TextUnmarshaler = new(Entry) var _ json.Marshaler = Entry{} +var _ json.Unmarshaler = new(Entry) func TestEntryMarshal(t *testing.T) { when := time.Now() @@ -230,3 +231,84 @@ func getEntryJsonMarshalTestRunner(title string, date time.Time, fields []Meta, } } } + +func TestEntryJsonUnmarshal(t *testing.T) { + when := time.Now() + whens := when.Format(time.RFC3339) + simple := []Meta{} + tests := []struct { + name string + in string + title string + date time.Time + fields []Meta + err error + }{ + {"simple", `{"title":"A Title","date":"` + whens + `"}`, "A Title", when, simple, nil}, + {"missing-title", `{"date":"` + whens + `"}`, "", when, simple, ErrorMissingTitle}, + {"missing-date", `{"title":"A Title"}`, "", when, simple, ErrorMissingDate}, + {"empty-title", `{"title":"","date":"` + whens + `"}`, "", when, simple, ErrorMissingTitle}, + {"empty-date", `{"title":"A Title","date":""}`, "", when, simple, ErrorMissingDate}, + {"bad-date", `{"title":"A Title","date":"bad"}`, "", when, simple, ErrorParsing}, + { + "single-field", + `{"title":"A Title","date":"` + whens + `","hello":"Hi"}`, + "A Title", + when, + []Meta{{"hello", "Hi"}}, + nil, + }, + { + "many-fields", + `{"title":"A Title","date":"` + whens + `","hello":"Hi","bye":42,"b":true}`, + "A Title", + when, + []Meta{{"hello", "Hi"}, {"bye", 42}, {"b", true}}, + nil, + }, + { + "date-field", + `{"title":"A Title","date":"` + whens + `","posted":"` + when.Add(-time.Hour).Format(time.RFC3339) + `"}`, + "A Title", + when, + []Meta{{"posted", when.Add(-time.Hour)}}, + nil, + }, + } + + for _, tt := range tests { + t.Run(tt.name, getEntryJsonUnmarshalTestRunner(tt.in, tt.title, tt.date, tt.fields, tt.err)) + } +} + +func getEntryJsonUnmarshalTestRunner(in, title string, date time.Time, fields []Meta, err error) func(t *testing.T) { + return func(t *testing.T) { + e := new(Entry) + er := json.Unmarshal([]byte(in), e) + if err != nil { + assert.ErrorIs(t, er, err) + return + } + + assert.Equal(t, title, e.Title) + assert.WithinRange(t, e.Date, date.Add(-time.Second), date.Add(time.Second)) + for _, f := range fields { + got := false + for _, m := range e.Fields { + var mVal any = m.Value + var fVal any = f.Value + if mJ, ok := m.Value.(json.RawMessage); ok { + mVal = string(mJ) + } + if fJ, ok := f.Value.(json.RawMessage); ok { + fVal = string(fJ) + } + if m.Key == f.Key && mVal == fVal { + got = true + break + } + } + assert.Truef(t, got, "Couldn't find field %+v", f) + } + } +}