mattermost-push-proxy-router/server_test.go
Felipe M. 8a4b11281d
feat: add Prometheus metrics endpoint
Expose /metrics with counters for routed requests, routing errors,
upstream outcomes, and upstream latency histograms. Instrument the
router and proxy forwarding path and document the new metrics.
2026-07-27 08:38:28 +02:00

87 lines
2.5 KiB
Go

package main
import (
"io"
"net/http"
"net/http/httptest"
"strings"
"testing"
"time"
"github.com/prometheus/client_golang/prometheus"
)
func TestHandleRouteForwardsToCustomBackend(t *testing.T) {
custom := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.URL.Path != "/api/v1/send_push" {
t.Fatalf("path = %q", r.URL.Path)
}
body, _ := io.ReadAll(r.Body)
if !strings.Contains(string(body), "apple_bubbles") {
t.Fatalf("body = %s", body)
}
w.Header().Set("Content-Type", "application/json")
_, _ = w.Write([]byte(`{"status":"OK"}`))
}))
defer custom.Close()
cfg := Config{
Routes: []Route{
{Prefixes: []string{"apple_bubbles"}, URL: custom.URL},
{Prefixes: []string{"apple_rn"}, URL: "https://example.invalid"},
},
RequestTimeout: time.Duration(defaultRequestTimeoutSec) * time.Second,
}
proxy := NewProxy(cfg, NewMetrics(prometheus.NewRegistry()))
req := httptest.NewRequest(http.MethodPost, "/api/v1/send_push", strings.NewReader(`{"platform":"apple_bubbles","device_id":"tok","server_id":"s1"}`))
rec := httptest.NewRecorder()
handleRoute(rec, req, proxy, cfg, "/api/v1/send_push")
if rec.Code != http.StatusOK {
t.Fatalf("status = %d body = %s", rec.Code, rec.Body.String())
}
if !strings.Contains(rec.Body.String(), `"status":"OK"`) {
t.Fatalf("body = %s", rec.Body.String())
}
}
func TestHandleRouteUnknownPlatform(t *testing.T) {
cfg := Config{
Routes: []Route{
{Prefixes: []string{"apple_bubbles"}, URL: "http://localhost:1"},
},
RequestTimeout: time.Duration(defaultRequestTimeoutSec) * time.Second,
}
proxy := NewProxy(cfg, NewMetrics(prometheus.NewRegistry()))
req := httptest.NewRequest(http.MethodPost, "/api/v1/send_push", strings.NewReader(`{"platform":"unknown_app","device_id":"tok","server_id":"s1"}`))
rec := httptest.NewRecorder()
handleRoute(rec, req, proxy, cfg, "/api/v1/send_push")
if !strings.Contains(rec.Body.String(), `"status":"FAIL"`) {
t.Fatalf("body = %s", rec.Body.String())
}
if !strings.Contains(rec.Body.String(), "unknown_app") {
t.Fatalf("body = %s", rec.Body.String())
}
}
func TestHealthEndpoint(t *testing.T) {
req := httptest.NewRequest(http.MethodGet, "/health", nil)
rec := httptest.NewRecorder()
handleHealth(rec, req)
if rec.Code != http.StatusOK {
t.Fatalf("status = %d", rec.Code)
}
if ct := rec.Header().Get("Content-Type"); !strings.Contains(ct, "application/json") {
t.Fatalf("content-type = %q", ct)
}
if strings.TrimSpace(rec.Body.String()) != `{"status":"ok"}` {
t.Fatalf("body = %q", rec.Body.String())
}
}