package web import ( "encoding/json" "fmt" "io/fs" "net/http" "net/http/httptest" "os" "path/filepath" "testing" "time" "pete/internal/config" "pete/internal/storage" ) // TestDrive is not a test. It is a hand crank: it stands the casino up on a real // port with one funded player so a browser can be pointed at it. Skipped unless // PETE_DRIVE is set. Delete it if it ever stops earning its keep. func TestDrive(t *testing.T) { if os.Getenv("PETE_DRIVE") == "" { t.Skip("set PETE_DRIVE=1 to hand-drive the casino") } // Built through New() with the tables already open, because the /games routes // are registered at construction — newCasino() switches them on afterwards, // which is fine for handler tests and useless for a browser. storage.Close() if err := storage.Init(filepath.Join(t.TempDir(), "drive.db")); err != nil { t.Fatal(err) } defer storage.Close() s, err := New(config.WebConfig{ SiteTitle: "Pete", ListenAddr: ":0", BaseURL: "http://127.0.0.1", Games: config.GamesConfig{Enabled: true, MatrixServer: "parodia.dev"}, }, nil, true, config.AdventureConfig{}, nil) if err != nil { t.Fatal(err) } // New() only mounts the casino when auth is live, and auth means an OIDC // discovery call. Sign the cookie by hand and mount the routes here instead — // the handshake is not what a browser is here to look at. s.auth = &Authenticator{secret: []byte("test-secret-key-at-least-16")} fund(t, 5000) static, err := fs.Sub(staticFS, "static") if err != nil { t.Fatal(err) } mux := http.NewServeMux() mux.Handle("GET /static/", http.StripPrefix("/static/", http.FileServer(http.FS(static)))) mux.HandleFunc("GET /healthz", func(w http.ResponseWriter, _ *http.Request) { w.WriteHeader(200) }) mux.HandleFunc("GET /games", s.handleLobby) mux.HandleFunc("GET /games/blackjack", s.handleBlackjack) mux.HandleFunc("GET /api/games/table", s.handleTable) mux.HandleFunc("POST /api/games/buyin", s.handleBuyIn) mux.HandleFunc("POST /api/games/cashout", s.handleCashOut) mux.HandleFunc("POST /api/games/blackjack/deal", s.handleDeal) mux.HandleFunc("POST /api/games/blackjack/move", s.handleMove) srv := httptest.NewServer(mux) defer srv.Close() payload, _ := json.Marshal(SessionUser{ Sub: "sub-1", Username: "reala", Exp: time.Now().Add(time.Hour).Unix(), }) fmt.Printf("DRIVE_URL=%s\nDRIVE_COOKIE=%s=%s\n", srv.URL, sessionCookie, s.auth.sign(payload)) // Long enough for a browser to buy in, deal a few hands, and be screenshotted. deadline := time.Now().Add(3 * time.Minute) for time.Now().Before(deadline) { time.Sleep(500 * time.Millisecond) if _, err := http.Get(srv.URL + "/healthz"); err != nil { return } } }