From a95202247ac22a85874ce7d9fc167dc2568dd3fb Mon Sep 17 00:00:00 2001 From: Erik Winter Date: Fri, 20 Sep 2024 07:09:30 +0200 Subject: [PATCH] event item --- .gitignore | 1 + cal/main.go | 2 +- go.mod | 1 + go.sum | 2 + item/event.go | 63 ++++++++++++++++++ item/event_test.go | 126 +++++++++++++++++++++++++++++++++++ {sync/item => item}/item.go | 0 sync/client/client.go | 2 +- sync/service/handler.go | 2 +- sync/service/handler_test.go | 2 +- sync/service/memory.go | 2 +- sync/service/memory_test.go | 12 ++-- sync/service/postgres.go | 2 +- sync/service/storage.go | 2 +- 14 files changed, 206 insertions(+), 13 deletions(-) create mode 100644 item/event.go create mode 100644 item/event_test.go rename {sync/item => item}/item.go (100%) diff --git a/.gitignore b/.gitignore index e7e12b7..d87f22c 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ test.db* +plannersync diff --git a/cal/main.go b/cal/main.go index 8b59277..5f8ebdd 100644 --- a/cal/main.go +++ b/cal/main.go @@ -5,8 +5,8 @@ import ( "os" "time" + "go-mod.ewintr.nl/planner/item" "go-mod.ewintr.nl/planner/sync/client" - "go-mod.ewintr.nl/planner/sync/item" ) func main() { diff --git a/go.mod b/go.mod index 59e2029..1f60790 100644 --- a/go.mod +++ b/go.mod @@ -4,6 +4,7 @@ go 1.21.5 require ( github.com/dustin/go-humanize v1.0.1 // indirect + github.com/google/go-cmp v0.6.0 // indirect github.com/google/uuid v1.6.0 // indirect github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect github.com/lib/pq v1.10.9 // indirect diff --git a/go.sum b/go.sum index b99f05c..dd81e53 100644 --- a/go.sum +++ b/go.sum @@ -1,5 +1,7 @@ github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY= github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= +github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= +github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/hashicorp/golang-lru/v2 v2.0.7 h1:a+bsQ5rvGLjzHuww6tVxozPZFVghXaHOwFs4luLUK2k= diff --git a/item/event.go b/item/event.go new file mode 100644 index 0000000..03fd096 --- /dev/null +++ b/item/event.go @@ -0,0 +1,63 @@ +package item + +import ( + "encoding/json" + "fmt" + "time" +) + +type EventBody struct { + Title string `json:"title"` + Start time.Time `json:"start"` + End time.Time `json:"end"` +} + +func (e EventBody) MarshalJSON() ([]byte, error) { + type Alias EventBody + return json.Marshal(&struct { + Start string `json:"start"` + End string `json:"end"` + *Alias + }{ + Start: e.Start.UTC().Format(time.RFC3339), + End: e.End.UTC().Format(time.RFC3339), + Alias: (*Alias)(&e), + }) +} + +type Event struct { + ID string `json:"id"` + EventBody +} + +func NewEvent(i Item) (Event, error) { + if i.Kind != KindEvent { + return Event{}, fmt.Errorf("item is not an event") + } + + var e Event + if err := json.Unmarshal([]byte(i.Body), &e); err != nil { + return Event{}, fmt.Errorf("could not unmarshal item body: %v", err) + } + + e.ID = i.ID + + return e, nil +} + +func (e Event) Item() (Item, error) { + body, err := json.Marshal(EventBody{ + Title: e.Title, + Start: e.Start, + End: e.End, + }) + if err != nil { + return Item{}, fmt.Errorf("could not marshal event to json") + } + + return Item{ + ID: e.ID, + Kind: KindEvent, + Body: string(body), + }, nil +} diff --git a/item/event_test.go b/item/event_test.go new file mode 100644 index 0000000..28489d0 --- /dev/null +++ b/item/event_test.go @@ -0,0 +1,126 @@ +package item_test + +import ( + "testing" + "time" + + "github.com/google/go-cmp/cmp" + "go-mod.ewintr.nl/planner/item" +) + +func TestNewEvent(t *testing.T) { + t.Parallel() + + for _, tc := range []struct { + name string + it item.Item + expEvent item.Event + expErr bool + }{ + { + name: "wrong kind", + it: item.Item{ + ID: "a", + Kind: item.KindTask, + Body: `{ + "title":"title", + "start":"2024-09-20T08:00:00Z", + "end":"2024-09-20T10:00:00Z" +}`, + }, + expErr: true, + }, + { + name: "invalid json", + it: item.Item{ + ID: "a", + Kind: item.KindEvent, + Body: `{"id":"a"`, + }, + expErr: true, + }, + { + name: "valid", + it: item.Item{ + ID: "a", + Kind: item.KindEvent, + Body: `{ + "title":"title", + "start":"2024-09-20T08:00:00Z", + "end":"2024-09-20T10:00:00Z" +}`, + }, + expEvent: item.Event{ + ID: "a", + EventBody: item.EventBody{ + Title: "title", + Start: time.Date(2024, 9, 20, 8, 0, 0, 0, time.UTC), + End: time.Date(2024, 9, 20, 10, 0, 0, 0, time.UTC), + }, + }, + }, + } { + t.Run(tc.name, func(t *testing.T) { + actEvent, actErr := item.NewEvent(tc.it) + if tc.expErr != (actErr != nil) { + t.Errorf("exp nil, got %v", actErr) + } + if tc.expErr { + return + } + if diff := cmp.Diff(tc.expEvent, actEvent); diff != "" { + t.Errorf("(exp +, got -)\n%s", diff) + } + }) + } +} + +func TestEventItem(t *testing.T) { + t.Parallel() + + for _, tc := range []struct { + name string + event item.Event + expItem item.Item + expErr bool + }{ + { + name: "empty", + expItem: item.Item{ + Kind: item.KindEvent, + Updated: time.Time{}, + Body: `{"start":"0001-01-01T00:00:00Z","end":"0001-01-01T00:00:00Z","title":""}`, + }, + }, + { + name: "normal", + event: item.Event{ + ID: "a", + EventBody: item.EventBody{ + Title: "title", + Start: time.Date(2024, 9, 23, 8, 0, 0, 0, time.UTC), + End: time.Date(2024, 9, 23, 10, 0, 0, 0, time.UTC), + }, + }, + expItem: item.Item{ + ID: "a", + Kind: item.KindEvent, + Updated: time.Time{}, + Body: `{"start":"2024-09-23T08:00:00Z","end":"2024-09-23T10:00:00Z","title":"title"}`, + }, + }, + } { + t.Run(tc.name, func(t *testing.T) { + actItem, actErr := tc.event.Item() + if tc.expErr != (actErr != nil) { + t.Errorf("exp nil, got %v", actErr) + } + if tc.expErr { + return + } + if diff := cmp.Diff(tc.expItem, actItem); diff != "" { + t.Errorf("(exp+, got -)\n%s", diff) + } + }) + } +} diff --git a/sync/item/item.go b/item/item.go similarity index 100% rename from sync/item/item.go rename to item/item.go diff --git a/sync/client/client.go b/sync/client/client.go index b060fdc..9b3a4bc 100644 --- a/sync/client/client.go +++ b/sync/client/client.go @@ -10,7 +10,7 @@ import ( "strings" "time" - "go-mod.ewintr.nl/planner/sync/item" + "go-mod.ewintr.nl/planner/item" ) type Client struct { diff --git a/sync/service/handler.go b/sync/service/handler.go index f06ca88..e5872dc 100644 --- a/sync/service/handler.go +++ b/sync/service/handler.go @@ -11,7 +11,7 @@ import ( "strings" "time" - "go-mod.ewintr.nl/planner/sync/item" + "go-mod.ewintr.nl/planner/item" ) type Server struct { diff --git a/sync/service/handler_test.go b/sync/service/handler_test.go index c64bac8..63c6427 100644 --- a/sync/service/handler_test.go +++ b/sync/service/handler_test.go @@ -15,7 +15,7 @@ import ( "testing" "time" - "go-mod.ewintr.nl/planner/sync/item" + "go-mod.ewintr.nl/planner/item" ) func TestServerServeHTTP(t *testing.T) { diff --git a/sync/service/memory.go b/sync/service/memory.go index 743b20b..c421ee5 100644 --- a/sync/service/memory.go +++ b/sync/service/memory.go @@ -4,7 +4,7 @@ import ( "slices" "time" - "go-mod.ewintr.nl/planner/sync/item" + "go-mod.ewintr.nl/planner/item" ) type Memory struct { diff --git a/sync/service/memory_test.go b/sync/service/memory_test.go index db2496a..d2f38d3 100644 --- a/sync/service/memory_test.go +++ b/sync/service/memory_test.go @@ -5,7 +5,7 @@ import ( "testing" "time" - "go-mod.ewintr.nl/planner/sync/item" + "go-mod.ewintr.nl/planner/item" ) func TestMemoryItem(t *testing.T) { @@ -87,14 +87,14 @@ func TestMemoryItem(t *testing.T) { }) expItems := []item.Item{t1, t2} sort.Slice(expItems, func(i, j int) bool { - return expItems[i].ID < actItems[j].ID + return expItems[i].ID < expItems[j].ID }) - if actItems[0].ID != t1.ID { - t.Errorf("exp %v, got %v", actItems[0].ID, t1.ID) + if actItems[0].ID != expItems[0].ID { + t.Errorf("exp %v, got %v", actItems[0].ID, expItems[0].ID) } - if actItems[1].ID != t2.ID { - t.Errorf("exp %v, got %v", actItems[1].ID, t2.ID) + if actItems[1].ID != expItems[1].ID { + t.Errorf("exp %v, got %v", actItems[1].ID, expItems[1].ID) } t.Log("select kind") diff --git a/sync/service/postgres.go b/sync/service/postgres.go index 6c27df7..e3196ef 100644 --- a/sync/service/postgres.go +++ b/sync/service/postgres.go @@ -8,7 +8,7 @@ import ( "time" _ "github.com/lib/pq" - "go-mod.ewintr.nl/planner/sync/item" + "go-mod.ewintr.nl/planner/item" ) const ( diff --git a/sync/service/storage.go b/sync/service/storage.go index 5672052..ba14634 100644 --- a/sync/service/storage.go +++ b/sync/service/storage.go @@ -4,7 +4,7 @@ import ( "errors" "time" - "go-mod.ewintr.nl/planner/sync/item" + "go-mod.ewintr.nl/planner/item" ) var (