package middleware_test import ( "bytes" "encoding/json" "errors" "net/http/httptest" "testing" apierrors "git.yuntuo.hk/k2safe/go-omni/errors" "git.yuntuo.hk/k2safe/go-omni/httpx" "git.yuntuo.hk/k2safe/go-omni/logx" "git.yuntuo.hk/k2safe/go-omni/middleware" ) func TestAccessLogReportsCommittedStatus(t *testing.T) { for _, tc := range []struct { name string handler httpx.Handler status int }{ {"unwritten error", func(c *httpx.Context) error { return apierrors.NotFound("MISSING", "missing") }, 404}, {"encoding error", func(c *httpx.Context) error { return c.OK(make(chan int)) }, 500}, {"committed error", func(c *httpx.Context) error { _ = c.Created("saved"); return errors.New("later error") }, 201}, {"committed panic", func(c *httpx.Context) error { _ = c.Accepted("saved"); panic("later panic") }, 202}, } { t.Run(tc.name, func(t *testing.T) { var output bytes.Buffer logger, err := logx.New(logx.Config{Format: "json", Writer: &output}) if err != nil { t.Fatal(err) } logx.SetDefault(logger) defer logx.SetDefault(nil) req := httptest.NewRequest("GET", "/users/42", nil) req.Header.Set("X-Request-ID", "logRequest") req = req.WithContext(httpx.WithRoutePattern(req.Context(), "/users/:id")) w := httptest.NewRecorder() ctx := httpx.NewContext(req, w, nil) chain := middleware.RequestID("X-Request-ID")(middleware.AccessLog()(middleware.Recovery()(tc.handler))) if err := chain(ctx); err != nil { ctx.WriteError(err) } var entry struct { Status int Route string RequestID string `json:"requestId"` } if err := json.Unmarshal(output.Bytes(), &entry); err != nil { t.Fatal(err) } if entry.Status != tc.status || w.Code != tc.status || entry.Route != "/users/:id" || entry.RequestID != "logRequest" { t.Fatalf("log=%s response=%d; expected status %d and request metadata", &output, w.Code, tc.status) } }) } }