github.com/massongit/reviewdog@v0.0.0-20240331071725-4a16675475a8/doghouse/server/cookieman/cookieman_test.go (about) 1 package cookieman 2 3 import ( 4 "encoding/base64" 5 "errors" 6 "fmt" 7 "net/http" 8 "net/http/httptest" 9 "testing" 10 "time" 11 ) 12 13 type fakeCipher struct { 14 Cipher 15 fakeEncrypt func(plaintext []byte) ([]byte, error) 16 fakeDecrypt func(ciphertext []byte) ([]byte, error) 17 } 18 19 func (f *fakeCipher) Encrypt(plaintext []byte) ([]byte, error) { 20 if f.fakeEncrypt != nil { 21 return f.fakeEncrypt(plaintext) 22 } 23 return plaintext, nil 24 } 25 26 func (f *fakeCipher) Decrypt(ciphertext []byte) ([]byte, error) { 27 if f.fakeDecrypt != nil { 28 return f.fakeDecrypt(ciphertext) 29 } 30 return ciphertext, nil 31 } 32 33 func GetRequestWithCookie(w *httptest.ResponseRecorder) *http.Request { 34 response := w.Result() 35 defer response.Body.Close() 36 req, _ := http.NewRequest("", "", nil) 37 for _, c := range response.Cookies() { 38 req.AddCookie(c) 39 } 40 return req 41 } 42 43 func TestCookieStore_Set_Get(t *testing.T) { 44 opt := CookieOption{} 45 cookieman := New(&fakeCipher{}, opt) 46 name := "vim" 47 value := "vim vim vim" 48 w := httptest.NewRecorder() 49 50 vimStore := cookieman.NewCookieStore(name, nil) 51 52 if vimStore.Name() != name { 53 t.Errorf("CookieStore.Name() = %q, want %q", vimStore.Name(), name) 54 } 55 56 if err := vimStore.Set(w, []byte(value)); err != nil { 57 t.Error(err) 58 } 59 60 response := w.Result() 61 defer response.Body.Close() 62 gotSetCookie := response.Header.Get("Set-Cookie") 63 wantSetCookie := fmt.Sprintf("%s=%s", name, base64.URLEncoding.EncodeToString([]byte(value))) 64 if gotSetCookie != wantSetCookie { 65 t.Errorf("CookieStore.Get: Set-Cookie value: got %q, want %q", gotSetCookie, wantSetCookie) 66 } 67 68 req := GetRequestWithCookie(w) 69 b, err := vimStore.Get(req) 70 if err != nil { 71 t.Fatal(err) 72 } 73 74 if got := string(b); got != value { 75 t.Errorf("CookieStore.Get: got %q, want %q", got, value) 76 } 77 } 78 79 func TestCookieStore_Set_encrypt_failure(t *testing.T) { 80 cipher := &fakeCipher{ 81 fakeEncrypt: func(plaintext []byte) ([]byte, error) { 82 return nil, errors.New("test encrypt failure") 83 }, 84 } 85 86 opt := CookieOption{} 87 cookieman := New(cipher, opt) 88 w := httptest.NewRecorder() 89 store := cookieman.NewCookieStore("n", nil) 90 if err := store.Set(w, []byte("v")); err == nil { 91 t.Error("got nil, but want error") 92 } 93 } 94 95 func TestCookieStore_Get_decrypt_failure(t *testing.T) { 96 cipher := &fakeCipher{ 97 fakeDecrypt: func(ciphertext []byte) ([]byte, error) { 98 return nil, errors.New("test decrypt failure") 99 }, 100 } 101 102 opt := CookieOption{} 103 cookieman := New(cipher, opt) 104 w := httptest.NewRecorder() 105 store := cookieman.NewCookieStore("n", nil) 106 if err := store.Set(w, []byte("v")); err != nil { 107 t.Error(err) 108 } 109 110 req := GetRequestWithCookie(w) 111 if _, err := store.Get(req); err == nil { 112 t.Error("got nil, but want error") 113 } 114 } 115 116 func TestCookieStore_Get_decode_base64_error(t *testing.T) { 117 cipher := &fakeCipher{} 118 opt := CookieOption{} 119 cookieman := New(cipher, opt) 120 w := httptest.NewRecorder() 121 store := cookieman.NewCookieStore("n", nil) 122 123 http.SetCookie(w, &http.Cookie{ 124 Name: "n", 125 Value: "zzz: non base64 encoding", 126 }) 127 128 req := GetRequestWithCookie(w) 129 if _, err := store.Get(req); err == nil { 130 t.Error("got nil, but want error") 131 } 132 } 133 134 func TestCookieStore_Get_not_found(t *testing.T) { 135 cipher := &fakeCipher{} 136 opt := CookieOption{} 137 cookieman := New(cipher, opt) 138 store := cookieman.NewCookieStore("n", nil) 139 req, _ := http.NewRequest("", "", nil) 140 if _, err := store.Get(req); err == nil { 141 t.Error("got nil, but want error") 142 } 143 } 144 145 func TestCookieStore_Clear(t *testing.T) { 146 opt := CookieOption{} 147 cookieman := New(&fakeCipher{}, opt) 148 name := "vim" 149 w := httptest.NewRecorder() 150 151 vimStore := cookieman.NewCookieStore(name, nil) 152 vimStore.Clear(w) 153 154 response := w.Result() 155 defer response.Body.Close() 156 157 if cookieLen := len(response.Cookies()); cookieLen != 1 { 158 t.Fatalf("got %d cookies, want 1 cookie", cookieLen) 159 } 160 cookie := response.Cookies()[0] 161 162 if cookie.Name != name { 163 t.Errorf("Cookie.Name = %q, want %q", cookie.Name, name) 164 } 165 if cookie.MaxAge != -1 { 166 t.Errorf("Cookie.MaxAge = %d, want -1", cookie.MaxAge) 167 } 168 } 169 170 func TestCookieOption(t *testing.T) { 171 defaultOpt := CookieOption{ 172 http.Cookie{ 173 Secure: false, 174 MaxAge: 30, 175 }, 176 } 177 cookieman := New(&fakeCipher{}, defaultOpt) 178 179 w := httptest.NewRecorder() 180 opt := &CookieOption{ 181 http.Cookie{ 182 Domain: "domain", 183 Expires: time.Now(), 184 HttpOnly: true, 185 MaxAge: 14, 186 Path: "/", 187 Secure: true, 188 }, 189 } 190 if err := cookieman.Set(w, "n", []byte(""), opt); err != nil { 191 t.Fatal(err) 192 } 193 194 if cookieLen := len(w.Result().Cookies()); cookieLen != 1 { 195 t.Fatalf("got %d cookies, want 1 cookie", cookieLen) 196 } 197 cookie := w.Result().Cookies()[0] 198 199 if cookie.Domain != opt.Domain { 200 t.Errorf("Cookie.Domain = %q, want %q", cookie.Domain, opt.Domain) 201 } 202 if cookie.Expires.Second() != opt.Expires.Second() { 203 t.Errorf("Cookie.Expires = %q, want %q", cookie.Expires, opt.Expires) 204 } 205 if cookie.HttpOnly != opt.HttpOnly { 206 t.Errorf("Cookie.HttpOnly = %v, want %v", cookie.HttpOnly, opt.HttpOnly) 207 } 208 if cookie.MaxAge != opt.MaxAge { 209 t.Errorf("Cookie.MaxAge = %v, want %v", cookie.MaxAge, opt.MaxAge) 210 } 211 if cookie.Path != opt.Path { 212 t.Errorf("Cookie.Path = %q, want %q", cookie.Path, opt.Path) 213 } 214 if cookie.Secure != opt.Secure { 215 t.Errorf("Cookie.Secure = %v, want %v", cookie.Secure, opt.Secure) 216 } 217 }