@@ -0,0 +1,64 @@
|
||||
package postgres
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"errors"
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"gardomatic.kleiax.de/internal/storage"
|
||||
)
|
||||
|
||||
func TestTaskModelEnforcesGardenBoundary(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 userID, gardenID, foreignGardenID int
|
||||
if err := db.QueryRow(`INSERT INTO users (name, email, password_hash, activated) VALUES ('Task integration', $1, 'hash', true) RETURNING id`, "task-integration-"+t.Name()+"@example.com").Scan(&userID); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := db.QueryRow(`INSERT INTO gardens (name) VALUES ('Task integration A') RETURNING id`).Scan(&gardenID); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := db.QueryRow(`INSERT INTO gardens (name) VALUES ('Task 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)
|
||||
_, _ = db.Exec(`DELETE FROM users WHERE id = $1`, userID)
|
||||
})
|
||||
|
||||
model := TaskModel{DB: db}
|
||||
local, err := model.Insert(storage.Task{GardenID: gardenID, Title: "Gießen", CreatedBy: userID})
|
||||
if err != nil {
|
||||
t.Fatalf("insert task: %v", err)
|
||||
}
|
||||
foreign, err := model.Insert(storage.Task{GardenID: foreignGardenID, Title: "Fremd", CreatedBy: userID})
|
||||
if err != nil {
|
||||
t.Fatalf("insert foreign task: %v", err)
|
||||
}
|
||||
if _, err := model.Get(gardenID, foreign.ID); !errors.Is(err, storage.ErrRecordNotFound) {
|
||||
t.Fatalf("foreign lookup: got %v", err)
|
||||
}
|
||||
local.Title = "Kräftig gießen"
|
||||
updated, err := model.Update(gardenID, local)
|
||||
if err != nil || updated.Version != 2 {
|
||||
t.Fatalf("update: task=%+v err=%v", updated, err)
|
||||
}
|
||||
if err := model.Delete(foreignGardenID, local.ID); !errors.Is(err, storage.ErrRecordNotFound) {
|
||||
t.Fatalf("foreign delete: got %v", err)
|
||||
}
|
||||
if listed, err := model.GetAllForGarden(gardenID); err != nil || len(listed) != 1 || listed[0].ID != local.ID {
|
||||
t.Fatalf("list: tasks=%+v err=%v", listed, err)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user