package telescope import ( "net/http" "net/http/httptest" "strings" "testing" ) func TestRingOrderAndOverflow(t *testing.T) { tel := New(3) for i := 0; i < 5; i++ { tel.add(Entry{Path: string(rune('a' + i))}) } got := tel.Entries() if len(got) != 3 { t.Fatalf("want 3 entries, got %d", len(got)) } // جدید-به-قدیم: e, d, c (a و b بازنویسی شده‌اند). want := []string{"e", "d", "c"} for i, w := range want { if got[i].Path != w { t.Errorf("entry %d: want %q got %q", i, w, got[i].Path) } } // شناسه‌ها باید افزایشی و یکتا باشند. if got[0].ID != 5 || got[2].ID != 3 { t.Errorf("ids wrong: %d..%d", got[2].ID, got[0].ID) } } func TestMiddlewareCapturesErrorBodyMasked(t *testing.T) { tel := New(10) h := tel.Middleware(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { w.WriteHeader(http.StatusBadRequest) })) req := httptest.NewRequest(http.MethodPost, "/api/x", strings.NewReader(`{"password":"secret","kind":"coin"}`)) h.ServeHTTP(httptest.NewRecorder(), req) e := tel.Entries() if len(e) != 1 || e[0].Status != 400 { t.Fatalf("expected one 400 entry, got %+v", e) } if !strings.Contains(e[0].Body, `"password":"***"`) { t.Errorf("password not masked: %s", e[0].Body) } if !strings.Contains(e[0].Body, `"kind":"coin"`) { t.Errorf("non-secret field lost: %s", e[0].Body) } } func TestMiddlewareOKHasNoBody(t *testing.T) { tel := New(10) h := tel.Middleware(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { w.WriteHeader(http.StatusOK) })) req := httptest.NewRequest(http.MethodPost, "/api/y", strings.NewReader(`{"token":"abc"}`)) h.ServeHTTP(httptest.NewRecorder(), req) e := tel.Entries() if len(e) != 1 || e[0].Body != "" { t.Errorf("2xx should not store body, got %+v", e) } } func TestMiddlewareSkipsWS(t *testing.T) { tel := New(10) h := tel.Middleware(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) { w.WriteHeader(http.StatusOK) })) h.ServeHTTP(httptest.NewRecorder(), httptest.NewRequest(http.MethodGet, "/ws", nil)) if len(tel.Entries()) != 0 { t.Error("ws request should be skipped") } }