76 lines
2.7 KiB
Go
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)
|
|
}
|
|
}
|