From a296c257adfe639bc0d7c56b96b022e653af0316 Mon Sep 17 00:00:00 2001 From: Erik Winter Date: Fri, 3 Sep 2021 09:19:36 +0200 Subject: [PATCH] send process --- internal/process/send.go | 49 ++++++++++++++++++++++++++ internal/process/send_test.go | 61 +++++++++++++++++++++++++++++++++ internal/process/update_test.go | 2 +- internal/storage/local.go | 1 + internal/storage/memory.go | 8 +++++ internal/storage/memory_test.go | 12 +++++++ internal/storage/sqlite.go | 10 ++++++ internal/task/localtask.go | 5 +-- 8 files changed, 145 insertions(+), 3 deletions(-) create mode 100644 internal/process/send.go create mode 100644 internal/process/send_test.go diff --git a/internal/process/send.go b/internal/process/send.go new file mode 100644 index 0000000..356f298 --- /dev/null +++ b/internal/process/send.go @@ -0,0 +1,49 @@ +package process + +import ( + "errors" + "fmt" + + "git.ewintr.nl/gte/internal/storage" + "git.ewintr.nl/gte/internal/task" +) + +var ( + ErrSendTasks = errors.New("could not send tasks") +) + +// Send sends local tasks that need to be dispatched +type Send struct { + local storage.LocalRepository + disp *storage.Dispatcher +} + +func NewSend(local storage.LocalRepository, disp *storage.Dispatcher) *Send { + return &Send{ + local: local, + disp: disp, + } +} + +func (s *Send) Process() error { + tasks, err := s.local.FindAll() + if err != nil { + return fmt.Errorf("%w: %v", ErrSendTasks, err) + } + + for _, t := range tasks { + if t.LocalStatus != task.STATUS_UPDATED { + continue + } + + t.ApplyUpdate() + if err := s.disp.Dispatch(&t.Task); err != nil { + return fmt.Errorf("%w: %v", ErrSendTasks, err) + } + if err := s.local.MarkDispatched(t.LocalId); err != nil { + return fmt.Errorf("%w: %v", ErrSendTasks, err) + } + } + + return nil +} diff --git a/internal/process/send_test.go b/internal/process/send_test.go new file mode 100644 index 0000000..37a5ea0 --- /dev/null +++ b/internal/process/send_test.go @@ -0,0 +1,61 @@ +package process_test + +import ( + "testing" + + "git.ewintr.nl/go-kit/test" + "git.ewintr.nl/gte/internal/process" + "git.ewintr.nl/gte/internal/storage" + "git.ewintr.nl/gte/internal/task" + "git.ewintr.nl/gte/pkg/msend" +) + +func TestSend(t *testing.T) { + task1 := &task.Task{ + Id: "id-1", + Version: 2, + Project: "project1", + Action: "action1", + Due: task.NewDate(2021, 7, 29), + Folder: task.FOLDER_PLANNED, + } + task2 := &task.Task{ + Id: "id-2", + Version: 2, + Project: "project1", + Action: "action2", + Folder: task.FOLDER_UNPLANNED, + } + local := storage.NewMemory() + allTasks := []*task.Task{task1, task2} + + test.OK(t, local.SetTasks(allTasks)) + + t.Run("no updates", func(t *testing.T) { + out := msend.NewMemory() + disp := storage.NewDispatcher(out) + send := process.NewSend(local, disp) + test.OK(t, send.Process()) + test.Assert(t, len(out.Messages) == 0, "amount of messages was not 0") + }) + + t.Run("update", func(t *testing.T) { + lu := &task.LocalUpdate{ + ForVersion: task2.Version, + Fields: []string{task.FIELD_ACTION}, + Action: "updated", + } + lt, err := local.FindById(task2.Id) + test.OK(t, err) + lt.AddUpdate(lu) + test.OK(t, local.SetLocalUpdate(lt)) + + out := msend.NewMemory() + disp := storage.NewDispatcher(out) + send := process.NewSend(local, disp) + test.OK(t, send.Process()) + test.Assert(t, len(out.Messages) == 1, "amount of messages was not 1") + expSubject := "project1 - updated" + test.Equals(t, expSubject, out.Messages[0].Subject) + }) +} diff --git a/internal/process/update_test.go b/internal/process/update_test.go index d41a277..fe7c8c9 100644 --- a/internal/process/update_test.go +++ b/internal/process/update_test.go @@ -64,7 +64,7 @@ func TestUpdate(t *testing.T) { }, } { t.Run(tc.name, func(t *testing.T) { - local.SetTasks(allTasks) + test.OK(t, local.SetTasks(allTasks)) out := msend.NewMemory() disp := storage.NewDispatcher(out) diff --git a/internal/storage/local.go b/internal/storage/local.go index dfd4ac0..bac9ee1 100644 --- a/internal/storage/local.go +++ b/internal/storage/local.go @@ -19,6 +19,7 @@ type LocalRepository interface { FindById(id string) (*task.LocalTask, error) FindByLocalId(id int) (*task.LocalTask, error) SetLocalUpdate(tsk *task.LocalTask) error + MarkDispatched(id int) error } // NextLocalId finds a new local id by incrememting to a variable limit. diff --git a/internal/storage/memory.go b/internal/storage/memory.go index d3e1e5e..84f0d7b 100644 --- a/internal/storage/memory.go +++ b/internal/storage/memory.go @@ -69,7 +69,15 @@ func (m *Memory) FindByLocalId(localId int) (*task.LocalTask, error) { } func (m *Memory) SetLocalUpdate(tsk *task.LocalTask) error { + tsk.LocalStatus = task.STATUS_UPDATED m.tasks[tsk.Id] = tsk return nil } + +func (m *Memory) MarkDispatched(localId int) error { + t, _ := m.FindByLocalId(localId) + m.tasks[t.Id].LocalStatus = task.STATUS_DISPATCHED + + return nil +} diff --git a/internal/storage/memory_test.go b/internal/storage/memory_test.go index 89bd42f..600317c 100644 --- a/internal/storage/memory_test.go +++ b/internal/storage/memory_test.go @@ -114,5 +114,17 @@ func TestMemory(t *testing.T) { actTask, err := mem.FindByLocalId(2) test.OK(t, err) test.Equals(t, expUpdate, actTask.LocalUpdate) + test.Equals(t, task.STATUS_UPDATED, actTask.LocalStatus) + }) + + t.Run("markdispatched", func(t *testing.T) { + mem := storage.NewMemory() + test.OK(t, mem.SetTasks(tasks)) + lt, err := mem.FindById(task2.Id) + test.OK(t, err) + test.OK(t, mem.MarkDispatched(lt.LocalId)) + act, err := mem.FindById(task2.Id) + test.OK(t, err) + test.Equals(t, task.STATUS_DISPATCHED, act.LocalStatus) }) } diff --git a/internal/storage/sqlite.go b/internal/storage/sqlite.go index bc2c1d8..7f9528b 100644 --- a/internal/storage/sqlite.go +++ b/internal/storage/sqlite.go @@ -199,6 +199,16 @@ WHERE local_id = ?`, tsk.LocalUpdate, task.STATUS_UPDATED, tsk.LocalId); err != return nil } +func (s *Sqlite) MarkDispatched(localId int) error { + if _, err := s.db.Exec(` +UPDATE task +SET local_status = ? +WHERE local_id = ?`, task.STATUS_DISPATCHED, localId); err != nil { + return fmt.Errorf("%w: %v", ErrSqliteFailure, err) + } + return nil +} + func (s *Sqlite) migrate(wanted []sqliteMigration) error { // admin table if _, err := s.db.Exec(` diff --git a/internal/task/localtask.go b/internal/task/localtask.go index c2ae808..36fac69 100644 --- a/internal/task/localtask.go +++ b/internal/task/localtask.go @@ -8,8 +8,9 @@ import ( ) const ( - STATUS_FETCHED = "fetched" - STATUS_UPDATED = "updated" + STATUS_FETCHED = "fetched" + STATUS_UPDATED = "updated" + STATUS_DISPATCHED = "dispatched" ) type LocalTask struct {