90 lines
3.4 KiB
Go
90 lines
3.4 KiB
Go
package client
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"net/http"
|
|
"testing"
|
|
)
|
|
|
|
func TestGardenCanUsesEffectivePermissions(t *testing.T) {
|
|
custom := Garden{Role: "garden:custom", Permissions: []string{"plants:create"}}
|
|
if !custom.Can("plants:create") || custom.Can("garden:update") {
|
|
t.Fatalf("custom role did not use effective permissions: %+v", custom)
|
|
}
|
|
|
|
deniedOverride := Garden{Role: "owner", Permissions: []string{"garden:read"}}
|
|
if deniedOverride.Can("garden:update") {
|
|
t.Fatal("explicit permissions must override the built-in role fallback")
|
|
}
|
|
|
|
legacyOwner := Garden{Role: "owner"}
|
|
if !legacyOwner.Can("garden:update") {
|
|
t.Fatal("legacy built-in role response should retain compatibility")
|
|
}
|
|
if legacyOwner.Can("unknown:permission") {
|
|
t.Fatal("legacy role fallback must reject unknown permissions")
|
|
}
|
|
}
|
|
|
|
func TestGardenClientCRUD(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
name := "Neu"
|
|
description := "Beschreibung"
|
|
handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
w.Header().Set("Content-Type", "application/json")
|
|
switch {
|
|
case r.Method == http.MethodPost && r.URL.Path == "/v1/gardens":
|
|
var input CreateGardenInput
|
|
if err := json.NewDecoder(r.Body).Decode(&input); err != nil {
|
|
t.Error(err)
|
|
}
|
|
if input.Name != "Hinterhof" {
|
|
t.Errorf("create name: got %q, want %q", input.Name, "Hinterhof")
|
|
}
|
|
w.WriteHeader(http.StatusCreated)
|
|
_, _ = w.Write([]byte(`{"garden":{"id":12,"name":"Hinterhof","version":1}}`))
|
|
case r.Method == http.MethodGet && r.URL.Path == "/v1/gardens":
|
|
_, _ = w.Write([]byte(`{"gardens":[{"id":12,"name":"Hinterhof","version":1}]}`))
|
|
case r.Method == http.MethodGet && r.URL.Path == "/v1/gardens/12":
|
|
_, _ = w.Write([]byte(`{"garden":{"id":12,"name":"Hinterhof","version":1}}`))
|
|
case r.Method == http.MethodPatch && r.URL.Path == "/v1/gardens/12":
|
|
var input UpdateGardenInput
|
|
if err := json.NewDecoder(r.Body).Decode(&input); err != nil {
|
|
t.Error(err)
|
|
}
|
|
if input.Name == nil || *input.Name != name || input.Description == nil || *input.Description != description {
|
|
t.Errorf("update input: got %+v", input)
|
|
}
|
|
_, _ = w.Write([]byte(`{"garden":{"id":12,"name":"Neu","description":"Beschreibung","version":2}}`))
|
|
case r.Method == http.MethodDelete && r.URL.Path == "/v1/gardens/12":
|
|
w.WriteHeader(http.StatusNoContent)
|
|
default:
|
|
http.NotFound(w, r)
|
|
}
|
|
})
|
|
|
|
apiClient := newTestClient(t, handler)
|
|
created, response, err := apiClient.CreateGarden(context.Background(), CreateGardenInput{Name: "Hinterhof"})
|
|
if err != nil || response.StatusCode != http.StatusCreated || created.ID != 12 {
|
|
t.Fatalf("CreateGarden(): garden=%+v response=%v err=%v", created, response, err)
|
|
}
|
|
gardens, _, err := apiClient.Gardens(context.Background())
|
|
if err != nil || len(gardens) != 1 || gardens[0].ID != 12 {
|
|
t.Fatalf("Gardens(): gardens=%+v err=%v", gardens, err)
|
|
}
|
|
garden, _, err := apiClient.Garden(context.Background(), 12)
|
|
if err != nil || garden.Name != "Hinterhof" {
|
|
t.Fatalf("Garden(): garden=%+v err=%v", garden, err)
|
|
}
|
|
updated, _, err := apiClient.UpdateGarden(context.Background(), 12, UpdateGardenInput{Name: &name, Description: &description})
|
|
if err != nil || updated.Version != 2 || updated.Name != name {
|
|
t.Fatalf("UpdateGarden(): garden=%+v err=%v", updated, err)
|
|
}
|
|
response, err = apiClient.DeleteGarden(context.Background(), 12)
|
|
if err != nil || response.StatusCode != http.StatusNoContent {
|
|
t.Fatalf("DeleteGarden(): response=%v err=%v", response, err)
|
|
}
|
|
}
|