Files
Gardomatic/internal/storage/postgres/locations_integration_test.go
kleiax 904d14b64c
CI / test (push) Canceled after 0s
Initial commit
2026-09-12 22:22:17 +02:00

76 lines
2.7 KiB
Go

package postgres
import (
"database/sql"
"encoding/json"
"errors"
"os"
"testing"
"gardomatic.kleiax.de/internal/storage"
)
func TestLocationAndPlantLocationModelsEnforceGardenBoundary(t *testing.T) {
dsn := os.Getenv("GARDOMATIC_TEST_DB_DSN")
if dsn == "" {
t.Skip("set GARDOMATIC_TEST_DB_DSN to run PostgreSQL integration tests")
}
db, err := sql.Open("postgres", dsn)
if err != nil {
t.Fatal(err)
}
t.Cleanup(func() { _ = db.Close() })
if err := db.Ping(); err != nil {
t.Fatalf("connect to PostgreSQL: %v", err)
}
var gardenID, foreignGardenID int
if err := db.QueryRow(`INSERT INTO gardens (name) VALUES ('Location integration A') RETURNING id`).Scan(&gardenID); err != nil {
t.Fatal(err)
}
if err := db.QueryRow(`INSERT INTO gardens (name) VALUES ('Location integration B') RETURNING id`).Scan(&foreignGardenID); err != nil {
t.Fatal(err)
}
t.Cleanup(func() { _, _ = db.Exec(`DELETE FROM gardens WHERE id IN ($1, $2)`, gardenID, foreignGardenID) })
locations := LocationModel{DB: db}
local, err := locations.Insert(storage.Location{GardenID: gardenID, Name: "Beet", Attributes: json.RawMessage(`{}`)})
if err != nil {
t.Fatalf("insert local location: %v", err)
}
foreign, err := locations.Insert(storage.Location{GardenID: foreignGardenID, Name: "Fremdes Beet", Attributes: json.RawMessage(`{}`)})
if err != nil {
t.Fatalf("insert foreign location: %v", err)
}
if _, err := locations.Get(gardenID, foreign.ID); !errors.Is(err, storage.ErrRecordNotFound) {
t.Fatalf("foreign location lookup: got %v, want ErrRecordNotFound", err)
}
var plantID int
if err := db.QueryRow(`INSERT INTO plants (garden_id, name) VALUES ($1, 'Tomate') RETURNING id`, gardenID).Scan(&plantID); err != nil {
t.Fatal(err)
}
plants, err := (PlantModel{DB: db}).GetAllForGarden(gardenID)
if err != nil {
t.Fatalf("list plants with planter join: %v", err)
}
if len(plants) != 1 || plants[0].ID != plantID {
t.Fatalf("listed plants: got %+v, want plant %d", plants, plantID)
}
assignments := PlantLocationModel{DB: db}
created, err := assignments.Insert(gardenID, storage.PlantLocation{PlantID: plantID, LocationID: local.ID, Quantity: 2})
if err != nil {
t.Fatalf("insert local assignment: %v", err)
}
if created.ID == 0 {
t.Fatal("local assignment has no id")
}
if _, err := assignments.Insert(gardenID, storage.PlantLocation{PlantID: plantID, LocationID: foreign.ID, Quantity: 1}); !errors.Is(err, storage.ErrRecordNotFound) {
t.Fatalf("foreign assignment: got %v, want ErrRecordNotFound", err)
}
listed, err := assignments.GetAllForPlant(gardenID, plantID)
if err != nil || len(listed) != 1 {
t.Fatalf("list assignments: values=%+v err=%v", listed, err)
}
}