github.com/gitbundle/modules@v0.0.0-20231025071548-85b91c5c3b01/httpcache/httpcache_test.go (about) 1 // Copyright 2023 The GitBundle Inc. All rights reserved. 2 // Copyright 2017 The Gitea Authors. All rights reserved. 3 // Use of this source code is governed by a MIT-style 4 // license that can be found in the LICENSE file. 5 6 package httpcache 7 8 import ( 9 "net/http" 10 "net/http/httptest" 11 "os" 12 "strings" 13 "testing" 14 "time" 15 16 "github.com/stretchr/testify/assert" 17 ) 18 19 type mockFileInfo struct{} 20 21 func (m mockFileInfo) Name() string { return "gitbundle.test" } 22 func (m mockFileInfo) Size() int64 { return int64(10) } 23 func (m mockFileInfo) Mode() os.FileMode { return os.ModePerm } 24 func (m mockFileInfo) ModTime() time.Time { return time.Time{} } 25 func (m mockFileInfo) IsDir() bool { return false } 26 func (m mockFileInfo) Sys() interface{} { return nil } 27 28 func countFormalHeaders(h http.Header) (c int) { 29 for k := range h { 30 // ignore our headers for internal usage 31 if strings.HasPrefix(k, "X-Gitea-") { 32 continue 33 } 34 c++ 35 } 36 return c 37 } 38 39 func TestHandleFileETagCache(t *testing.T) { 40 fi := mockFileInfo{} 41 etag := `"MTBnaXRlYS50ZXN0TW9uLCAwMSBKYW4gMDAwMSAwMDowMDowMCBHTVQ="` 42 43 t.Run("No_If-None-Match", func(t *testing.T) { 44 req := &http.Request{Header: make(http.Header)} 45 w := httptest.NewRecorder() 46 47 handled := HandleFileETagCache(req, w, fi) 48 49 assert.False(t, handled) 50 assert.Equal(t, 2, countFormalHeaders(w.Header())) 51 assert.Contains(t, w.Header(), "Cache-Control") 52 assert.Contains(t, w.Header(), "Etag") 53 assert.Equal(t, etag, w.Header().Get("Etag")) 54 }) 55 t.Run("Wrong_If-None-Match", func(t *testing.T) { 56 req := &http.Request{Header: make(http.Header)} 57 w := httptest.NewRecorder() 58 59 req.Header.Set("If-None-Match", `"wrong etag"`) 60 61 handled := HandleFileETagCache(req, w, fi) 62 63 assert.False(t, handled) 64 assert.Equal(t, 2, countFormalHeaders(w.Header())) 65 assert.Contains(t, w.Header(), "Cache-Control") 66 assert.Contains(t, w.Header(), "Etag") 67 assert.Equal(t, etag, w.Header().Get("Etag")) 68 }) 69 t.Run("Correct_If-None-Match", func(t *testing.T) { 70 req := &http.Request{Header: make(http.Header)} 71 w := httptest.NewRecorder() 72 73 req.Header.Set("If-None-Match", etag) 74 75 handled := HandleFileETagCache(req, w, fi) 76 77 assert.True(t, handled) 78 assert.Equal(t, 1, countFormalHeaders(w.Header())) 79 assert.Contains(t, w.Header(), "Etag") 80 assert.Equal(t, etag, w.Header().Get("Etag")) 81 assert.Equal(t, http.StatusNotModified, w.Code) 82 }) 83 } 84 85 func TestHandleGenericETagCache(t *testing.T) { 86 etag := `"test"` 87 88 t.Run("No_If-None-Match", func(t *testing.T) { 89 req := &http.Request{Header: make(http.Header)} 90 w := httptest.NewRecorder() 91 92 handled := HandleGenericETagCache(req, w, etag) 93 94 assert.False(t, handled) 95 assert.Equal(t, 2, countFormalHeaders(w.Header())) 96 assert.Contains(t, w.Header(), "Cache-Control") 97 assert.Contains(t, w.Header(), "Etag") 98 assert.Equal(t, etag, w.Header().Get("Etag")) 99 }) 100 t.Run("Wrong_If-None-Match", func(t *testing.T) { 101 req := &http.Request{Header: make(http.Header)} 102 w := httptest.NewRecorder() 103 104 req.Header.Set("If-None-Match", `"wrong etag"`) 105 106 handled := HandleGenericETagCache(req, w, etag) 107 108 assert.False(t, handled) 109 assert.Equal(t, 2, countFormalHeaders(w.Header())) 110 assert.Contains(t, w.Header(), "Cache-Control") 111 assert.Contains(t, w.Header(), "Etag") 112 assert.Equal(t, etag, w.Header().Get("Etag")) 113 }) 114 t.Run("Correct_If-None-Match", func(t *testing.T) { 115 req := &http.Request{Header: make(http.Header)} 116 w := httptest.NewRecorder() 117 118 req.Header.Set("If-None-Match", etag) 119 120 handled := HandleGenericETagCache(req, w, etag) 121 122 assert.True(t, handled) 123 assert.Equal(t, 1, countFormalHeaders(w.Header())) 124 assert.Contains(t, w.Header(), "Etag") 125 assert.Equal(t, etag, w.Header().Get("Etag")) 126 assert.Equal(t, http.StatusNotModified, w.Code) 127 }) 128 t.Run("Multiple_Wrong_If-None-Match", func(t *testing.T) { 129 req := &http.Request{Header: make(http.Header)} 130 w := httptest.NewRecorder() 131 132 req.Header.Set("If-None-Match", `"wrong etag", "wrong etag "`) 133 134 handled := HandleGenericETagCache(req, w, etag) 135 136 assert.False(t, handled) 137 assert.Equal(t, 2, countFormalHeaders(w.Header())) 138 assert.Contains(t, w.Header(), "Cache-Control") 139 assert.Contains(t, w.Header(), "Etag") 140 assert.Equal(t, etag, w.Header().Get("Etag")) 141 }) 142 t.Run("Multiple_Correct_If-None-Match", func(t *testing.T) { 143 req := &http.Request{Header: make(http.Header)} 144 w := httptest.NewRecorder() 145 146 req.Header.Set("If-None-Match", `"wrong etag", `+etag) 147 148 handled := HandleGenericETagCache(req, w, etag) 149 150 assert.True(t, handled) 151 assert.Equal(t, 1, countFormalHeaders(w.Header())) 152 assert.Contains(t, w.Header(), "Etag") 153 assert.Equal(t, etag, w.Header().Get("Etag")) 154 assert.Equal(t, http.StatusNotModified, w.Code) 155 }) 156 }