github.com/Tyktechnologies/tyk@v2.9.5+incompatible/gateway/mw_redis_cache_test.go (about) 1 package gateway 2 3 import ( 4 "crypto/md5" 5 "encoding/hex" 6 "hash" 7 "net/http" 8 "strings" 9 "testing" 10 11 "github.com/TykTechnologies/tyk/apidef" 12 "github.com/TykTechnologies/tyk/config" 13 "github.com/TykTechnologies/tyk/test" 14 ) 15 16 func TestRedisCacheMiddleware_WithCompressedResponse(t *testing.T) { 17 const path = "/compressed" 18 19 globalConf := config.Global() 20 globalConf.AnalyticsConfig.EnableDetailedRecording = true 21 config.SetGlobal(globalConf) 22 23 ts := StartTest() 24 defer ts.Close() 25 26 createAPI := func(withCache bool) { 27 BuildAndLoadAPI(func(spec *APISpec) { 28 spec.Proxy.ListenPath = "/" 29 spec.CacheOptions.CacheTimeout = 60 30 spec.CacheOptions.EnableCache = withCache 31 UpdateAPIVersion(spec, "v1", func(v *apidef.VersionInfo) { 32 v.ExtendedPaths.Cached = []string{path} 33 }) 34 }) 35 } 36 37 t.Run("without cache", func(t *testing.T) { 38 createAPI(false) 39 40 ts.Run(t, []test.TestCase{ 41 {Path: path, Code: 200, BodyMatch: "This is a compressed response"}, 42 {Path: path, Code: 200, BodyMatch: "This is a compressed response"}, 43 }...) 44 }) 45 46 t.Run("with cache", func(t *testing.T) { 47 createAPI(true) 48 49 ts.Run(t, []test.TestCase{ 50 {Path: path, Code: 200, BodyMatch: "This is a compressed response"}, 51 {Path: path, Code: 200, BodyMatch: "This is a compressed response"}, 52 }...) 53 }) 54 55 } 56 57 func Test_isSafeMethod(t *testing.T) { 58 tests := []struct { 59 name string 60 method string 61 expected bool 62 }{ 63 {"Test if Get is a safe method", http.MethodGet, true}, 64 {"Test if Head is a safe method", http.MethodHead, true}, 65 {"Test if Options is a safe method", http.MethodOptions, true}, 66 {"Test if Post is a safe method", http.MethodPost, false}, 67 {"Test if Put is a safe method", http.MethodPut, false}, 68 {"Test if Patch is a safe method", http.MethodPatch, false}, 69 {"Test if Delete is a safe method", http.MethodDelete, false}, 70 {"Test if Connect is a safe method", http.MethodConnect, false}, 71 {"Test if Trace is a safe method", http.MethodTrace, false}, 72 } 73 for _, tt := range tests { 74 t.Run(tt.name, func(t *testing.T) { 75 if got := isSafeMethod(tt.method); got != tt.expected { 76 t.Errorf("isSafeMethod() = %v, want %v", got, tt.expected) 77 } 78 }) 79 } 80 } 81 82 func Test_isBodyHashRequired(t *testing.T) { 83 requestPutNoBody, _ := http.NewRequest(http.MethodPut, "http://test.com", nil) 84 requestGetNoBody, _ := http.NewRequest(http.MethodGet, "http://test.com", nil) 85 requestPutWithBody, _ := http.NewRequest(http.MethodPut, "http://test.com", strings.NewReader("some-body")) 86 requestPostWithBody, _ := http.NewRequest(http.MethodPost, "http://test.com", strings.NewReader("some-body")) 87 requestPatchWithBody, _ := http.NewRequest(http.MethodPatch, "http://test.com", strings.NewReader("some-body")) 88 requestGetWithBody, _ := http.NewRequest(http.MethodGet, "http://test.com", strings.NewReader("some-body")) 89 type args struct { 90 request *http.Request 91 } 92 tests := []struct { 93 name string 94 args args 95 expected bool 96 }{ 97 {"Put no body", args{requestPutNoBody}, false}, 98 {"Get no body", args{requestGetNoBody}, false}, 99 {"Get with body", args{requestGetWithBody}, false}, 100 {"Put with body", args{requestPutWithBody}, true}, 101 {"Post with body", args{requestPostWithBody}, true}, 102 {"Patch with body", args{requestPatchWithBody}, true}, 103 } 104 for _, tt := range tests { 105 t.Run(tt.name, func(t *testing.T) { 106 if got := isBodyHashRequired(tt.args.request); got != tt.expected { 107 t.Errorf("isBodyHashRequired() = %v, expected %v", got, tt.expected) 108 } 109 }) 110 } 111 } 112 113 func Test_addBodyHash(t *testing.T) { 114 requestPutNoBody, _ := http.NewRequest(http.MethodPut, "http://test.com", nil) 115 requestPostWithBody, _ := http.NewRequest(http.MethodPost, "http://test.com", strings.NewReader("some-body")) 116 requestPatchWithBody, _ := http.NewRequest(http.MethodPatch, "http://test.com", strings.NewReader("{\"id\":\"1\",\"name\":\"test\"}")) 117 type args struct { 118 req *http.Request 119 regex string 120 h hash.Hash 121 } 122 tests := []struct { 123 name string 124 args args 125 expected string 126 }{ 127 {"No body", args{requestPutNoBody, ".*", md5.New()}, "d41d8cd98f00b204e9800998ecf8427e"}, 128 {"Hash the entire body by regexp", args{requestPostWithBody, ".*", md5.New()}, "2838333d94b3b7114a3cabdf4e4fadf4"}, 129 {"Hash the entire body no regexp", args{requestPostWithBody, "", md5.New()}, "2838333d94b3b7114a3cabdf4e4fadf4"}, 130 {"Hash by id regexp", args{requestPatchWithBody, "\"id\":[^,]*", md5.New()}, "abe7ef0275f752342a4bf370afb0be2b"}, 131 } 132 for _, tt := range tests { 133 t.Run(tt.name, func(t *testing.T) { 134 if addBodyHash(tt.args.req, tt.args.regex, tt.args.h); hex.EncodeToString(tt.args.h.Sum(nil)) != tt.expected { 135 t.Errorf("addBodyHash() recieved = %v, expected %v", hex.EncodeToString(tt.args.h.Sum(nil)), tt.expected) 136 } 137 }) 138 } 139 }