123 lines
2.9 KiB
Go
123 lines
2.9 KiB
Go
package handler
|
|
|
|
import (
|
|
"bytes"
|
|
"context"
|
|
"encoding/json"
|
|
"log/slog"
|
|
|
|
"errors"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"testing"
|
|
|
|
"gitea.michaelthomson.dev/mthomson/habits/internal/todo/service"
|
|
)
|
|
|
|
type MockTodoUpdater struct {
|
|
UpdateTodoFunc func(ctx context.Context, todo service.Todo) error
|
|
}
|
|
|
|
func (tg *MockTodoUpdater) UpdateTodo(ctx context.Context, todo service.Todo) error {
|
|
return tg.UpdateTodoFunc(ctx, todo)
|
|
}
|
|
|
|
func TestUpdateTodo(t *testing.T) {
|
|
logger := slog.Default()
|
|
t.Run("update todo", func(t *testing.T) {
|
|
updateTodoRequest := UpdateTodoRequest{Name: "clean dishes", Done: false}
|
|
|
|
service := MockTodoUpdater{
|
|
UpdateTodoFunc: func(ctx context.Context, todo service.Todo) error {
|
|
return nil
|
|
},
|
|
}
|
|
|
|
handler := HandleTodoUpdate(logger, &service)
|
|
|
|
requestBody, err := json.Marshal(updateTodoRequest)
|
|
|
|
if err != nil {
|
|
t.Fatalf("Failed to marshal request %+v: %v", updateTodoRequest, err)
|
|
}
|
|
|
|
req := httptest.NewRequest(http.MethodPut, "/todo/1", bytes.NewBuffer(requestBody))
|
|
res := httptest.NewRecorder()
|
|
req.SetPathValue("id", "1")
|
|
|
|
handler(res, req)
|
|
|
|
if res.Code != http.StatusOK {
|
|
t.Errorf("did not get correct status, got %d, want %d", res.Code, http.StatusOK)
|
|
}
|
|
})
|
|
|
|
t.Run("returns 400 with bad json", func(t *testing.T) {
|
|
handler := HandleTodoUpdate(logger, nil)
|
|
|
|
badStruct := struct {
|
|
Foo string
|
|
}{
|
|
Foo: "bar",
|
|
}
|
|
|
|
requestBody, err := json.Marshal(badStruct)
|
|
|
|
if err != nil {
|
|
t.Fatalf("Failed to marshal request %+v: %v", badStruct, err)
|
|
}
|
|
|
|
req := httptest.NewRequest(http.MethodPut, "/todo/1", bytes.NewBuffer(requestBody))
|
|
res := httptest.NewRecorder()
|
|
|
|
handler(res, req)
|
|
|
|
if res.Code != http.StatusBadRequest {
|
|
t.Errorf("did not get correct status, got %d, want %d", res.Code, http.StatusOK)
|
|
}
|
|
})
|
|
|
|
t.Run("returns 400 with bad id", func(t *testing.T) {
|
|
handler := HandleTodoUpdate(logger, nil)
|
|
|
|
req := httptest.NewRequest(http.MethodPut, "/todo/hello", nil)
|
|
res := httptest.NewRecorder()
|
|
req.SetPathValue("id", "hello")
|
|
|
|
handler(res, req)
|
|
|
|
if res.Code != http.StatusBadRequest {
|
|
t.Errorf("did not get correct status, got %d, want %d", res.Code, http.StatusOK)
|
|
}
|
|
})
|
|
|
|
t.Run("returns 500 arbitrary errors", func(t *testing.T) {
|
|
updateTodoRequest := UpdateTodoRequest{Name: "clean dishes", Done: false}
|
|
|
|
service := MockTodoUpdater{
|
|
UpdateTodoFunc: func(ctx context.Context, todo service.Todo) error {
|
|
return errors.New("foo bar")
|
|
},
|
|
}
|
|
|
|
handler := HandleTodoUpdate(logger, &service)
|
|
|
|
requestBody, err := json.Marshal(updateTodoRequest)
|
|
|
|
if err != nil {
|
|
t.Fatalf("Failed to marshal request %+v: %v", updateTodoRequest, err)
|
|
}
|
|
|
|
req := httptest.NewRequest(http.MethodPost, "/todo/1", bytes.NewBuffer(requestBody))
|
|
res := httptest.NewRecorder()
|
|
req.SetPathValue("id", "1")
|
|
|
|
handler(res, req)
|
|
|
|
if res.Code != http.StatusInternalServerError {
|
|
t.Errorf("did not get correct status, got %d, want %d", res.Code, http.StatusOK)
|
|
}
|
|
})
|
|
|
|
}
|