1 package middleware
2
3 import (
4 "bytes"
5 "fmt"
6 "net/http"
7 "net/http/httptest"
8 "testing"
9
10 "edge-infra.dev/pkg/edge/api/middleware"
11 "edge-infra.dev/pkg/lib/fog"
12
13 "github.com/gin-contrib/requestid"
14 "github.com/gin-gonic/gin"
15 "github.com/stretchr/testify/assert"
16 )
17
18 func TestSetLoggerInContext(t *testing.T) {
19 r := httptest.NewRecorder()
20 buf := new(bytes.Buffer)
21 router := createTestRouter(r, buf)
22
23 req := httptest.NewRequest(http.MethodGet, "/", bytes.NewBuffer([]byte{}))
24 correlationID := "correlationID"
25 req.Header.Set(CorrelationIDKey, correlationID)
26
27 var operationID string
28 router.Any("/", func(ctx *gin.Context) {
29 operationID = fog.OperationID(ctx.Request.Context())
30 l := fog.FromContext(ctx)
31 l.Info("test")
32 })
33 router.ServeHTTP(r, req)
34
35 output := buf.String()
36 assert.Contains(t, output, fmt.Sprintf(`"%s":"%s"`, correlationIDLabel, correlationID))
37 assert.Contains(t, output, fmt.Sprintf(`"%s":{"%s":"%s"}`, fog.OperationKey, "id", operationID))
38 }
39
40 func TestRequestFinishedLog(t *testing.T) {
41 tests := map[string]struct {
42 status int
43 exp string
44 }{
45 "200": {
46 status: http.StatusOK,
47 exp: "true",
48 },
49 "300": {
50 status: http.StatusMultipleChoices,
51 exp: "true",
52 },
53 "400": {
54 status: http.StatusBadRequest,
55 exp: "false",
56 },
57 "500": {
58 status: http.StatusInternalServerError,
59 exp: "false",
60 },
61 }
62
63 for name, tc := range tests {
64 t.Run(name, func(t *testing.T) {
65 r := httptest.NewRecorder()
66 buf := new(bytes.Buffer)
67 router := createTestRouter(r, buf)
68
69 req := httptest.NewRequest(http.MethodGet, "/", bytes.NewBuffer([]byte{}))
70
71 router.Any("/", func(ctx *gin.Context) {
72 ctx.Status(tc.status)
73 })
74 router.ServeHTTP(r, req)
75
76 output := buf.String()
77 assert.Contains(t, output, "Request received")
78 assert.Contains(t, output, "Request completed")
79 assert.Contains(t, output, fmt.Sprintf(`"isSuccessful":%s`, tc.exp))
80 })
81 }
82 }
83
84 func TestGetCorrelationID(t *testing.T) {
85 r := httptest.NewRecorder()
86 buf := new(bytes.Buffer)
87 router := createTestRouter(r, buf)
88
89 req := httptest.NewRequest(http.MethodGet, "/", bytes.NewBuffer([]byte{}))
90 expected := "correlationID"
91 req.Header.Set(CorrelationIDKey, expected)
92
93 var actual string
94 router.Any("/", func(ctx *gin.Context) {
95 actual = GetCorrelationID(ctx)
96 })
97 router.ServeHTTP(r, req)
98
99 assert.Equal(t, expected, actual)
100 }
101
102 func TestNoDuplicatedLogValues(t *testing.T) {
103 r := httptest.NewRecorder()
104 buf := new(bytes.Buffer)
105 router := createTestRouter(r, buf)
106
107 router.Any("/", func(ctx *gin.Context) {
108 log := fog.FromContext(ctx)
109 log.Info("test")
110 })
111
112 correlationIDs := []string{"123", "456", "789"}
113 for i, correlationID := range correlationIDs {
114 req := httptest.NewRequest(http.MethodGet, "/", bytes.NewBuffer([]byte{}))
115 req.Header.Set(CorrelationIDKey, correlationID)
116 router.ServeHTTP(r, req)
117
118 assert.Contains(t, buf.String(), fmt.Sprintf(`"%s":"%s"`, correlationIDLabel, correlationID))
119 for x := i - 1; x >= 0; x-- {
120 assert.NotContains(t, buf.String(), fmt.Sprintf(`"%s":"%s"`, correlationIDLabel, correlationIDs[x]))
121 }
122
123 buf.Reset()
124 }
125 }
126
127 func createTestRouter(r *httptest.ResponseRecorder, buf *bytes.Buffer) (router *gin.Engine) {
128 _, router = gin.CreateTestContext(r)
129 router.ContextWithFallback = true
130 router.Use(middleware.SetRequestContext())
131 router.Use(requestid.New(requestid.WithCustomHeaderStrKey(CorrelationIDKey)))
132 router.Use(SetLoggerInContext(fog.New(fog.To(buf))))
133 router.Use(RequestBookendLogs())
134 return router
135 }
136
View as plain text