Files
kleiax 904d14b64c
CI / test (push) Canceled after 0s
Initial commit
2026-09-12 22:22:17 +02:00

87 lines
4.4 KiB
Go

package web
import (
"context"
"encoding/json"
"io"
"net/http"
"net/http/httptest"
"net/url"
"strings"
"testing"
"gardomatic.kleiax.de/lib/client"
"github.com/julienschmidt/httprouter"
)
func taskWebRequest(request *http.Request, apiClient *client.Client, params httprouter.Params) *http.Request {
ctx := context.WithValue(request.Context(), httprouter.ParamsKey, params)
ctx = client.NewContext(ctx, apiClient)
return request.WithContext(ctx)
}
func TestTaskListAndCreateWebFlow(t *testing.T) {
var created client.TaskInput
apiHandler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
switch {
case r.Method == http.MethodGet && r.URL.Path == "/v1/gardens/3":
_, _ = w.Write([]byte(`{"garden":{"id":3,"name":"Hinterhof"}}`))
case r.Method == http.MethodGet && r.URL.Path == "/v1/gardens/3/tasks":
_, _ = w.Write([]byte(`{"tasks":[{"id":7,"garden_id":3,"title":"Tomaten gießen","plant_id":5,"location_id":6,"priority":5},{"id":9,"garden_id":3,"title":"Bereits erledigt","completed_at":"2026-09-01T10:00:00Z"}]}`))
case r.Method == http.MethodGet && r.URL.Path == "/v1/gardens/3/plants":
_, _ = w.Write([]byte(`{"plants":[{"id":5,"garden_id":3,"name":"Tomate"}]}`))
case r.Method == http.MethodGet && r.URL.Path == "/v1/gardens/3/locations":
_, _ = w.Write([]byte(`{"locations":[{"id":6,"garden_id":3,"name":"Beet"}]}`))
case r.Method == http.MethodGet && r.URL.Path == "/v1/task-priorities":
_, _ = w.Write([]byte(`{"priorities":[{"id":1,"name":"Normal","value":0,"active":true},{"id":2,"name":"Hoch","value":5,"active":true}]}`))
case r.Method == http.MethodPost && r.URL.Path == "/v1/gardens/3/tasks":
body, _ := io.ReadAll(r.Body)
if err := json.Unmarshal(body, &created); err != nil {
t.Fatal(err)
}
w.WriteHeader(http.StatusCreated)
_, _ = w.Write([]byte(`{"task":{"id":8,"garden_id":3,"title":"Ernten"}}`))
default:
http.NotFound(w, r)
}
})
app := newAPIBackedTestApplication(t, apiHandler)
params := httprouter.Params{{Key: "gardenID", Value: "3"}}
listRequest := taskWebRequest(httptest.NewRequest(http.MethodGet, "/g/3/tasks", nil), app.apiClient, params)
listResponse := httptest.NewRecorder()
app.tasks(listResponse, listRequest)
if listResponse.Code != http.StatusOK || !strings.Contains(listResponse.Body.String(), "Tomaten gießen") || !strings.Contains(listResponse.Body.String(), "Pflanze: Tomate") || strings.Contains(listResponse.Body.String(), "Bereits erledigt") {
t.Fatalf("task list: status=%d body=%s", listResponse.Code, listResponse.Body.String())
}
form := url.Values{"title": {"Ernten"}, "plant_id": {"5"}, "location_id": {"6"}, "priority": {"3"}, "due_at_start": {"2026-09-03T08:00"}, "due_at_end": {"2026-09-03T18:00"}, "recurrence": {"weekly"}, "recurrence_interval": {"2"}}
createRequest := httptest.NewRequest(http.MethodPost, "/g/3/tasks/new", strings.NewReader(form.Encode()))
createRequest.Header.Set("Content-Type", "application/x-www-form-urlencoded")
createRequest = taskWebRequest(createRequest, app.apiClient, params)
createResponse := httptest.NewRecorder()
app.taskSave(createResponse, createRequest)
if createResponse.Code != http.StatusSeeOther || createResponse.Header().Get("Location") != "/g/3/tasks" {
t.Fatalf("create redirect: status=%d location=%q body=%s", createResponse.Code, createResponse.Header().Get("Location"), createResponse.Body.String())
}
if created.Title == nil || *created.Title != "Ernten" || created.PlantID == nil || *created.PlantID != 5 || created.DueAtEnd == nil || created.Recurrence == nil || *created.Recurrence != "weekly" || created.RecurrenceInterval == nil || *created.RecurrenceInterval != 2 {
t.Errorf("created task input: %+v", created)
}
}
func TestCollectionPageSizeUsesValidatedUserPreference(t *testing.T) {
request := httptest.NewRequest(http.MethodGet, "/g/3/tasks", nil)
request = request.WithContext(context.WithValue(request.Context(), userContextKey, client.User{ID: 7}))
request.AddCookie(&http.Cookie{Name: "gardomatic.entries-per-page.7", Value: "50"})
if got := collectionPageSize(request); got != 50 {
t.Fatalf("collectionPageSize = %d, want 50", got)
}
request = httptest.NewRequest(http.MethodGet, "/g/3/tasks", nil)
request.AddCookie(&http.Cookie{Name: "gardomatic.entries-per-page", Value: "17"})
if got := collectionPageSize(request); got != 20 {
t.Fatalf("invalid collectionPageSize = %d, want default 20", got)
}
}