github.com/yandex/pandora@v0.5.32/components/providers/scenario/http/templater/templater_text_test.go (about) 1 package templater 2 3 import ( 4 "strconv" 5 "testing" 6 7 "github.com/stretchr/testify/assert" 8 "github.com/stretchr/testify/require" 9 gun "github.com/yandex/pandora/components/guns/http_scenario" 10 ) 11 12 func TestTextTemplater_Apply(t *testing.T) { 13 tests := []struct { 14 name string 15 scenarioName string 16 stepName string 17 parts *gun.RequestParts 18 vs map[string]interface{} 19 expectedURL string 20 expectedHeaders map[string]string 21 expectedBody string 22 expectError bool 23 }{ 24 { 25 name: "Test Scenario 1", 26 scenarioName: "TestScenario", 27 stepName: "TestStep", 28 parts: &gun.RequestParts{ 29 URL: "http://example.com/{{.endpoint}}", 30 Headers: map[string]string{ 31 "Authorization": "Bearer {{.token}}", 32 "Content-Type": "application/json", 33 }, 34 Body: []byte(`{"name": "{{.name}}", "age": {{.age}}}`), 35 }, 36 vs: map[string]interface{}{ 37 "endpoint": "users", 38 "token": "abc123", 39 "name": "John", 40 "age": 30, 41 }, 42 expectedURL: "http://example.com/users", 43 expectedHeaders: map[string]string{ 44 "Authorization": "Bearer abc123", 45 "Content-Type": "application/json", 46 }, 47 expectedBody: `{"name": "John", "age": 30}`, 48 expectError: false, 49 }, 50 { 51 name: "Test Scenario 2 (Invalid Template)", 52 scenarioName: "TestScenario", 53 stepName: "TestStep", 54 parts: &gun.RequestParts{ 55 URL: "http://example.com/{{.endpoint", 56 }, 57 vs: map[string]interface{}{ 58 "endpoint": "users", 59 }, 60 expectedURL: "", 61 expectedHeaders: nil, 62 expectedBody: "", 63 expectError: true, 64 }, 65 { 66 name: "Test Scenario 3 (Empty RequestParts)", 67 scenarioName: "EmptyScenario", 68 stepName: "EmptyStep", 69 parts: &gun.RequestParts{}, 70 vs: map[string]interface{}{}, 71 expectedURL: "", 72 expectedHeaders: nil, 73 expectedBody: "", 74 expectError: false, 75 }, 76 { 77 name: "Test Scenario 4 (No Variables)", 78 scenarioName: "NoVarsScenario", 79 stepName: "NoVarsStep", 80 parts: &gun.RequestParts{ 81 URL: "http://example.com", 82 Headers: map[string]string{ 83 "Authorization": "Bearer abc123", 84 }, 85 Body: []byte(`{"name": "John", "age": 30}`), 86 }, 87 vs: map[string]interface{}{}, 88 expectedURL: "http://example.com", 89 expectedHeaders: map[string]string{ 90 "Authorization": "Bearer abc123", 91 }, 92 expectedBody: `{"name": "John", "age": 30}`, 93 expectError: false, 94 }, 95 { 96 name: "Test Scenario 5 (URL Only)", 97 scenarioName: "URLScenario", 98 stepName: "URLStep", 99 parts: &gun.RequestParts{ 100 URL: "http://example.com/{{.endpoint}}", 101 }, 102 vs: map[string]interface{}{ 103 "endpoint": "users", 104 }, 105 expectedURL: "http://example.com/users", 106 expectedHeaders: nil, 107 expectedBody: "", 108 expectError: false, 109 }, 110 { 111 name: "Test Scenario 6 (Headers Only)", 112 scenarioName: "HeaderScenario", 113 stepName: "HeaderStep", 114 parts: &gun.RequestParts{ 115 Headers: map[string]string{ 116 "Authorization": "Bearer {{.token}}", 117 "Content-Type": "application/json", 118 }, 119 }, 120 vs: map[string]interface{}{ 121 "token": "xyz456", 122 }, 123 expectedURL: "", 124 expectedHeaders: map[string]string{ 125 "Authorization": "Bearer xyz456", 126 "Content-Type": "application/json", 127 }, 128 expectedBody: "", 129 expectError: false, 130 }, 131 { 132 name: "Test Scenario 7 (Body Only)", 133 scenarioName: "BodyScenario", 134 stepName: "BodyStep", 135 parts: &gun.RequestParts{ 136 Body: []byte(`{"name": "{{.name}}", "age": {{.age}}}`), 137 }, 138 vs: map[string]interface{}{ 139 "name": "Alice", 140 "age": 25, 141 }, 142 expectedURL: "", 143 expectedHeaders: nil, 144 expectedBody: `{"name": "Alice", "age": 25}`, 145 expectError: false, 146 }, 147 { 148 name: "Test Scenario 8 (Invalid Template in Headers)", 149 scenarioName: "InvalidHeaderScenario", 150 stepName: "InvalidHeaderStep", 151 parts: &gun.RequestParts{ 152 Headers: map[string]string{ 153 "Authorization": "Bearer {{.token", 154 }, 155 }, 156 vs: map[string]interface{}{}, 157 expectedURL: "", 158 expectedHeaders: nil, 159 expectedBody: "", 160 expectError: true, 161 }, 162 { 163 name: "Test Scenario 9 (Invalid Template in URL)", 164 scenarioName: "InvalidURLScenario", 165 stepName: "InvalidURLStep", 166 parts: &gun.RequestParts{ 167 URL: "http://example.com/{{.endpoint", 168 }, 169 vs: map[string]interface{}{}, 170 expectedURL: "", 171 expectedHeaders: nil, 172 expectedBody: "", 173 expectError: true, 174 }, 175 { 176 name: "Test Scenario 10 (Invalid Template in Body)", 177 scenarioName: "InvalidBodyScenario", 178 stepName: "InvalidBodyStep", 179 parts: &gun.RequestParts{ 180 Body: []byte(`{"name": "{{.name}"}`), 181 }, 182 vs: map[string]interface{}{}, 183 expectedURL: "", 184 expectedHeaders: nil, 185 expectedBody: "", 186 expectError: true, 187 }, 188 } 189 190 for _, test := range tests { 191 t.Run(test.name, func(t *testing.T) { 192 templater := &TextTemplater{} 193 err := templater.Apply(test.parts, test.vs, test.scenarioName, test.stepName) 194 195 if test.expectError { 196 require.Error(t, err) 197 } else { 198 require.NoError(t, err) 199 assert.Equal(t, test.expectedURL, test.parts.URL) 200 assert.Equal(t, test.expectedHeaders, test.parts.Headers) 201 assert.Equal(t, test.expectedBody, string(test.parts.Body)) 202 } 203 }) 204 } 205 } 206 207 func TestTextTemplater_Apply_WithRandFunct(t *testing.T) { 208 tests := []struct { 209 name string 210 parts *gun.RequestParts 211 vs map[string]interface{} 212 assertBody func(t *testing.T, body string) 213 expectError bool 214 }{ 215 { 216 name: "randInt with vars", 217 parts: &gun.RequestParts{Body: []byte(`{{ randInt .from .to }}`)}, 218 vs: map[string]interface{}{ 219 "from": int64(10), 220 "to": 30, 221 }, 222 assertBody: func(t *testing.T, body string) { 223 v, err := strconv.ParseInt(body, 10, 64) 224 require.NoError(t, err) 225 require.InDelta(t, 20, v, 10) 226 }, 227 expectError: false, 228 }, 229 { 230 name: "randInt with literals", 231 parts: &gun.RequestParts{Body: []byte(`{{ randInt 10 30 }}`)}, 232 vs: map[string]interface{}{}, 233 assertBody: func(t *testing.T, body string) { 234 v, err := strconv.ParseInt(body, 10, 64) 235 require.NoError(t, err) 236 require.InDelta(t, 20, v, 10) 237 }, 238 expectError: false, 239 }, 240 { 241 name: "randInt with no args", 242 parts: &gun.RequestParts{Body: []byte(`{{ randInt }}`)}, 243 vs: map[string]interface{}{}, 244 assertBody: func(t *testing.T, body string) { 245 v, err := strconv.ParseInt(body, 10, 64) 246 require.NoError(t, err) 247 require.InDelta(t, 5, v, 5) 248 }, 249 expectError: false, 250 }, 251 { 252 name: "randInt with literals", 253 parts: &gun.RequestParts{Body: []byte(`{{ randInt -10 }}`)}, 254 vs: map[string]interface{}{}, 255 assertBody: func(t *testing.T, body string) { 256 v, err := strconv.ParseInt(body, 10, 64) 257 require.NoError(t, err) 258 require.InDelta(t, -5, v, 5) 259 }, 260 expectError: false, 261 }, 262 { 263 name: "randInt with invalid args", 264 parts: &gun.RequestParts{Body: []byte(`{{ randInt 10 "asdf" }}`)}, 265 vs: map[string]interface{}{}, 266 assertBody: nil, 267 expectError: true, 268 }, 269 { 270 name: "randString with 2 arg", 271 parts: &gun.RequestParts{Body: []byte(`{{ randString 10 "asdfgzxcv" }}`)}, 272 vs: map[string]interface{}{}, 273 assertBody: func(t *testing.T, body string) { 274 require.Len(t, body, 10) 275 }, 276 expectError: false, 277 }, 278 { 279 name: "randString with 1 arg", 280 parts: &gun.RequestParts{Body: []byte(`{{ randString 10 }}`)}, 281 vs: map[string]interface{}{}, 282 assertBody: func(t *testing.T, body string) { 283 require.Len(t, body, 10) 284 }, 285 expectError: false, 286 }, 287 { 288 name: "randString with 0 arg", 289 parts: &gun.RequestParts{Body: []byte(`{{ randString }}`)}, 290 vs: map[string]interface{}{}, 291 assertBody: func(t *testing.T, body string) { 292 require.Len(t, body, 1) 293 }, 294 expectError: false, 295 }, 296 { 297 name: "randString with invalid arg", 298 parts: &gun.RequestParts{Body: []byte(`{{ randString "asdf" }}`)}, 299 vs: map[string]interface{}{}, 300 assertBody: nil, 301 expectError: true, 302 }, 303 { 304 name: "uuid", 305 parts: &gun.RequestParts{Body: []byte(`{{ uuid }}`)}, 306 vs: map[string]interface{}{}, 307 assertBody: func(t *testing.T, body string) { 308 require.Len(t, body, 36) 309 }, 310 expectError: false, 311 }, 312 } 313 for _, tt := range tests { 314 t.Run(tt.name, func(t *testing.T) { 315 templater := &TextTemplater{} 316 err := templater.Apply(tt.parts, tt.vs, "scenarioName", "stepName") 317 318 if tt.expectError { 319 require.Error(t, err) 320 } else { 321 require.NoError(t, err) 322 tt.assertBody(t, string(tt.parts.Body)) 323 } 324 }) 325 } 326 }