github.com/google/martian/v3@v3.3.3/cookie/cookie_filter_test.go (about) 1 // Copyright 2017 Google Inc. All rights reserved. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package cookie 16 17 import ( 18 "net/http" 19 "testing" 20 21 "github.com/google/martian/v3/filter" 22 _ "github.com/google/martian/v3/header" 23 "github.com/google/martian/v3/martiantest" 24 "github.com/google/martian/v3/parse" 25 "github.com/google/martian/v3/proxyutil" 26 ) 27 28 func TestFilterFromJSON(t *testing.T) { 29 msg := []byte(`{ 30 "cookie.Filter": { 31 "scope": ["request", "response"], 32 "name": "martian-cookie", 33 "value": "true", 34 "modifier": { 35 "header.Modifier" : { 36 "scope": ["request", "response"], 37 "name": "Martian-Testing", 38 "value": "true" 39 } 40 }, 41 "else": { 42 "header.Modifier" : { 43 "scope": ["request", "response"], 44 "name": "Martian-Testing", 45 "value": "false" 46 } 47 } 48 } 49 }`) 50 51 r, err := parse.FromJSON(msg) 52 if err != nil { 53 t.Fatalf("parse.FromJSON(): got %v, want no error", err) 54 } 55 reqmod := r.RequestModifier() 56 if reqmod == nil { 57 t.Fatal("reqmod: got nil, want not nil") 58 } 59 60 resmod := r.ResponseModifier() 61 if resmod == nil { 62 t.Fatal("resmod: got nil, want not nil") 63 } 64 65 for _, tc := range []struct { 66 name string 67 wantMatch bool 68 cookie *http.Cookie 69 }{ 70 { 71 name: "matching name and value", 72 wantMatch: true, 73 cookie: &http.Cookie{ 74 Name: "martian-cookie", 75 Value: "true", 76 }, 77 }, 78 { 79 name: "matching name with mismatched value", 80 wantMatch: false, 81 cookie: &http.Cookie{ 82 Name: "martian-cookie", 83 Value: "false", 84 }, 85 }, 86 { 87 name: "missing cookie", 88 wantMatch: false, 89 }, 90 } { 91 req, err := http.NewRequest("GET", "http://example.com", nil) 92 if err != nil { 93 t.Errorf("%s: http.NewRequest(): got %v, want no error", tc.name, err) 94 continue 95 } 96 if tc.cookie != nil { 97 req.AddCookie(tc.cookie) 98 } 99 100 if err := reqmod.ModifyRequest(req); err != nil { 101 t.Errorf("%s: ModifyRequest(): got %v, want no error", tc.name, err) 102 continue 103 } 104 105 want := "false" 106 if tc.wantMatch { 107 want = "true" 108 } 109 if got := req.Header.Get("Martian-Testing"); got != want { 110 t.Errorf("%s: req.Header.Get(%q): got %q, want %q", "Martian-Testing", tc.name, got, want) 111 continue 112 } 113 114 res := proxyutil.NewResponse(200, nil, req) 115 if tc.cookie != nil { 116 c := &http.Cookie{Name: tc.cookie.Name, Value: tc.cookie.Value} 117 res.Header.Add("Set-Cookie", c.String()) 118 } 119 120 if err := resmod.ModifyResponse(res); err != nil { 121 t.Fatalf("ModifyResponse(): got %v, want no error", err) 122 } 123 124 if got := res.Header.Get("Martian-Testing"); got != want { 125 t.Fatalf("res.Header.Get(%q): got %q, want %q", "Martian-Testing", got, want) 126 } 127 128 } 129 } 130 131 func TestFilterFromJSONWithoutElse(t *testing.T) { 132 msg := []byte(`{ 133 "cookie.Filter": { 134 "scope": ["request", "response"], 135 "name": "martian-cookie", 136 "value": "true", 137 "modifier": { 138 "header.Modifier" : { 139 "scope": ["request", "response"], 140 "name": "Martian-Testing", 141 "value": "true" 142 } 143 } 144 } 145 }`) 146 _, err := parse.FromJSON(msg) 147 if err != nil { 148 t.Fatalf("parse.FromJSON(): got %v, want no error", err) 149 } 150 } 151 152 func TestRequestWhenTrueCondition(t *testing.T) { 153 cm := NewMatcher(&http.Cookie{Name: "Martian-Testing", Value: "true"}) 154 155 tt := []struct { 156 name string 157 value string 158 want bool 159 }{ 160 { 161 name: "Martian-Production", 162 value: "true", 163 want: false, 164 }, 165 { 166 name: "Martian-Testing", 167 value: "true", 168 want: true, 169 }, 170 } 171 172 for i, tc := range tt { 173 tm := martiantest.NewModifier() 174 175 f := filter.New() 176 f.SetRequestCondition(cm) 177 f.RequestWhenTrue(tm) 178 179 req, err := http.NewRequest("GET", "/", nil) 180 if err != nil { 181 t.Fatalf("http.NewRequest(): got %v, want no error", err) 182 } 183 184 req.AddCookie(&http.Cookie{Name: tc.name, Value: tc.value}) 185 186 if err := f.ModifyRequest(req); err != nil { 187 t.Fatalf("%d. ModifyRequest(): got %v, want no error", i, err) 188 } 189 190 if tm.RequestModified() != tc.want { 191 t.Errorf("%d. tm.RequestModified(): got %t, want %t", i, tm.RequestModified(), tc.want) 192 } 193 } 194 } 195 196 func TestRequestWhenFalse(t *testing.T) { 197 cm := NewMatcher(&http.Cookie{Name: "Martian-Testing", Value: "true"}) 198 tt := []struct { 199 name string 200 value string 201 want bool 202 }{ 203 { 204 name: "Martian-Production", 205 value: "true", 206 want: true, 207 }, 208 { 209 name: "Martian-Testing", 210 value: "true", 211 want: false, 212 }, 213 } 214 215 for i, tc := range tt { 216 tm := martiantest.NewModifier() 217 218 f := filter.New() 219 f.SetRequestCondition(cm) 220 f.RequestWhenFalse(tm) 221 222 req, err := http.NewRequest("GET", "/", nil) 223 if err != nil { 224 t.Fatalf("http.NewRequest(): got %v, want no error", err) 225 } 226 227 req.AddCookie(&http.Cookie{Name: tc.name, Value: tc.value}) 228 229 if err := f.ModifyRequest(req); err != nil { 230 t.Fatalf("%d. ModifyRequest(): got %v, want no error", i, err) 231 } 232 233 if tm.RequestModified() != tc.want { 234 t.Errorf("%d. tm.RequestModified(): got %t, want %t", i, tm.RequestModified(), tc.want) 235 } 236 } 237 } 238 239 func TestResponseWhenTrue(t *testing.T) { 240 cm := NewMatcher(&http.Cookie{Name: "Martian-Testing", Value: "true"}) 241 242 tt := []struct { 243 name string 244 value string 245 want bool 246 }{ 247 { 248 name: "Martian-Production", 249 value: "true", 250 want: false, 251 }, 252 { 253 name: "Martian-Testing", 254 value: "true", 255 want: true, 256 }, 257 } 258 259 for i, tc := range tt { 260 tm := martiantest.NewModifier() 261 262 f := filter.New() 263 f.SetResponseCondition(cm) 264 f.ResponseWhenTrue(tm) 265 266 req, err := http.NewRequest("GET", "/", nil) 267 if err != nil { 268 t.Fatalf("http.NewRequest(): got %v, want no error", err) 269 } 270 271 res := proxyutil.NewResponse(200, nil, req) 272 273 c := &http.Cookie{Name: tc.name, Value: tc.value} 274 res.Header.Add("Set-Cookie", c.String()) 275 276 if err := f.ModifyResponse(res); err != nil { 277 t.Fatalf("%d. ModifyResponse(): got %v, want no error", i, err) 278 } 279 280 if tm.ResponseModified() != tc.want { 281 t.Errorf("%d. tm.ResponseModified(): got %t, want %t", i, tm.RequestModified(), tc.want) 282 } 283 } 284 } 285 286 func TestResponseWhenFalse(t *testing.T) { 287 cm := NewMatcher(&http.Cookie{Name: "Martian-Testing", Value: "true"}) 288 289 tt := []struct { 290 name string 291 value string 292 want bool 293 }{ 294 { 295 name: "Martian-Production", 296 value: "true", 297 want: true, 298 }, 299 { 300 name: "Martian-Testing", 301 value: "true", 302 want: false, 303 }, 304 } 305 306 for i, tc := range tt { 307 tm := martiantest.NewModifier() 308 309 f := filter.New() 310 f.SetResponseCondition(cm) 311 f.ResponseWhenFalse(tm) 312 313 req, err := http.NewRequest("GET", "/", nil) 314 if err != nil { 315 t.Fatalf("http.NewRequest(): got %v, want no error", err) 316 } 317 318 res := proxyutil.NewResponse(200, nil, req) 319 320 c := &http.Cookie{Name: tc.name, Value: tc.value} 321 res.Header.Add("Set-Cookie", c.String()) 322 323 if err := f.ModifyResponse(res); err != nil { 324 t.Fatalf("%d. ModifyResponse(): got %v, want no error", i, err) 325 } 326 327 if tm.ResponseModified() != tc.want { 328 t.Errorf("%d. tm.ResponseModified(): got %t, want %t", i, tm.RequestModified(), tc.want) 329 } 330 } 331 }