package acmecert import ( "fmt" "io" "net" "net/http" "testing" "time" "mailgoserver/internal/toolbox" ) // freePort asks the OS for an unused TCP port, mirroring the pattern used elsewhere in // this codebase's tests for binding to an ephemeral port deterministically. func freePort(t *testing.T) int { t.Helper() l, err := net.Listen("tcp", "127.0.0.1:0") if err != nil { t.Fatal(err) } defer l.Close() return l.Addr().(*net.TCPAddr).Port } func waitUntilUp(t *testing.T, url string) { t.Helper() deadline := time.Now().Add(2 * time.Second) for time.Now().Before(deadline) { if resp, err := http.Get(url); err == nil { resp.Body.Close() return } time.Sleep(10 * time.Millisecond) } t.Fatalf("server at %s never came up", url) } func TestHTTP01ServerHealthEndpointReturns200(t *testing.T) { port := freePort(t) s := NewHTTP01Server() s.Start(fmt.Sprintf("127.0.0.1:%d", port), toolbox.GetLogger("test")) url := fmt.Sprintf("http://127.0.0.1:%d/anything", port) waitUntilUp(t, url) resp, err := http.Get(url) if err != nil { t.Fatal(err) } defer resp.Body.Close() if resp.StatusCode != http.StatusOK { t.Fatalf("expected 200, got %d", resp.StatusCode) } } func TestHTTP01ServerServesPresentedChallenge(t *testing.T) { port := freePort(t) s := NewHTTP01Server() s.Start(fmt.Sprintf("127.0.0.1:%d", port), toolbox.GetLogger("test")) waitUntilUp(t, fmt.Sprintf("http://127.0.0.1:%d/", port)) if err := s.Present("example.com", "sometoken", "sometoken.keyauth"); err != nil { t.Fatal(err) } resp, err := http.Get(fmt.Sprintf("http://127.0.0.1:%d/.well-known/acme-challenge/sometoken", port)) if err != nil { t.Fatal(err) } defer resp.Body.Close() body, _ := io.ReadAll(resp.Body) if resp.StatusCode != http.StatusOK || string(body) != "sometoken.keyauth" { t.Fatalf("expected 200 with keyAuth body, got %d %q", resp.StatusCode, body) } if err := s.CleanUp("example.com", "sometoken", "sometoken.keyauth"); err != nil { t.Fatal(err) } resp2, err := http.Get(fmt.Sprintf("http://127.0.0.1:%d/.well-known/acme-challenge/sometoken", port)) if err != nil { t.Fatal(err) } defer resp2.Body.Close() if resp2.StatusCode != http.StatusNotFound { t.Fatalf("expected 404 after CleanUp, got %d", resp2.StatusCode) } }