todo service tests

This commit is contained in:
Michael Thomson 2025-02-07 22:05:05 -05:00
parent a71e09367c
commit 6175abee25
No known key found for this signature in database
GPG Key ID: 8EFECCD347C72F7D
5 changed files with 130 additions and 17 deletions

View File

@ -35,5 +35,5 @@ func main() {
if err != nil {
log.Fatal(err)
}
fmt.Printf("ID of created todo: %d", newTodo.Id)
fmt.Printf("ID of created todo: %d\n", newTodo.Id)
}

View File

@ -5,20 +5,20 @@ import (
)
type InMemoryTodoRepository struct {
db map[int64]repository.TodoRow
Db map[int64]repository.TodoRow
id int64
}
func NewInMemoryTodoRepository() InMemoryTodoRepository {
return InMemoryTodoRepository{
db: make(map[int64]repository.TodoRow),
Db: make(map[int64]repository.TodoRow),
id: 1,
}
}
func (r *InMemoryTodoRepository) GetById(id int64) (repository.TodoRow, error) {
todo, found := r.db[id]
todo, found := r.Db[id]
if !found {
return todo, repository.ErrNotFound
@ -29,32 +29,32 @@ func (r *InMemoryTodoRepository) GetById(id int64) (repository.TodoRow, error) {
func (r *InMemoryTodoRepository) Create(todo repository.TodoRow) (repository.TodoRow, error) {
todo.Id = r.id
r.db[r.id] = todo
r.Db[r.id] = todo
r.id++
return todo, nil
}
func (r *InMemoryTodoRepository) Update(todo repository.TodoRow) error {
_, found := r.db[todo.Id]
_, found := r.Db[todo.Id]
if !found {
return repository.ErrNotFound
}
r.db[todo.Id] = todo
r.Db[todo.Id] = todo
return nil
}
func (r *InMemoryTodoRepository) Delete(id int64) error {
_, found := r.db[id]
_, found := r.Db[id]
if !found {
return repository.ErrNotFound
}
delete(r.db, id)
delete(r.Db, id)
return nil
}

View File

@ -14,8 +14,8 @@ type TodoRow struct {
Done bool
}
func NewTodoDbModel(name string, done bool) *TodoRow {
return &TodoRow{Name: name, Done: done}
func NewTodoRow(name string, done bool) TodoRow {
return TodoRow{Name: name, Done: done}
}
type TodoRepository interface {

View File

@ -1,9 +1,17 @@
package service
import "gitea.michaelthomson.dev/mthomson/habits/internal/todo/repository"
import (
"errors"
"gitea.michaelthomson.dev/mthomson/habits/internal/todo/repository"
)
var (
ErrNotFound error = errors.New("Todo cannot be found")
)
type Todo struct {
Id int64
Id int64
Name string
Done bool
}
@ -20,6 +28,10 @@ func TodoRowFromTodo(todo Todo) repository.TodoRow {
return repository.TodoRow{Id: todo.Id, Name: todo.Name, Done: todo.Done}
}
func (t Todo) Equal(todo Todo) bool {
return t.Id == todo.Id && t.Name == todo.Name && t.Done == todo.Done
}
type TodoGetter interface {
GetTodo(id int64) (Todo, error)
}
@ -48,6 +60,10 @@ func (s *TodoService) GetTodo(id int64) (Todo, error) {
todo, err := s.repo.GetById(id)
if err != nil {
if err == repository.ErrNotFound {
return Todo{}, ErrNotFound
}
return Todo{}, err
}
@ -67,7 +83,11 @@ func (s *TodoService) CreateTodo(todo Todo) (Todo, error) {
}
func (s *TodoService) DeleteTodo(id int64) error {
err := s.repo.Delete(id);
err := s.repo.Delete(id)
if err == repository.ErrNotFound {
return ErrNotFound
}
return err
}
@ -77,5 +97,9 @@ func (s *TodoService) UpdateTodo(todo Todo) error {
err := s.repo.Update(todoRow)
if err == repository.ErrNotFound {
return ErrNotFound
}
return err
}

View File

@ -3,6 +3,7 @@ package service_test
import (
"testing"
"gitea.michaelthomson.dev/mthomson/habits/internal/todo/repository"
"gitea.michaelthomson.dev/mthomson/habits/internal/todo/repository/inmemory"
"gitea.michaelthomson.dev/mthomson/habits/internal/todo/service"
)
@ -17,8 +18,96 @@ func TestCreateTodo(t *testing.T) {
_, err := todoService.CreateTodo(todo)
if err != nil {
t.Error(err)
}
AssertNoError(t, err)
})
}
func TestGetTodo(t *testing.T) {
todoRepository := inmemory.NewInMemoryTodoRepository()
todoRepository.Db[1] = repository.TodoRow{Id: 1, Name: "clean dishes", Done: false}
todoService := service.NewTodoService(&todoRepository)
t.Run("Get exisiting todo", func(t *testing.T) {
_, err := todoService.GetTodo(1)
AssertNoError(t, err)
})
t.Run("Get non-existant todo", func(t *testing.T) {
_, err := todoService.GetTodo(2)
AssertErrors(t, err, service.ErrNotFound)
})
}
func TestDeleteTodo(t *testing.T) {
todoRepository := inmemory.NewInMemoryTodoRepository()
todoRepository.Db[1] = repository.TodoRow{Id: 1, Name: "clean dishes", Done: false}
todoService := service.NewTodoService(&todoRepository)
t.Run("Delete exisiting todo", func(t *testing.T) {
err := todoService.DeleteTodo(1)
AssertNoError(t, err)
})
t.Run("Delete non-existant todo", func(t *testing.T) {
err := todoService.DeleteTodo(1)
AssertErrors(t, err, service.ErrNotFound)
})
}
func TestUpdateTodo(t *testing.T) {
todoRepository := inmemory.NewInMemoryTodoRepository()
todoRepository.Db[1] = repository.TodoRow{Id: 1, Name: "clean dishes", Done: false}
todoService := service.NewTodoService(&todoRepository)
t.Run("Update exisiting todo", func(t *testing.T) {
todo := service.Todo{1, "clean dishes", true}
err := todoService.UpdateTodo(todo)
AssertNoError(t, err)
newTodo, err := todoService.GetTodo(1)
AssertNoError(t, err)
AssertTodos(t, newTodo, todo)
})
t.Run("Update non-existant todo", func(t *testing.T) {
todo := service.Todo{2, "clean dishes", true}
err := todoService.UpdateTodo(todo)
AssertErrors(t, err, service.ErrNotFound)
})
}
func AssertErrors(t testing.TB, got, want error) {
t.Helper()
if got != want {
t.Errorf("got error: %v, want error: %v", want, got)
}
}
func AssertNoError(t testing.TB, err error) {
t.Helper()
if err != nil {
t.Errorf("expected no error, got %v", err)
}
}
func AssertTodos(t testing.TB, got, want service.Todo) {
if !got.Equal(want) {
t.Errorf("got %+v want %+v", got, want)
}
}