package handlers_test import ( "encoding/json" "fmt" "io" "net/http" "net/http/httptest" "strings" "testing" "github.com/gin-gonic/gin" "github.com/openstatushq/openstatus/apps/checker/checker" "github.com/openstatushq/openstatus/apps/checker/handlers" "github.com/openstatushq/openstatus/apps/checker/pkg/tinybird" "github.com/openstatushq/openstatus/apps/checker/request" "github.com/stretchr/testify/assert" ) func TestHandler_HTTPCheckerHandler(t *testing.T) { hclient := &http.Client{Transport: RoundTripFunc(func(req *http.Request) *http.Response { return &http.Response{ StatusCode: http.StatusAccepted, Body: io.NopCloser(strings.NewReader(`Status Accepted`)), } })} client := tinybird.NewClient(hclient, "apiKey") t.Run("it should return 401 if there's no auth", func(t *testing.T) { region := "local" h := handlers.Handler{ TbClient: client, Secret: "", CloudProvider: "fly", Region: region, } router := gin.New() router.POST("/checker/:region", h.HTTPCheckerHandler) w := httptest.NewRecorder() data := request.HttpCheckerRequest{ URL: "https://www.openstatus.dev", } dataJson, _ := json.Marshal(data) req, _ := http.NewRequest(http.MethodPost, "/checker/"+region, strings.NewReader(string(dataJson))) router.ServeHTTP(w, req) assert.Equal(t, 401, w.Code) }) t.Run("it should return 400 if the payload is not ok", func(t *testing.T) { region := "local" h := handlers.Handler{ TbClient: client, Secret: "test", CloudProvider: "fly", Region: region, } router := gin.New() router.POST("/checker/:region", h.HTTPCheckerHandler) w := httptest.NewRecorder() data := request.PingRequest{ URL: "https://www.openstatus.dev", } dataJson, _ := json.Marshal(data) req, _ := http.NewRequest(http.MethodPost, "/checker/"+region, strings.NewReader(string(dataJson))) req.Header.Set("Authorization", "Basic test") router.ServeHTTP(w, req) assert.Equal(t, 400, w.Code) assert.Contains(t, w.Body.String(), "{\"error\":\"invalid request\"}") }) t.Run("it should return 200 if the payload is not ok", func(t *testing.T) { region := "local" httptest.NewRequest(http.MethodGet, "http://www.openstatus.dev", nil) httptest.NewRecorder() h := handlers.Handler{ TbClient: client, Secret: "test", CloudProvider: "fly", Region: region, } router := gin.New() router.POST("/checker/:region", h.HTTPCheckerHandler) w := httptest.NewRecorder() data := request.HttpCheckerRequest{ URL: "https://www.openstatus.dev", Method: "GET", Body: "", } dataJson, _ := json.Marshal(data) req, _ := http.NewRequest(http.MethodPost, "/checker/"+region, strings.NewReader(string(dataJson))) req.Header.Set("Authorization", "Basic test") router.ServeHTTP(w, req) assert.Equal(t, 200, w.Code) fmt.Println(w.Body.String()) }) } func TestEvaluateAssertions_raw(t *testing.T) { // Helper to marshal assertion marshal := func(a any) json.RawMessage { b, _ := json.Marshal(a) return b } // Success if no assertions and status code is 200 t.Run("no assertions, status code 200", func(t *testing.T) { raw := []json.RawMessage{} data := handlers.PingData{} res := checker.Response{Status: 200} ok, err := handlers.EvaluateHTTPAssertions(raw, data, res) assert.True(t, ok) assert.NoError(t, err) }) // Header assertion success t.Run("header assertion success", func(t *testing.T) { assertion := request.Assertion{AssertionType: request.AssertionHeader} target := struct { request.Assertion Comparator request.StringComparator `json:"compare"` Key string `json:"key"` Target string `json:"target"` }{ assertion, request.StringContains, "X-Test", "ok", } rawMsg := marshal(target) raw := []json.RawMessage{rawMsg} data := handlers.PingData{Headers: `{"X-Test":"ok-value"}`} res := checker.Response{Status: 200} ok, err := handlers.EvaluateHTTPAssertions(raw, data, res) assert.True(t, ok) assert.NoError(t, err) }) t.Run("header assertion failed", func(t *testing.T) { assertion := request.Assertion{AssertionType: request.AssertionHeader} target := struct { request.Assertion Comparator request.StringComparator `json:"compare"` Key string `json:"key"` Target string `json:"target"` }{ assertion, request.StringContains, "X-Test", "not-ok", } rawMsg := marshal(target) raw := []json.RawMessage{rawMsg} data := handlers.PingData{Headers: `{"X-Test":"ok-value"}`} res := checker.Response{Status: 200} ok, err := handlers.EvaluateHTTPAssertions(raw, data, res) assert.False(t, ok) assert.NoError(t, err) }) // Text body assertion failure t.Run("text body assertion failure", func(t *testing.T) { assertion := request.Assertion{AssertionType: request.AssertionTextBody} target := struct { request.Assertion Comparator request.StringComparator `json:"compare"` Target string `json:"target"` }{ assertion, request.StringEquals, "fail", } rawMsg := marshal(target) raw := []json.RawMessage{rawMsg} data := handlers.PingData{Body: "ok"} res := checker.Response{Status: 200} ok, err := handlers.EvaluateHTTPAssertions(raw, data, res) assert.False(t, ok) assert.NoError(t, err) }) // Text body assertion failure t.Run("text body assertion success", func(t *testing.T) { assertion := request.Assertion{AssertionType: request.AssertionTextBody} target := struct { request.Assertion Comparator request.StringComparator `json:"compare"` Target string `json:"target"` }{ assertion, request.StringEquals, "success", } rawMsg := marshal(target) raw := []json.RawMessage{rawMsg} data := handlers.PingData{Body: "success"} res := checker.Response{Status: 200} ok, err := handlers.EvaluateHTTPAssertions(raw, data, res) assert.True(t, ok) assert.NoError(t, err) }) // Status assertion success t.Run("status assertion success", func(t *testing.T) { assertion := request.Assertion{AssertionType: request.AssertionStatus} target := struct { request.Assertion Comparator request.NumberComparator `json:"compare"` Target int64 `json:"target"` }{ assertion, request.NumberEquals, 200, } rawMsg := marshal(target) raw := []json.RawMessage{rawMsg} data := handlers.PingData{} res := checker.Response{Status: 200} ok, err := handlers.EvaluateHTTPAssertions(raw, data, res) assert.True(t, ok) assert.NoError(t, err) }) // Malformed assertion t.Run("malformed assertion", func(t *testing.T) { raw := []json.RawMessage{[]byte(`{not valid json}`)} data := handlers.PingData{} res := checker.Response{Status: 200} ok, err := handlers.EvaluateHTTPAssertions(raw, data, res) assert.False(t, ok) assert.Error(t, err) }) // Unknown assertion type t.Run("unknown assertion type", func(t *testing.T) { assertion := request.Assertion{AssertionType: "unknown"} rawMsg := marshal(assertion) raw := []json.RawMessage{rawMsg} data := handlers.PingData{} res := checker.Response{Status: 200} ok, err := handlers.EvaluateHTTPAssertions(raw, data, res) assert.True(t, ok) // Should not fail, just skip assert.NoError(t, err) }) }