/
cloudservices
/
common
Обзор
Документация
Войти
/
cloudservices
/
common
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
master
test/middleware_test.go
115 строк
4 KB
Ivan
move middlewares into separate folder
26 июл 2026, 16:16
26 июл 2026, 16:16
a4dae25
Код
Авторство
О чём код?
package common_test import ( "context" "log/slog" "net/http" "net/http/httptest" "reflect" "testing" middleware "gitverse.ru/cloudservices/common/middleware" ) func TestChainAppliesMiddlewaresInOrder(t *testing.T) { var got []string mark := func(name string) middleware.Middleware { return func(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { got = append(got, name+" before") next.ServeHTTP(w, r) got = append(got, name+" after") }) } } h := middleware.Chain(http.HandlerFunc(func(http.ResponseWriter, *http.Request) { got = append(got, "handler") }), mark("first"), mark("second")) h.ServeHTTP(httptest.NewRecorder(), httptest.NewRequest(http.MethodGet, "/", nil)) want := []string{"first before", "second before", "handler", "second after", "first after"} if !reflect.DeepEqual(got, want) { t.Fatalf("execution order = %#v, want %#v", got, want) } } func TestRequestIDImportsHeader(t *testing.T) { const requestID = "request-id-from-client" var got string h := middleware.RequestID(true)(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { got, _ = r.Context().Value(middleware.RequestIDKey).(string) })) r := httptest.NewRequest(http.MethodGet, "/", nil) r.Header.Set(middleware.RequestIDHeader, requestID) h.ServeHTTP(httptest.NewRecorder(), r) if got != requestID { t.Fatalf("request ID = %q, want %q", got, requestID) } } func TestRequestIDGeneratesIDWhenHeaderIsAbsent(t *testing.T) { var got string h := middleware.RequestID(false)(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { got, _ = r.Context().Value(middleware.RequestIDKey).(string) })) h.ServeHTTP(httptest.NewRecorder(), httptest.NewRequest(http.MethodGet, "/", nil)) if got == "" { t.Fatal("generated request ID is empty") } } func TestLoggingLogsResponseDetails(t *testing.T) { records := make(chan slog.Record, 1) logger := slog.New(recordHandler{records: records}) h := middleware.Logging(logger)(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusCreated) })) r := httptest.NewRequest(http.MethodPost, "/items", nil) r = r.WithContext(context.WithValue(r.Context(), middleware.RequestIDKey, "request-id")) h.ServeHTTP(httptest.NewRecorder(), r) record := <-records values := recordAttrs(record) if record.Message != "http request" || values["status"] != int64(http.StatusCreated) || values["method"] != http.MethodPost || values["path"] != "/items" || values["request_id"] != "request-id" { t.Fatalf("log record = %#v, attrs = %#v", record, values) } } func TestRecoverReturnsInternalServerError(t *testing.T) { records := make(chan slog.Record, 1) h := middleware.Recover(slog.New(recordHandler{records: records}))(http.HandlerFunc(func(http.ResponseWriter, *http.Request) { panic("boom") })) w := httptest.NewRecorder() h.ServeHTTP(w, httptest.NewRequest(http.MethodGet, "/", nil)) if w.Code != http.StatusInternalServerError || w.Body.String() != "Internal Server Error\n" { t.Fatalf("response = %d %q, want 500 response", w.Code, w.Body.String()) } record := <-records if record.Message != "panic" { t.Fatalf("panic log message = %q, want %q", record.Message, "panic") } } type recordHandler struct{ records chan<- slog.Record } func (h recordHandler) Enabled(context.Context, slog.Level) bool { return true } func (h recordHandler) Handle(_ context.Context, record slog.Record) error { h.records <- record return nil } func (h recordHandler) WithAttrs([]slog.Attr) slog.Handler { return h } func (h recordHandler) WithGroup(string) slog.Handler { return h } func recordAttrs(record slog.Record) map[string]any { attrs := make(map[string]any) record.Attrs(func(attr slog.Attr) bool { attrs[attr.Key] = attr.Value.Any() return true }) return attrs }