done command

This commit is contained in:
Erik Winter 2021-07-10 12:30:38 +02:00
parent addf95a2e7
commit 56c4b22a43
8 changed files with 188 additions and 0 deletions

View File

@ -29,6 +29,8 @@ func Parse(args []string, conf *configuration.Configuration) (Command, error) {
return NewTomorrow(conf)
case "new":
return NewNew(conf, cmdArgs)
case "done":
return NewDone(conf, cmdArgs)
default:
return NewEmpty()
}

39
cmd/cli/command/done.go Normal file
View File

@ -0,0 +1,39 @@
package command
import (
"git.ewintr.nl/gte/cmd/cli/format"
"git.ewintr.nl/gte/internal/configuration"
"git.ewintr.nl/gte/internal/process"
"git.ewintr.nl/gte/internal/storage"
"git.ewintr.nl/gte/pkg/msend"
)
// Done updates a task to be marked done
type Done struct {
doner *process.Update
}
func NewDone(conf *configuration.Configuration, cmdArgs []string) (*Done, error) {
local, err := storage.NewSqlite(conf.Sqlite())
if err != nil {
return &Done{}, err
}
disp := storage.NewDispatcher(msend.NewSSLSMTP(conf.SMTP()))
fields := process.UpdateFields{"done": "true"}
updater := process.NewUpdate(local, disp, cmdArgs[0], fields)
return &Done{
doner: updater,
}, nil
}
func (d *Done) Do() string {
err := d.doner.Process()
if err != nil {
return format.FormatError(err)
}
return "message sent\n"
}

View File

@ -0,0 +1,53 @@
package process
import (
"errors"
"fmt"
"git.ewintr.nl/gte/internal/storage"
)
var (
ErrUpdateTask = errors.New("could not update task")
)
// Update dispatches an updated version of a task
type Update struct {
local storage.LocalRepository
disp *storage.Dispatcher
taskId string
updates UpdateFields
}
type UpdateFields map[string]string
func NewUpdate(local storage.LocalRepository, disp *storage.Dispatcher, taskId string, updates UpdateFields) *Update {
return &Update{
local: local,
disp: disp,
taskId: taskId,
updates: updates,
}
}
func (u *Update) Process() error {
task, err := u.local.FindById(u.taskId)
if err != nil {
return fmt.Errorf("%w: %v", ErrUpdateTask, err)
}
for k, v := range u.updates {
switch k {
case "done":
if v == "true" {
task.Done = true
}
}
}
if err := u.disp.Dispatch(task); err != nil {
return fmt.Errorf("%w: %v", ErrUpdateTask, err)
}
return nil
}

View File

@ -0,0 +1,43 @@
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 TestUpdate(t *testing.T) {
task1 := &task.Task{
Id: "id-1",
Project: "project1",
Action: "action1",
Folder: task.FOLDER_PLANNED,
}
local := storage.NewMemory()
out := msend.NewMemory()
disp := storage.NewDispatcher(out)
allTasks := []*task.Task{task1}
t.Run("done", func(t *testing.T) {
local.SetTasks(allTasks)
updates := process.UpdateFields{
"done": "true",
}
update := process.NewUpdate(local, disp, task1.Id, updates)
test.OK(t, update.Process())
expTask := task1
expTask.Done = true
expMsg := &msend.Message{
Subject: expTask.FormatSubject(),
Body: expTask.FormatBody(),
}
test.Assert(t, len(out.Messages) == 1, "amount of messages was not one")
test.Equals(t, expMsg, out.Messages[0])
})
}

View File

@ -1,14 +1,20 @@
package storage
import (
"errors"
"time"
"git.ewintr.nl/gte/internal/task"
)
var (
ErrTaskNotFound = errors.New("task was not found")
)
type LocalRepository interface {
LatestSync() (time.Time, error)
SetTasks(tasks []*task.Task) error
FindAllInFolder(folder string) ([]*task.Task, error)
FindAllInProject(project string) ([]*task.Task, error)
FindById(id string) (*task.Task, error)
}

View File

@ -56,3 +56,14 @@ func (m *Memory) FindAllInProject(project string) ([]*task.Task, error) {
return tasks, nil
}
func (m *Memory) FindById(id string) (*task.Task, error) {
for _, t := range m.tasks {
if t.Id == id {
return t, nil
}
}
return &task.Task{}, ErrTaskNotFound
}

View File

@ -14,6 +14,7 @@ func TestMemory(t *testing.T) {
folder1, folder2 := "folder1", "folder2"
project1, project2 := "project1", "project2"
task1 := &task.Task{
Id: "id-1",
Folder: folder1,
Project: project1,
Action: "action1",
@ -22,6 +23,7 @@ func TestMemory(t *testing.T) {
},
}
task2 := &task.Task{
Id: "id-2",
Folder: folder1,
Project: project2,
Action: "action2",
@ -30,6 +32,7 @@ func TestMemory(t *testing.T) {
},
}
task3 := &task.Task{
Id: "id-3",
Folder: folder2,
Project: project1,
Action: "action3",
@ -75,4 +78,12 @@ func TestMemory(t *testing.T) {
}
test.Equals(t, exp, act)
})
t.Run("findbyid", func(t *testing.T) {
mem := storage.NewMemory()
test.OK(t, mem.SetTasks(tasks))
act, err := mem.FindById("id-2")
test.OK(t, err)
test.Equals(t, task2, act)
})
}

View File

@ -122,6 +122,29 @@ WHERE project = ?`, project)
return tasksFromRows(rows)
}
func (s *Sqlite) FindById(id string) (*task.Task, error) {
var folder, action, project, due, recur string
var version int
row := s.db.QueryRow(`
SELECT version, folder, action, project, due, recur
FROM task
WHERE id = ?
LIMIT 1`, id)
if err := row.Scan(&version, &folder, &action, &project, &due, &recur); err != nil {
return &task.Task{}, fmt.Errorf("%w: %v", ErrSqliteFailure, err)
}
return &task.Task{
Id: id,
Version: version,
Folder: folder,
Action: action,
Project: project,
Due: task.NewDateFromString(due),
Recur: task.NewRecurrer(recur),
}, nil
}
func tasksFromRows(rows *sql.Rows) ([]*task.Task, error) {
tasks := []*task.Task{}