Openstatus www.openstatus.dev
6
fork

Configure Feed

Select the types of activity you want to include in your feed.

at main 262 lines 7.4 kB view raw
1package handlers_test 2 3import ( 4 "encoding/json" 5 "fmt" 6 "io" 7 "net/http" 8 "net/http/httptest" 9 "strings" 10 "testing" 11 12 "github.com/gin-gonic/gin" 13 "github.com/openstatushq/openstatus/apps/checker/checker" 14 "github.com/openstatushq/openstatus/apps/checker/handlers" 15 16 "github.com/openstatushq/openstatus/apps/checker/pkg/tinybird" 17 "github.com/openstatushq/openstatus/apps/checker/request" 18 "github.com/stretchr/testify/assert" 19) 20 21func TestHandler_HTTPCheckerHandler(t *testing.T) { 22 hclient := &http.Client{Transport: RoundTripFunc(func(req *http.Request) *http.Response { 23 return &http.Response{ 24 StatusCode: http.StatusAccepted, 25 Body: io.NopCloser(strings.NewReader(`Status Accepted`)), 26 } 27 })} 28 client := tinybird.NewClient(hclient, "apiKey") 29 30 t.Run("it should return 401 if there's no auth", func(t *testing.T) { 31 32 region := "local" 33 h := handlers.Handler{ 34 TbClient: client, 35 Secret: "", 36 CloudProvider: "fly", 37 Region: region, 38 } 39 router := gin.New() 40 router.POST("/checker/:region", h.HTTPCheckerHandler) 41 42 w := httptest.NewRecorder() 43 44 data := request.HttpCheckerRequest{ 45 URL: "https://www.openstatus.dev", 46 } 47 dataJson, _ := json.Marshal(data) 48 req, _ := http.NewRequest(http.MethodPost, "/checker/"+region, strings.NewReader(string(dataJson))) 49 router.ServeHTTP(w, req) 50 51 assert.Equal(t, 401, w.Code) 52 }) 53 54 t.Run("it should return 400 if the payload is not ok", func(t *testing.T) { 55 region := "local" 56 57 h := handlers.Handler{ 58 TbClient: client, 59 Secret: "test", 60 CloudProvider: "fly", 61 Region: region, 62 } 63 router := gin.New() 64 router.POST("/checker/:region", h.HTTPCheckerHandler) 65 66 w := httptest.NewRecorder() 67 68 data := request.PingRequest{ 69 URL: "https://www.openstatus.dev", 70 } 71 dataJson, _ := json.Marshal(data) 72 req, _ := http.NewRequest(http.MethodPost, "/checker/"+region, strings.NewReader(string(dataJson))) 73 req.Header.Set("Authorization", "Basic test") 74 router.ServeHTTP(w, req) 75 76 assert.Equal(t, 400, w.Code) 77 assert.Contains(t, w.Body.String(), "{\"error\":\"invalid request\"}") 78 }) 79 80 t.Run("it should return 200 if the payload is not ok", func(t *testing.T) { 81 region := "local" 82 83 httptest.NewRequest(http.MethodGet, "http://www.openstatus.dev", nil) 84 httptest.NewRecorder() 85 86 h := handlers.Handler{ 87 TbClient: client, 88 Secret: "test", 89 CloudProvider: "fly", 90 Region: region, 91 } 92 router := gin.New() 93 router.POST("/checker/:region", h.HTTPCheckerHandler) 94 95 w := httptest.NewRecorder() 96 97 data := request.HttpCheckerRequest{ 98 URL: "https://www.openstatus.dev", 99 Method: "GET", 100 Body: "", 101 } 102 dataJson, _ := json.Marshal(data) 103 req, _ := http.NewRequest(http.MethodPost, "/checker/"+region, strings.NewReader(string(dataJson))) 104 req.Header.Set("Authorization", "Basic test") 105 router.ServeHTTP(w, req) 106 107 assert.Equal(t, 200, w.Code) 108 fmt.Println(w.Body.String()) 109 }) 110} 111 112func TestEvaluateAssertions_raw(t *testing.T) { 113 // Helper to marshal assertion 114 marshal := func(a any) json.RawMessage { 115 b, _ := json.Marshal(a) 116 return b 117 } 118 119 // Success if no assertions and status code is 200 120 t.Run("no assertions, status code 200", func(t *testing.T) { 121 raw := []json.RawMessage{} 122 data := handlers.PingData{} 123 res := checker.Response{Status: 200} 124 ok, err := handlers.EvaluateHTTPAssertions(raw, data, res) 125 assert.True(t, ok) 126 assert.NoError(t, err) 127 }) 128 129 // Header assertion success 130 t.Run("header assertion success", func(t *testing.T) { 131 assertion := request.Assertion{AssertionType: request.AssertionHeader} 132 target := struct { 133 request.Assertion 134 Comparator request.StringComparator `json:"compare"` 135 Key string `json:"key"` 136 Target string `json:"target"` 137 }{ 138 assertion, 139 request.StringContains, 140 "X-Test", 141 "ok", 142 } 143 rawMsg := marshal(target) 144 raw := []json.RawMessage{rawMsg} 145 data := handlers.PingData{Headers: `{"X-Test":"ok-value"}`} 146 res := checker.Response{Status: 200} 147 148 ok, err := handlers.EvaluateHTTPAssertions(raw, data, res) 149 assert.True(t, ok) 150 assert.NoError(t, err) 151 }) 152 153 t.Run("header assertion failed", func(t *testing.T) { 154 assertion := request.Assertion{AssertionType: request.AssertionHeader} 155 target := struct { 156 request.Assertion 157 Comparator request.StringComparator `json:"compare"` 158 Key string `json:"key"` 159 Target string `json:"target"` 160 }{ 161 assertion, 162 request.StringContains, 163 "X-Test", 164 "not-ok", 165 } 166 rawMsg := marshal(target) 167 raw := []json.RawMessage{rawMsg} 168 data := handlers.PingData{Headers: `{"X-Test":"ok-value"}`} 169 res := checker.Response{Status: 200} 170 171 ok, err := handlers.EvaluateHTTPAssertions(raw, data, res) 172 assert.False(t, ok) 173 assert.NoError(t, err) 174 }) 175 176 // Text body assertion failure 177 t.Run("text body assertion failure", func(t *testing.T) { 178 assertion := request.Assertion{AssertionType: request.AssertionTextBody} 179 target := struct { 180 request.Assertion 181 Comparator request.StringComparator `json:"compare"` 182 Target string `json:"target"` 183 }{ 184 assertion, 185 request.StringEquals, 186 "fail", 187 } 188 rawMsg := marshal(target) 189 raw := []json.RawMessage{rawMsg} 190 data := handlers.PingData{Body: "ok"} 191 res := checker.Response{Status: 200} 192 193 ok, err := handlers.EvaluateHTTPAssertions(raw, data, res) 194 assert.False(t, ok) 195 assert.NoError(t, err) 196 }) 197 198 // Text body assertion failure 199 t.Run("text body assertion success", func(t *testing.T) { 200 assertion := request.Assertion{AssertionType: request.AssertionTextBody} 201 target := struct { 202 request.Assertion 203 Comparator request.StringComparator `json:"compare"` 204 Target string `json:"target"` 205 }{ 206 assertion, 207 request.StringEquals, 208 "success", 209 } 210 rawMsg := marshal(target) 211 raw := []json.RawMessage{rawMsg} 212 data := handlers.PingData{Body: "success"} 213 res := checker.Response{Status: 200} 214 215 ok, err := handlers.EvaluateHTTPAssertions(raw, data, res) 216 assert.True(t, ok) 217 assert.NoError(t, err) 218 }) 219 // Status assertion success 220 t.Run("status assertion success", func(t *testing.T) { 221 assertion := request.Assertion{AssertionType: request.AssertionStatus} 222 target := struct { 223 request.Assertion 224 Comparator request.NumberComparator `json:"compare"` 225 Target int64 `json:"target"` 226 }{ 227 assertion, 228 request.NumberEquals, 229 200, 230 } 231 rawMsg := marshal(target) 232 raw := []json.RawMessage{rawMsg} 233 data := handlers.PingData{} 234 res := checker.Response{Status: 200} 235 236 ok, err := handlers.EvaluateHTTPAssertions(raw, data, res) 237 assert.True(t, ok) 238 assert.NoError(t, err) 239 }) 240 241 // Malformed assertion 242 t.Run("malformed assertion", func(t *testing.T) { 243 raw := []json.RawMessage{[]byte(`{not valid json}`)} 244 data := handlers.PingData{} 245 res := checker.Response{Status: 200} 246 ok, err := handlers.EvaluateHTTPAssertions(raw, data, res) 247 assert.False(t, ok) 248 assert.Error(t, err) 249 }) 250 251 // Unknown assertion type 252 t.Run("unknown assertion type", func(t *testing.T) { 253 assertion := request.Assertion{AssertionType: "unknown"} 254 rawMsg := marshal(assertion) 255 raw := []json.RawMessage{rawMsg} 256 data := handlers.PingData{} 257 res := checker.Response{Status: 200} 258 ok, err := handlers.EvaluateHTTPAssertions(raw, data, res) 259 assert.True(t, ok) // Should not fail, just skip 260 assert.NoError(t, err) 261 }) 262}