package infra import ( "database/sql" "net/http" "net/http/httptest" "testing" "time" _ "github.com/mattn/go-sqlite3" ) type ctxKey string const testUserCtxKey ctxKey = "user_id" func setupSessionDB(t *testing.T) (*sql.DB, string) { t.Helper() db, err := sql.Open("sqlite3", ":memory:") if err != nil { t.Fatalf("open db: %v", err) } sess, err := SessionCreate(db, "user-42", time.Hour, nil) if err != nil { t.Fatalf("session_create: %v", err) } return db, sess.Token } func TestHTTPSessionCookieMiddleware(t *testing.T) { t.Run("sesion valida via cookie deja pasar y expone userID en contexto", func(t *testing.T) { db, token := setupSessionDB(t) defer db.Close() cfg := SessionCookieConfig{ DB: db, CookieName: "app_session", SkipPaths: []string{"/api/auth/"}, UserCtxKey: testUserCtxKey, } var gotUserID string handler := HTTPSessionCookieMiddleware(cfg)(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { gotUserID, _ = UserIDFromContext(r.Context(), testUserCtxKey) w.WriteHeader(http.StatusOK) })) req := httptest.NewRequest(http.MethodGet, "/api/board", nil) req.AddCookie(&http.Cookie{Name: "app_session", Value: token}) rec := httptest.NewRecorder() handler.ServeHTTP(rec, req) if rec.Code != http.StatusOK { t.Errorf("status: got %d, want 200", rec.Code) } if gotUserID != "user-42" { t.Errorf("userID: got %q, want %q", gotUserID, "user-42") } }) t.Run("sin cookie ni header devuelve 401", func(t *testing.T) { db, _ := setupSessionDB(t) defer db.Close() cfg := SessionCookieConfig{ DB: db, CookieName: "app_session", SkipPaths: []string{}, UserCtxKey: testUserCtxKey, } handler := HTTPSessionCookieMiddleware(cfg)(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusOK) })) req := httptest.NewRequest(http.MethodGet, "/api/board", nil) rec := httptest.NewRecorder() handler.ServeHTTP(rec, req) if rec.Code != http.StatusUnauthorized { t.Errorf("status: got %d, want 401", rec.Code) } }) t.Run("skip path bypassa sin validar token", func(t *testing.T) { db, _ := setupSessionDB(t) defer db.Close() cfg := SessionCookieConfig{ DB: db, CookieName: "app_session", SkipPaths: []string{"/api/auth/", "/health"}, UserCtxKey: testUserCtxKey, } handler := HTTPSessionCookieMiddleware(cfg)(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusOK) })) req := httptest.NewRequest(http.MethodPost, "/api/auth/login", nil) rec := httptest.NewRecorder() handler.ServeHTTP(rec, req) if rec.Code != http.StatusOK { t.Errorf("skip path: got %d, want 200", rec.Code) } }) }