package antispam import ( "net/http" "net/http/httptest" "net/url" "strings" "testing" ) func setupHcaptchaTest(t *testing.T) (*httptest.Server, *HCaptcha) { server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { if r.Method != http.MethodPost || r.URL.Path != "/siteverify" { t.Errorf("Expecting call to `POST /siteverify`, got: %s %s", r.Method, r.URL.Path) } err := r.ParseForm() if err != nil { t.Errorf("Form parsing error: %s", err) } if secret := r.PostForm.Get("secret"); secret != "test" { t.Errorf("Expecting hCaptcha secret key `test`, got: %s", secret) } w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusOK) if r.PostForm.Get("response") == "test" { _, _ = w.Write([]byte(`{"success": true, "hostname": "localhost"}`)) } else { _, _ = w.Write([]byte(`{"success": false, "hostname": "localhost", "error-codes": ["invalid-input-response"]}`)) } })) hcaptcha := newHcaptcha("test", "test", server.URL) return server, hcaptcha } // TestHcaptchaEmpty checks that empty requests (without the hCaptcha token) are blocked. func TestHcaptchaEmpty(t *testing.T) { server, hcaptcha := setupHcaptchaTest(t) defer server.Close() req := httptest.NewRequest(http.MethodPost, "http://localhost/form", nil) result, err := hcaptcha.CheckRequest(req) if result || err != nil { t.Errorf("hcaptcha.CheckRequest(req) = %v, %v, expecting false, nil", result, err) } } // TestHcaptchaBadToken checks that invalid hCaptcha tokens are blocked. func TestHcaptchaBadToken(t *testing.T) { server, hcaptcha := setupHcaptchaTest(t) defer server.Close() form := url.Values{} form.Add("x-captcha-response", "wrong") req := httptest.NewRequest(http.MethodPost, "http://localhost/form", strings.NewReader(form.Encode())) req.Header.Set("Content-Type", "application/x-www-form-urlencoded") result, err := hcaptcha.CheckRequest(req) if result || err != nil { t.Errorf("hcaptcha.CheckRequest(req) = %v, %v, want false, nil", result, err) } } // TestHcaptchaSuccess mocks a successful hCaptcha verification run. func TestHcaptchaSuccess(t *testing.T) { server, hcaptcha := setupHcaptchaTest(t) defer server.Close() form := url.Values{} form.Add("x-captcha-response", "test") req := httptest.NewRequest(http.MethodPost, "http://localhost/form", strings.NewReader(form.Encode())) req.Header.Set("Content-Type", "application/x-www-form-urlencoded") result, err := hcaptcha.CheckRequest(req) if !result || err != nil { t.Errorf("hcaptcha.CheckRequest(req) = %v, %v, want true, nil", result, err) } }