github.com/yandex/pandora@v0.5.32/components/providers/scenario/http/postprocessor/var_header_test.go (about) 1 package postprocessor 2 3 import ( 4 "fmt" 5 "net/http" 6 "testing" 7 8 "github.com/stretchr/testify/assert" 9 ) 10 11 func TestVarHeaderPostprocessor_Process(t *testing.T) { 12 tests := []struct { 13 name string 14 mappings map[string]string 15 respHeaders map[string]string 16 wantMap map[string]any 17 wantErr bool 18 }{ 19 { 20 name: "No Headers", 21 mappings: map[string]string{ 22 "key1": "header1", 23 "key2": "header2", 24 }, 25 respHeaders: map[string]string{}, 26 wantMap: map[string]any{}, 27 }, 28 { 29 name: "No Fields", 30 mappings: map[string]string{}, 31 respHeaders: map[string]string{ 32 "key1": "header1", 33 "key2": "header2"}, 34 wantMap: nil, 35 }, 36 { 37 name: "Error in Fields", 38 mappings: map[string]string{ 39 "key1": "header1||", 40 }, 41 respHeaders: map[string]string{}, 42 wantMap: map[string]any{}, 43 wantErr: true, 44 }, 45 { 46 name: "Headers Exist", 47 mappings: map[string]string{ 48 "key1": "header1", 49 "key2": "header2|lower", 50 "key3": "header3|upper", 51 "key4": "header4|substr(1,3)", 52 "key5": "header5|lower|replace(s,x)|substr(1,3)", 53 "auth": "Authorization|lower|replace(=,)|substr(6)", 54 }, 55 respHeaders: map[string]string{ 56 "header1": "Value1", 57 "header2": "Value2", 58 "header3": "Value3", 59 "header4": "Value4", 60 "header5": "aSdFgHjKl", 61 "Authorization": "Basic Ym9zY236Ym9zY28=", 62 }, 63 wantMap: map[string]any{ 64 "key1": "Value1", 65 "key2": "value2", 66 "key3": "VALUE3", 67 "key4": "al", 68 "key5": "xd", 69 "auth": "ym9zy236ym9zy28", 70 }, 71 }, 72 } 73 74 for _, tt := range tests { 75 t.Run(tt.name, func(t *testing.T) { 76 p := &VarHeaderPostprocessor{Mapping: tt.mappings} 77 resp := &http.Response{ 78 Header: make(http.Header), 79 } 80 for k, v := range tt.respHeaders { 81 resp.Header.Set(k, v) 82 } 83 84 reqMap, err := p.Process(resp, nil) 85 if tt.wantErr { 86 assert.Error(t, err) 87 return 88 } 89 assert.NoError(t, err) 90 assert.Equal(t, tt.wantMap, reqMap) 91 }) 92 } 93 } 94 95 func TestVarHeaderPostprocessor_ParseValue(t *testing.T) { 96 tests := []struct { 97 name string 98 input string 99 wantVal string 100 wantValAfterModifier string 101 wantErr error 102 }{ 103 { 104 name: "No Modifier", 105 input: "hello", 106 wantVal: "hello", 107 wantValAfterModifier: "hello", 108 wantErr: nil, 109 }, 110 { 111 name: "Lowercase Modifier", 112 input: "fOOt|lower", 113 wantVal: "fOOt", 114 wantValAfterModifier: "foot", 115 wantErr: nil, 116 }, 117 { 118 name: "Uppercase Modifier", 119 input: "bar|upper", 120 wantVal: "bar", 121 wantValAfterModifier: "BAR", 122 wantErr: nil, 123 }, 124 { 125 name: "Substring Modifier", 126 input: "asdfghjkl|substr(1,3)", 127 wantVal: "asdfghjkl", 128 wantValAfterModifier: "sd", 129 wantErr: nil, 130 }, 131 { 132 name: "Multiple Modifiers", 133 input: "aSdFgHjKl|lower|replace(s,x)|substr(1,3)", 134 wantVal: "aSdFgHjKl", 135 wantValAfterModifier: "xd", 136 wantErr: nil, 137 }, 138 { 139 name: "Multiple Modifiers 2", 140 input: "aPPliCation-JSONbro|lower|replace(-, /)|substr(0, 16)", 141 wantVal: "aPPliCation-JSONbro", 142 wantValAfterModifier: "application/json", 143 wantErr: nil, 144 }, 145 { 146 name: "Invalid Modifier", 147 input: "invalid|unknown", 148 wantVal: "", // The method should return an empty string when the modifier is unknown. 149 wantValAfterModifier: "", 150 wantErr: fmt.Errorf("failed to parse modifier unknown: unknown modifier unknown"), 151 }, 152 { 153 name: "Invalid Modifier Arguments", 154 input: "invalid|substr(abc)", 155 wantVal: "", // The method should return an empty string when the modifier arguments are invalid. 156 wantValAfterModifier: "", 157 wantErr: fmt.Errorf("failed to parse modifier substr(abc): substr modifier requires integer as first argument, got abc"), 158 }, 159 } 160 161 for _, tt := range tests { 162 t.Run(tt.name, func(t *testing.T) { 163 p := &VarHeaderPostprocessor{} 164 value, modifier, err := p.parseValue(tt.input) 165 if err != nil { 166 assert.EqualError(t, err, tt.wantErr.Error()) 167 return 168 } 169 assert.NoError(t, err) 170 171 assert.Equal(t, tt.wantVal, value) 172 173 gotModifierVal := modifier(value) 174 assert.Equal(t, tt.wantValAfterModifier, gotModifierVal) 175 176 }) 177 } 178 } 179 180 func TestVarHeaderPostprocessor_ParseModifier(t *testing.T) { 181 p := &VarHeaderPostprocessor{} 182 183 tests := []struct { 184 name string 185 input string 186 value string 187 want string 188 wantErr error 189 }{ 190 { 191 name: "Lowercase Modifier", 192 input: "lower", 193 value: "HELLO", 194 want: "hello", 195 wantErr: nil, 196 }, 197 { 198 name: "Uppercase Modifier", 199 input: "upper", 200 value: "world", 201 want: "WORLD", 202 wantErr: nil, 203 }, 204 { 205 name: "Substring Modifier - Normal Case", 206 input: "substr(1,4)", 207 value: "abcdefgh", 208 want: "bcd", 209 wantErr: nil, 210 }, 211 { 212 name: "Substring Modifier - Start Index Out of Range (Negative)", 213 input: "substr(-2,4)", 214 value: "abcdefgh", 215 want: "ef", 216 wantErr: nil, 217 }, 218 { 219 name: "Substring Modifier - Start Index Greater Than End Index", 220 input: "substr(5,3)", 221 value: "abcdefgh", 222 want: "de", 223 wantErr: nil, 224 }, 225 { 226 name: "Substring Modifier - End Index Beyond Length", 227 input: "substr(2,100)", 228 value: "abcdefgh", 229 want: "cdefgh", // End index is beyond the length of the input value, so the modifier should return the substring from index 2 to the end. 230 wantErr: nil, 231 }, 232 { 233 name: "Replace Modifier", 234 input: "replace(a,x)", 235 value: "banana", 236 want: "bxnxnx", 237 wantErr: nil, 238 }, 239 { 240 name: "Invalid Modifier", 241 input: "invalid", 242 value: "test", 243 want: "", // The modFunc will be nil, so want should be an empty string. 244 wantErr: fmt.Errorf("unknown modifier invalid"), 245 }, 246 { 247 name: "Substring Modifier with Invalid Arguments", 248 input: "substr(2)", 249 value: "abc", 250 want: "c", 251 wantErr: nil, 252 }, 253 { 254 name: "Replace Modifier with Invalid Arguments", 255 input: "replace(x)", 256 value: "abc", 257 want: "", // The modFunc will be nil, so want should be an empty string. 258 wantErr: fmt.Errorf("replace modifier requires 2 arguments"), 259 }, 260 } 261 262 for _, tt := range tests { 263 t.Run(tt.name, func(t *testing.T) { 264 modFunc, err := p.parseModifier(tt.input) 265 266 // If there is an error, modFunc should be nil, and the result should be an empty string. 267 if err != nil { 268 assert.Nil(t, modFunc) 269 assert.EqualError(t, err, tt.wantErr.Error()) 270 return 271 } 272 273 // If there is no error, apply the modFunc and check the result. 274 res := modFunc(tt.value) 275 assert.Equal(t, tt.want, res) 276 assert.NoError(t, err) 277 }) 278 } 279 } 280 281 func TestVarHeaderPostprocessor_Substr(t *testing.T) { 282 tests := []struct { 283 name string 284 args []string 285 value string 286 want string 287 wantErr error 288 }{ 289 { 290 name: "Substring Modifier - Normal Case", 291 args: []string{"1", "4"}, 292 value: "abcdefgh", 293 want: "bcd", 294 wantErr: nil, 295 }, 296 { 297 name: "Substring Modifier - Start Index Out of Range (Negative)", 298 args: []string{"-2", "4"}, 299 value: "abcdefgh", 300 want: "ef", // Start index is negative, so it should count from the end of the string. 301 wantErr: nil, 302 }, 303 { 304 name: "Substring Modifier - End Index Out of Range (Negative)", 305 args: []string{"1", "-2"}, 306 value: "abcdefgh", 307 want: "bcdef", // End index is negative, so it should count from the end of the string. 308 wantErr: nil, 309 }, 310 { 311 name: "Substring Modifier - Start Index Greater Than End Index", 312 args: []string{"5", "3"}, 313 value: "abcdefgh", 314 want: "de", // Start index is greater than end index, so the modifier should return the substring from index 3 to 5. 315 wantErr: nil, 316 }, 317 { 318 name: "Substring Modifier - End Index Beyond Length", 319 args: []string{"2", "100"}, 320 value: "abcdefgh", 321 want: "cdefgh", // End index is beyond the length of the input value, so the modifier should return the substring from index 2 to the end. 322 wantErr: nil, 323 }, 324 { 325 name: "Substring Modifier with Invalid Arguments", 326 args: []string{"2"}, 327 value: "abc", 328 want: "c", 329 wantErr: nil, 330 }, 331 { 332 name: "Substring Modifier with Empty Arguments", 333 args: []string{}, 334 value: "abc", 335 want: "", // The modFunc will be nil, so want should be an empty string. 336 wantErr: fmt.Errorf("substr modifier requires one or two arguments"), 337 }, 338 { 339 name: "Substring Modifier with Non-Integer Arguments", 340 args: []string{"abc", "xyz"}, 341 value: "abc", 342 want: "", // The modFunc will be nil, so want should be an empty string. 343 wantErr: fmt.Errorf("substr modifier requires integer as first argument, got abc"), 344 }, 345 { 346 name: "Substring Modifier with Non-Integer second Argument", 347 args: []string{"1", "xyz"}, 348 value: "abc", 349 want: "", // The modFunc will be nil, so want should be an empty string. 350 wantErr: fmt.Errorf("substr modifier requires integer as second argument, got xyz"), 351 }, 352 } 353 354 for _, tt := range tests { 355 t.Run(tt.name, func(t *testing.T) { 356 p := &VarHeaderPostprocessor{} 357 modFunc, err := p.substr(tt.args) 358 if err != nil { 359 assert.Nil(t, modFunc) 360 assert.EqualError(t, err, tt.wantErr.Error()) 361 return 362 } 363 assert.NoError(t, err) 364 assert.Equal(t, tt.want, modFunc(tt.value)) 365 }) 366 } 367 }