package neoircapi_test import ( "io" "net" "net/http" "net/http/httptest" "net/url" "testing" api "sneak.berlin/go/neoirc/internal/cli/api" ) const cookieValue = "opaque-value" // newSessionServer starts a plain-HTTP server that, like // neoircd, sets a Secure auth cookie when a session is // created and answers GET /api/v1/state only when that // cookie comes back. func newSessionServer(t *testing.T) *httptest.Server { t.Helper() mux := http.NewServeMux() mux.HandleFunc("GET /api/v1/server", func( writer http.ResponseWriter, _ *http.Request, ) { _, _ = io.WriteString(writer, `{}`) }) mux.HandleFunc("POST /api/v1/session", func( writer http.ResponseWriter, _ *http.Request, ) { http.SetCookie(writer, &http.Cookie{ Name: "neoirc_auth", Value: cookieValue, Path: "/", HttpOnly: true, Secure: true, SameSite: http.SameSiteStrictMode, }) writer.WriteHeader(http.StatusCreated) _, _ = io.WriteString(writer, `{"id":1,"nick":"alice"}`) }) mux.HandleFunc("GET /api/v1/state", func( writer http.ResponseWriter, request *http.Request, ) { cookie, err := request.Cookie("neoirc_auth") if err != nil || cookie.Value != cookieValue { writer.WriteHeader(http.StatusUnauthorized) return } _, _ = io.WriteString( writer, `{"id":1,"nick":"alice","channels":[]}`, ) }) server := httptest.NewServer(mux) t.Cleanup(server.Close) return server } func TestClientKeepsSessionOverPlainHTTPOnLocalhost(t *testing.T) { t.Parallel() server := newSessionServer(t) serverURL, err := url.Parse(server.URL) if err != nil { t.Fatalf("parse server URL: %v", err) } for _, host := range []string{"127.0.0.1", "localhost"} { t.Run(host, func(t *testing.T) { t.Parallel() client := api.NewClient( "http://" + net.JoinHostPort(host, serverURL.Port()), ) _, err := client.CreateSession("alice") if err != nil { t.Fatalf("create session: %v", err) } _, err = client.GetState() if err != nil { t.Fatalf("state after creating the session: %v", err) } }) } }