package api import ( "database/sql" "fmt" "net/http" "net/http/httptest" "os" "sync/atomic" "testing" "reanimator/internal/repository" "reanimator/internal/repository/migrate" ) func TestRemovedIngestRoutesReturnNotFound(t *testing.T) { dsn := os.Getenv("DATABASE_DSN") if dsn == "" { t.Skip("DATABASE_DSN not set") } db, err := repository.Open(dsn) if err != nil { t.Fatalf("open db: %v", err) } defer db.Close() if err := applyMigrations(db); err != nil { t.Fatalf("apply migrations: %v", err) } if err := cleanupRegistry(db); err != nil { t.Fatalf("cleanup: %v", err) } mux := http.NewServeMux() RegisterIngestRoutes(mux, IngestDependencies{Service: nil}) RegisterFailureRoutes(mux, FailureDependencies{Failures: nil}) server := httptest.NewServer(mux) defer server.Close() resp, err := http.Post(server.URL+"/ingest/logbundle", "application/json", nil) if err != nil { t.Fatalf("post: %v", err) } defer resp.Body.Close() if resp.StatusCode != http.StatusNotFound { t.Fatalf("expected 404 for /ingest/logbundle, got %d", resp.StatusCode) } resp, err = http.Post(server.URL+"/ingest/failures", "application/json", nil) if err != nil { t.Fatalf("post failure ingest: %v", err) } defer resp.Body.Close() if resp.StatusCode != http.StatusNotFound { t.Fatalf("expected 404 for /ingest/failures, got %d", resp.StatusCode) } } func applyMigrations(db *sql.DB) error { return migrate.EnsureSchema(db, "migrations") } func cleanupRegistry(db *sql.DB) error { statements := []string{ "DELETE FROM failure_events", "DELETE FROM machine_firmware_states", "DELETE FROM timeline_events", "DELETE FROM observations", "DELETE FROM log_bundles", "DELETE FROM installations", "DELETE FROM parts", "DELETE FROM machines", "DELETE FROM id_sequences", "DELETE FROM schema_migrations", } for _, stmt := range statements { if _, err := db.Exec(stmt); err != nil { return err } } return nil } var testIDSeq uint64 func insertAsset(t *testing.T, db *sql.DB, name, serial string) string { t.Helper() id := nextTestID("ME") if _, err := db.Exec(`INSERT INTO machines (id, name, vendor_serial) VALUES (?, ?, ?)`, id, name, serial); err != nil { t.Fatalf("insert asset: %v", err) } return id } func nextTestID(prefix string) string { next := atomic.AddUint64(&testIDSeq, 1) return fmt.Sprintf("%s-%07d", prefix, next) } func assertCount(t *testing.T, db *sql.DB, table string, expected int) { t.Helper() query := "SELECT COUNT(*) FROM " + table assertCountQuery(t, db, query, expected) } func assertCountQuery(t *testing.T, db *sql.DB, query string, expected int) { t.Helper() var count int if err := db.QueryRow(query).Scan(&count); err != nil { t.Fatalf("count query: %v", err) } if count != expected { t.Fatalf("expected %d, got %d for query %q", expected, count, query) } }