github.com/fastly/cli@v1.7.2-0.20240304164155-9d0f1d77c3bf/pkg/commands/logging/https/https_integration_test.go (about) 1 package https_test 2 3 import ( 4 "bytes" 5 "errors" 6 "io" 7 "strings" 8 "testing" 9 10 "github.com/fastly/go-fastly/v9/fastly" 11 12 "github.com/fastly/cli/pkg/app" 13 "github.com/fastly/cli/pkg/global" 14 "github.com/fastly/cli/pkg/mock" 15 "github.com/fastly/cli/pkg/testutil" 16 ) 17 18 func TestHTTPSCreate(t *testing.T) { 19 args := testutil.Args 20 scenarios := []struct { 21 args []string 22 api mock.API 23 wantError string 24 wantOutput string 25 }{ 26 { 27 args: args("logging https create --service-id 123 --version 1 --name log --url example.com --autoclone"), 28 api: mock.API{ 29 ListVersionsFn: testutil.ListVersions, 30 CloneVersionFn: testutil.CloneVersionResult(4), 31 CreateHTTPSFn: createHTTPSOK, 32 }, 33 wantOutput: "Created HTTPS logging endpoint log (service 123 version 4)", 34 }, 35 { 36 args: args("logging https create --service-id 123 --version 1 --name log --url example.com --autoclone"), 37 api: mock.API{ 38 ListVersionsFn: testutil.ListVersions, 39 CloneVersionFn: testutil.CloneVersionResult(4), 40 CreateHTTPSFn: createHTTPSError, 41 }, 42 wantError: errTest.Error(), 43 }, 44 } 45 for testcaseIdx := range scenarios { 46 testcase := &scenarios[testcaseIdx] 47 t.Run(strings.Join(testcase.args, " "), func(t *testing.T) { 48 var stdout bytes.Buffer 49 app.Init = func(_ []string, _ io.Reader) (*global.Data, error) { 50 opts := testutil.MockGlobalData(testcase.args, &stdout) 51 opts.APIClientFactory = mock.APIClient(testcase.api) 52 return opts, nil 53 } 54 err := app.Run(testcase.args, nil) 55 testutil.AssertErrorContains(t, err, testcase.wantError) 56 testutil.AssertStringContains(t, stdout.String(), testcase.wantOutput) 57 }) 58 } 59 } 60 61 func TestHTTPSList(t *testing.T) { 62 args := testutil.Args 63 scenarios := []struct { 64 args []string 65 api mock.API 66 wantError string 67 wantOutput string 68 }{ 69 { 70 args: args("logging https list --service-id 123 --version 1"), 71 api: mock.API{ 72 ListVersionsFn: testutil.ListVersions, 73 ListHTTPSFn: listHTTPSsOK, 74 }, 75 wantOutput: listHTTPSsShortOutput, 76 }, 77 { 78 args: args("logging https list --service-id 123 --version 1 --verbose"), 79 api: mock.API{ 80 ListVersionsFn: testutil.ListVersions, 81 ListHTTPSFn: listHTTPSsOK, 82 }, 83 wantOutput: listHTTPSsVerboseOutput, 84 }, 85 { 86 args: args("logging https list --service-id 123 --version 1 -v"), 87 api: mock.API{ 88 ListVersionsFn: testutil.ListVersions, 89 ListHTTPSFn: listHTTPSsOK, 90 }, 91 wantOutput: listHTTPSsVerboseOutput, 92 }, 93 { 94 args: args("logging https --verbose list --service-id 123 --version 1"), 95 api: mock.API{ 96 ListVersionsFn: testutil.ListVersions, 97 ListHTTPSFn: listHTTPSsOK, 98 }, 99 wantOutput: listHTTPSsVerboseOutput, 100 }, 101 { 102 args: args("logging -v https list --service-id 123 --version 1"), 103 api: mock.API{ 104 ListVersionsFn: testutil.ListVersions, 105 ListHTTPSFn: listHTTPSsOK, 106 }, 107 wantOutput: listHTTPSsVerboseOutput, 108 }, 109 { 110 args: args("logging https list --service-id 123 --version 1"), 111 api: mock.API{ 112 ListVersionsFn: testutil.ListVersions, 113 ListHTTPSFn: listHTTPSsError, 114 }, 115 wantError: errTest.Error(), 116 }, 117 } 118 for testcaseIdx := range scenarios { 119 testcase := &scenarios[testcaseIdx] 120 t.Run(strings.Join(testcase.args, " "), func(t *testing.T) { 121 var stdout bytes.Buffer 122 app.Init = func(_ []string, _ io.Reader) (*global.Data, error) { 123 opts := testutil.MockGlobalData(testcase.args, &stdout) 124 opts.APIClientFactory = mock.APIClient(testcase.api) 125 return opts, nil 126 } 127 err := app.Run(testcase.args, nil) 128 testutil.AssertErrorContains(t, err, testcase.wantError) 129 testutil.AssertString(t, testcase.wantOutput, stdout.String()) 130 }) 131 } 132 } 133 134 func TestHTTPSDescribe(t *testing.T) { 135 args := testutil.Args 136 scenarios := []struct { 137 args []string 138 api mock.API 139 wantError string 140 wantOutput string 141 }{ 142 { 143 args: args("logging https describe --service-id 123 --version 1"), 144 wantError: "error parsing arguments: required flag --name not provided", 145 }, 146 { 147 args: args("logging https describe --service-id 123 --version 1 --name logs"), 148 api: mock.API{ 149 ListVersionsFn: testutil.ListVersions, 150 GetHTTPSFn: getHTTPSError, 151 }, 152 wantError: errTest.Error(), 153 }, 154 { 155 args: args("logging https describe --service-id 123 --version 1 --name logs"), 156 api: mock.API{ 157 ListVersionsFn: testutil.ListVersions, 158 GetHTTPSFn: getHTTPSOK, 159 }, 160 wantOutput: describeHTTPSOutput, 161 }, 162 } 163 for testcaseIdx := range scenarios { 164 testcase := &scenarios[testcaseIdx] 165 t.Run(strings.Join(testcase.args, " "), func(t *testing.T) { 166 var stdout bytes.Buffer 167 app.Init = func(_ []string, _ io.Reader) (*global.Data, error) { 168 opts := testutil.MockGlobalData(testcase.args, &stdout) 169 opts.APIClientFactory = mock.APIClient(testcase.api) 170 return opts, nil 171 } 172 err := app.Run(testcase.args, nil) 173 testutil.AssertErrorContains(t, err, testcase.wantError) 174 testutil.AssertString(t, testcase.wantOutput, stdout.String()) 175 }) 176 } 177 } 178 179 func TestHTTPSUpdate(t *testing.T) { 180 args := testutil.Args 181 scenarios := []struct { 182 args []string 183 api mock.API 184 wantError string 185 wantOutput string 186 }{ 187 { 188 args: args("logging https update --service-id 123 --version 1 --new-name log"), 189 wantError: "error parsing arguments: required flag --name not provided", 190 }, 191 { 192 args: args("logging https update --service-id 123 --version 1 --name logs --new-name log --autoclone"), 193 api: mock.API{ 194 ListVersionsFn: testutil.ListVersions, 195 CloneVersionFn: testutil.CloneVersionResult(4), 196 UpdateHTTPSFn: updateHTTPSError, 197 }, 198 wantError: errTest.Error(), 199 }, 200 { 201 args: args("logging https update --service-id 123 --version 1 --name logs --new-name log --autoclone"), 202 api: mock.API{ 203 ListVersionsFn: testutil.ListVersions, 204 CloneVersionFn: testutil.CloneVersionResult(4), 205 UpdateHTTPSFn: updateHTTPSOK, 206 }, 207 wantOutput: "Updated HTTPS logging endpoint log (service 123 version 4)", 208 }, 209 } 210 for testcaseIdx := range scenarios { 211 testcase := &scenarios[testcaseIdx] 212 t.Run(strings.Join(testcase.args, " "), func(t *testing.T) { 213 var stdout bytes.Buffer 214 app.Init = func(_ []string, _ io.Reader) (*global.Data, error) { 215 opts := testutil.MockGlobalData(testcase.args, &stdout) 216 opts.APIClientFactory = mock.APIClient(testcase.api) 217 return opts, nil 218 } 219 err := app.Run(testcase.args, nil) 220 testutil.AssertErrorContains(t, err, testcase.wantError) 221 testutil.AssertStringContains(t, stdout.String(), testcase.wantOutput) 222 }) 223 } 224 } 225 226 func TestHTTPSDelete(t *testing.T) { 227 args := testutil.Args 228 scenarios := []struct { 229 args []string 230 api mock.API 231 wantError string 232 wantOutput string 233 }{ 234 { 235 args: args("logging https delete --service-id 123 --version 1"), 236 wantError: "error parsing arguments: required flag --name not provided", 237 }, 238 { 239 args: args("logging https delete --service-id 123 --version 1 --name logs --autoclone"), 240 api: mock.API{ 241 ListVersionsFn: testutil.ListVersions, 242 CloneVersionFn: testutil.CloneVersionResult(4), 243 DeleteHTTPSFn: deleteHTTPSError, 244 }, 245 wantError: errTest.Error(), 246 }, 247 { 248 args: args("logging https delete --service-id 123 --version 1 --name logs --autoclone"), 249 api: mock.API{ 250 ListVersionsFn: testutil.ListVersions, 251 CloneVersionFn: testutil.CloneVersionResult(4), 252 DeleteHTTPSFn: deleteHTTPSOK, 253 }, 254 wantOutput: "Deleted HTTPS logging endpoint logs (service 123 version 4)", 255 }, 256 } 257 for testcaseIdx := range scenarios { 258 testcase := &scenarios[testcaseIdx] 259 t.Run(strings.Join(testcase.args, " "), func(t *testing.T) { 260 var stdout bytes.Buffer 261 app.Init = func(_ []string, _ io.Reader) (*global.Data, error) { 262 opts := testutil.MockGlobalData(testcase.args, &stdout) 263 opts.APIClientFactory = mock.APIClient(testcase.api) 264 return opts, nil 265 } 266 err := app.Run(testcase.args, nil) 267 testutil.AssertErrorContains(t, err, testcase.wantError) 268 testutil.AssertStringContains(t, stdout.String(), testcase.wantOutput) 269 }) 270 } 271 } 272 273 var errTest = errors.New("fixture error") 274 275 func createHTTPSOK(i *fastly.CreateHTTPSInput) (*fastly.HTTPS, error) { 276 return &fastly.HTTPS{ 277 ServiceID: fastly.ToPointer(i.ServiceID), 278 ServiceVersion: fastly.ToPointer(i.ServiceVersion), 279 Name: fastly.ToPointer("log"), 280 ResponseCondition: fastly.ToPointer("Prevent default logging"), 281 Format: fastly.ToPointer(`%h %l %u %t "%r" %>s %b`), 282 URL: fastly.ToPointer("example.com"), 283 RequestMaxEntries: fastly.ToPointer(2), 284 RequestMaxBytes: fastly.ToPointer(2), 285 ContentType: fastly.ToPointer("application/json"), 286 HeaderName: fastly.ToPointer("name"), 287 HeaderValue: fastly.ToPointer("value"), 288 Method: fastly.ToPointer("GET"), 289 JSONFormat: fastly.ToPointer("1"), 290 Placement: fastly.ToPointer("none"), 291 TLSCACert: fastly.ToPointer("-----BEGIN CERTIFICATE-----foo"), 292 TLSClientCert: fastly.ToPointer("-----BEGIN CERTIFICATE-----bar"), 293 TLSClientKey: fastly.ToPointer("-----BEGIN PRIVATE KEY-----bar"), 294 TLSHostname: fastly.ToPointer("example.com"), 295 MessageType: fastly.ToPointer("classic"), 296 FormatVersion: fastly.ToPointer(2), 297 }, nil 298 } 299 300 func createHTTPSError(_ *fastly.CreateHTTPSInput) (*fastly.HTTPS, error) { 301 return nil, errTest 302 } 303 304 func listHTTPSsOK(i *fastly.ListHTTPSInput) ([]*fastly.HTTPS, error) { 305 return []*fastly.HTTPS{ 306 { 307 ServiceID: fastly.ToPointer(i.ServiceID), 308 ServiceVersion: fastly.ToPointer(i.ServiceVersion), 309 Name: fastly.ToPointer("logs"), 310 ResponseCondition: fastly.ToPointer("Prevent default logging"), 311 Format: fastly.ToPointer(`%h %l %u %t "%r" %>s %b`), 312 URL: fastly.ToPointer("example.com"), 313 RequestMaxEntries: fastly.ToPointer(2), 314 RequestMaxBytes: fastly.ToPointer(2), 315 ContentType: fastly.ToPointer("application/json"), 316 HeaderName: fastly.ToPointer("name"), 317 HeaderValue: fastly.ToPointer("value"), 318 Method: fastly.ToPointer("GET"), 319 JSONFormat: fastly.ToPointer("1"), 320 Placement: fastly.ToPointer("none"), 321 TLSCACert: fastly.ToPointer("-----BEGIN CERTIFICATE-----foo"), 322 TLSClientCert: fastly.ToPointer("-----BEGIN CERTIFICATE-----bar"), 323 TLSClientKey: fastly.ToPointer("-----BEGIN PRIVATE KEY-----bar"), 324 TLSHostname: fastly.ToPointer("example.com"), 325 MessageType: fastly.ToPointer("classic"), 326 FormatVersion: fastly.ToPointer(2), 327 }, 328 { 329 ServiceID: fastly.ToPointer(i.ServiceID), 330 ServiceVersion: fastly.ToPointer(i.ServiceVersion), 331 Name: fastly.ToPointer("analytics"), 332 ResponseCondition: fastly.ToPointer("Prevent default logging"), 333 Format: fastly.ToPointer(`%h %l %u %t "%r" %>s %b`), 334 URL: fastly.ToPointer("analytics.example.com"), 335 RequestMaxEntries: fastly.ToPointer(2), 336 RequestMaxBytes: fastly.ToPointer(2), 337 ContentType: fastly.ToPointer("application/json"), 338 HeaderName: fastly.ToPointer("name"), 339 HeaderValue: fastly.ToPointer("value"), 340 Method: fastly.ToPointer("GET"), 341 JSONFormat: fastly.ToPointer("1"), 342 Placement: fastly.ToPointer("none"), 343 TLSCACert: fastly.ToPointer("-----BEGIN CERTIFICATE-----foo"), 344 TLSClientCert: fastly.ToPointer("-----BEGIN CERTIFICATE-----bar"), 345 TLSClientKey: fastly.ToPointer("-----BEGIN PRIVATE KEY-----bar"), 346 TLSHostname: fastly.ToPointer("example.com"), 347 MessageType: fastly.ToPointer("classic"), 348 FormatVersion: fastly.ToPointer(2), 349 }, 350 }, nil 351 } 352 353 func listHTTPSsError(_ *fastly.ListHTTPSInput) ([]*fastly.HTTPS, error) { 354 return nil, errTest 355 } 356 357 var listHTTPSsShortOutput = strings.TrimSpace(` 358 SERVICE VERSION NAME 359 123 1 logs 360 123 1 analytics 361 `) + "\n" 362 363 var listHTTPSsVerboseOutput = strings.TrimSpace(` 364 Fastly API endpoint: https://api.fastly.com 365 Fastly API token provided via config file (profile: user) 366 367 Service ID (via --service-id): 123 368 369 Version: 1 370 HTTPS 1/2 371 Service ID: 123 372 Version: 1 373 Name: logs 374 URL: example.com 375 Content type: application/json 376 Header name: name 377 Header value: value 378 Method: GET 379 JSON format: 1 380 TLS CA certificate: -----BEGIN CERTIFICATE-----foo 381 TLS client certificate: -----BEGIN CERTIFICATE-----bar 382 TLS client key: -----BEGIN PRIVATE KEY-----bar 383 TLS hostname: example.com 384 Request max entries: 2 385 Request max bytes: 2 386 Message type: classic 387 Format: %h %l %u %t "%r" %>s %b 388 Format version: 2 389 Response condition: Prevent default logging 390 Placement: none 391 HTTPS 2/2 392 Service ID: 123 393 Version: 1 394 Name: analytics 395 URL: analytics.example.com 396 Content type: application/json 397 Header name: name 398 Header value: value 399 Method: GET 400 JSON format: 1 401 TLS CA certificate: -----BEGIN CERTIFICATE-----foo 402 TLS client certificate: -----BEGIN CERTIFICATE-----bar 403 TLS client key: -----BEGIN PRIVATE KEY-----bar 404 TLS hostname: example.com 405 Request max entries: 2 406 Request max bytes: 2 407 Message type: classic 408 Format: %h %l %u %t "%r" %>s %b 409 Format version: 2 410 Response condition: Prevent default logging 411 Placement: none 412 `) + "\n\n" 413 414 func getHTTPSOK(i *fastly.GetHTTPSInput) (*fastly.HTTPS, error) { 415 return &fastly.HTTPS{ 416 ServiceID: fastly.ToPointer(i.ServiceID), 417 ServiceVersion: fastly.ToPointer(i.ServiceVersion), 418 Name: fastly.ToPointer("log"), 419 ResponseCondition: fastly.ToPointer("Prevent default logging"), 420 Format: fastly.ToPointer(`%h %l %u %t "%r" %>s %b`), 421 URL: fastly.ToPointer("example.com"), 422 RequestMaxEntries: fastly.ToPointer(2), 423 RequestMaxBytes: fastly.ToPointer(2), 424 ContentType: fastly.ToPointer("application/json"), 425 HeaderName: fastly.ToPointer("name"), 426 HeaderValue: fastly.ToPointer("value"), 427 Method: fastly.ToPointer("GET"), 428 JSONFormat: fastly.ToPointer("1"), 429 Placement: fastly.ToPointer("none"), 430 TLSCACert: fastly.ToPointer("-----BEGIN CERTIFICATE-----foo"), 431 TLSClientCert: fastly.ToPointer("-----BEGIN CERTIFICATE-----bar"), 432 TLSClientKey: fastly.ToPointer("-----BEGIN PRIVATE KEY-----bar"), 433 TLSHostname: fastly.ToPointer("example.com"), 434 MessageType: fastly.ToPointer("classic"), 435 FormatVersion: fastly.ToPointer(2), 436 }, nil 437 } 438 439 func getHTTPSError(_ *fastly.GetHTTPSInput) (*fastly.HTTPS, error) { 440 return nil, errTest 441 } 442 443 var describeHTTPSOutput = "\n" + strings.TrimSpace(` 444 Content type: application/json 445 Format: %h %l %u %t "%r" %>s %b 446 Format version: 2 447 Header name: name 448 Header value: value 449 JSON format: 1 450 Message type: classic 451 Method: GET 452 Name: log 453 Placement: none 454 Request max bytes: 2 455 Request max entries: 2 456 Response condition: Prevent default logging 457 Service ID: 123 458 TLS CA certificate: -----BEGIN CERTIFICATE-----foo 459 TLS client certificate: -----BEGIN CERTIFICATE-----bar 460 TLS client key: -----BEGIN PRIVATE KEY-----bar 461 TLS hostname: example.com 462 URL: example.com 463 Version: 1 464 `) + "\n" 465 466 func updateHTTPSOK(i *fastly.UpdateHTTPSInput) (*fastly.HTTPS, error) { 467 return &fastly.HTTPS{ 468 ServiceID: fastly.ToPointer(i.ServiceID), 469 ServiceVersion: fastly.ToPointer(i.ServiceVersion), 470 Name: fastly.ToPointer("log"), 471 ResponseCondition: fastly.ToPointer("Prevent default logging"), 472 Format: fastly.ToPointer(`%h %l %u %t "%r" %>s %b`), 473 URL: fastly.ToPointer("example.com"), 474 RequestMaxEntries: fastly.ToPointer(2), 475 RequestMaxBytes: fastly.ToPointer(2), 476 ContentType: fastly.ToPointer("application/json"), 477 HeaderName: fastly.ToPointer("name"), 478 HeaderValue: fastly.ToPointer("value"), 479 Method: fastly.ToPointer("GET"), 480 JSONFormat: fastly.ToPointer("1"), 481 Placement: fastly.ToPointer("none"), 482 TLSCACert: fastly.ToPointer("-----BEGIN CERTIFICATE-----foo"), 483 TLSClientCert: fastly.ToPointer("-----BEGIN CERTIFICATE-----bar"), 484 TLSClientKey: fastly.ToPointer("-----BEGIN PRIVATE KEY-----bar"), 485 TLSHostname: fastly.ToPointer("example.com"), 486 MessageType: fastly.ToPointer("classic"), 487 FormatVersion: fastly.ToPointer(2), 488 }, nil 489 } 490 491 func updateHTTPSError(_ *fastly.UpdateHTTPSInput) (*fastly.HTTPS, error) { 492 return nil, errTest 493 } 494 495 func deleteHTTPSOK(_ *fastly.DeleteHTTPSInput) error { 496 return nil 497 } 498 499 func deleteHTTPSError(_ *fastly.DeleteHTTPSInput) error { 500 return errTest 501 }