github.com/fastly/cli@v1.7.2-0.20240304164155-9d0f1d77c3bf/pkg/commands/logging/sftp/sftp_test.go (about) 1 package sftp_test 2 3 import ( 4 "bytes" 5 "testing" 6 7 "github.com/fastly/go-fastly/v9/fastly" 8 9 "github.com/fastly/cli/pkg/argparser" 10 "github.com/fastly/cli/pkg/commands/logging/sftp" 11 "github.com/fastly/cli/pkg/config" 12 "github.com/fastly/cli/pkg/errors" 13 "github.com/fastly/cli/pkg/global" 14 "github.com/fastly/cli/pkg/manifest" 15 "github.com/fastly/cli/pkg/mock" 16 "github.com/fastly/cli/pkg/testutil" 17 ) 18 19 func TestCreateSFTPInput(t *testing.T) { 20 for _, testcase := range []struct { 21 name string 22 cmd *sftp.CreateCommand 23 want *fastly.CreateSFTPInput 24 wantError string 25 }{ 26 { 27 name: "required values set flag serviceID", 28 cmd: createCommandRequired(), 29 want: &fastly.CreateSFTPInput{ 30 ServiceID: "123", 31 ServiceVersion: 4, 32 Name: fastly.ToPointer("log"), 33 Address: fastly.ToPointer("127.0.0.1"), 34 User: fastly.ToPointer("user"), 35 SSHKnownHosts: fastly.ToPointer(knownHosts()), 36 }, 37 }, 38 { 39 name: "all values set flag serviceID", 40 cmd: createCommandAll(), 41 want: &fastly.CreateSFTPInput{ 42 ServiceID: "123", 43 ServiceVersion: 4, 44 Name: fastly.ToPointer("log"), 45 Address: fastly.ToPointer("127.0.0.1"), 46 Port: fastly.ToPointer(80), 47 User: fastly.ToPointer("user"), 48 Password: fastly.ToPointer("password"), 49 PublicKey: fastly.ToPointer(pgpPublicKey()), 50 SecretKey: fastly.ToPointer(sshPrivateKey()), 51 SSHKnownHosts: fastly.ToPointer(knownHosts()), 52 Path: fastly.ToPointer("/log"), 53 Period: fastly.ToPointer(3600), 54 FormatVersion: fastly.ToPointer(2), 55 Format: fastly.ToPointer(`%h %l %u %t "%r" %>s %b`), 56 ResponseCondition: fastly.ToPointer("Prevent default logging"), 57 MessageType: fastly.ToPointer("classic"), 58 TimestampFormat: fastly.ToPointer("%Y-%m-%dT%H:%M:%S.000"), 59 Placement: fastly.ToPointer("none"), 60 CompressionCodec: fastly.ToPointer("zstd"), 61 }, 62 }, 63 { 64 name: "error missing serviceID", 65 cmd: createCommandMissingServiceID(), 66 want: nil, 67 wantError: errors.ErrNoServiceID.Error(), 68 }, 69 } { 70 t.Run(testcase.name, func(t *testing.T) { 71 var bs []byte 72 out := bytes.NewBuffer(bs) 73 verboseMode := true 74 75 serviceID, serviceVersion, err := argparser.ServiceDetails(argparser.ServiceDetailsOpts{ 76 AutoCloneFlag: testcase.cmd.AutoClone, 77 APIClient: testcase.cmd.Globals.APIClient, 78 Manifest: testcase.cmd.Manifest, 79 Out: out, 80 ServiceVersionFlag: testcase.cmd.ServiceVersion, 81 VerboseMode: verboseMode, 82 }) 83 84 switch { 85 case err != nil && testcase.wantError == "": 86 t.Fatalf("unexpected error getting service details: %v", err) 87 return 88 case err != nil && testcase.wantError != "": 89 testutil.AssertErrorContains(t, err, testcase.wantError) 90 return 91 case err == nil && testcase.wantError != "": 92 t.Fatalf("expected error, have nil (service details: %s, %d)", serviceID, serviceVersion.Number) 93 case err == nil && testcase.wantError == "": 94 have, err := testcase.cmd.ConstructInput(serviceID, fastly.ToValue(serviceVersion.Number)) 95 testutil.AssertErrorContains(t, err, testcase.wantError) 96 testutil.AssertEqual(t, testcase.want, have) 97 } 98 }) 99 } 100 } 101 102 func TestUpdateSFTPInput(t *testing.T) { 103 scenarios := []struct { 104 name string 105 cmd *sftp.UpdateCommand 106 api mock.API 107 want *fastly.UpdateSFTPInput 108 wantError string 109 }{ 110 { 111 name: "all values set flag serviceID", 112 cmd: updateCommandAll(), 113 api: mock.API{ 114 ListVersionsFn: testutil.ListVersions, 115 CloneVersionFn: testutil.CloneVersionResult(4), 116 GetSFTPFn: getSFTPOK, 117 }, 118 want: &fastly.UpdateSFTPInput{ 119 ServiceID: "123", 120 ServiceVersion: 4, 121 Name: "log", 122 NewName: fastly.ToPointer("new1"), 123 Address: fastly.ToPointer("new2"), 124 Port: fastly.ToPointer(81), 125 User: fastly.ToPointer("new3"), 126 SSHKnownHosts: fastly.ToPointer("new4"), 127 Password: fastly.ToPointer("new5"), 128 PublicKey: fastly.ToPointer("new6"), 129 SecretKey: fastly.ToPointer("new7"), 130 Path: fastly.ToPointer("new8"), 131 Period: fastly.ToPointer(3601), 132 FormatVersion: fastly.ToPointer(3), 133 GzipLevel: fastly.ToPointer(0), 134 Format: fastly.ToPointer("new9"), 135 ResponseCondition: fastly.ToPointer("new10"), 136 TimestampFormat: fastly.ToPointer("new11"), 137 Placement: fastly.ToPointer("new12"), 138 MessageType: fastly.ToPointer("new13"), 139 CompressionCodec: fastly.ToPointer("new14"), 140 }, 141 }, 142 { 143 name: "no updates", 144 cmd: updateCommandNoUpdates(), 145 api: mock.API{ 146 ListVersionsFn: testutil.ListVersions, 147 CloneVersionFn: testutil.CloneVersionResult(4), 148 GetSFTPFn: getSFTPOK, 149 }, 150 want: &fastly.UpdateSFTPInput{ 151 ServiceID: "123", 152 ServiceVersion: 4, 153 Name: "log", 154 }, 155 }, 156 { 157 name: "error missing serviceID", 158 cmd: updateCommandMissingServiceID(), 159 want: nil, 160 wantError: errors.ErrNoServiceID.Error(), 161 }, 162 } 163 for testcaseIdx := range scenarios { 164 testcase := &scenarios[testcaseIdx] 165 t.Run(testcase.name, func(t *testing.T) { 166 testcase.cmd.Globals.APIClient = testcase.api 167 168 var bs []byte 169 out := bytes.NewBuffer(bs) 170 verboseMode := true 171 172 serviceID, serviceVersion, err := argparser.ServiceDetails(argparser.ServiceDetailsOpts{ 173 AutoCloneFlag: testcase.cmd.AutoClone, 174 APIClient: testcase.api, 175 Manifest: testcase.cmd.Manifest, 176 Out: out, 177 ServiceVersionFlag: testcase.cmd.ServiceVersion, 178 VerboseMode: verboseMode, 179 }) 180 181 switch { 182 case err != nil && testcase.wantError == "": 183 t.Fatalf("unexpected error getting service details: %v", err) 184 return 185 case err != nil && testcase.wantError != "": 186 testutil.AssertErrorContains(t, err, testcase.wantError) 187 return 188 case err == nil && testcase.wantError != "": 189 t.Fatalf("expected error, have nil (service details: %s, %d)", serviceID, serviceVersion.Number) 190 case err == nil && testcase.wantError == "": 191 have, err := testcase.cmd.ConstructInput(serviceID, fastly.ToValue(serviceVersion.Number)) 192 testutil.AssertErrorContains(t, err, testcase.wantError) 193 testutil.AssertEqual(t, testcase.want, have) 194 } 195 }) 196 } 197 } 198 199 func createCommandRequired() *sftp.CreateCommand { 200 var b bytes.Buffer 201 202 g := global.Data{ 203 Config: config.File{}, 204 Env: config.Environment{}, 205 Output: &b, 206 } 207 g.APIClient, _ = mock.APIClient(mock.API{ 208 ListVersionsFn: testutil.ListVersions, 209 CloneVersionFn: testutil.CloneVersionResult(4), 210 })("token", "endpoint", false) 211 212 return &sftp.CreateCommand{ 213 Base: argparser.Base{ 214 Globals: &g, 215 }, 216 Manifest: manifest.Data{ 217 Flag: manifest.Flag{ 218 ServiceID: "123", 219 }, 220 }, 221 ServiceVersion: argparser.OptionalServiceVersion{ 222 OptionalString: argparser.OptionalString{Value: "1"}, 223 }, 224 AutoClone: argparser.OptionalAutoClone{ 225 OptionalBool: argparser.OptionalBool{ 226 Optional: argparser.Optional{ 227 WasSet: true, 228 }, 229 Value: true, 230 }, 231 }, 232 EndpointName: argparser.OptionalString{Optional: argparser.Optional{WasSet: true}, Value: "log"}, 233 Address: argparser.OptionalString{Optional: argparser.Optional{WasSet: true}, Value: "127.0.0.1"}, 234 User: argparser.OptionalString{Optional: argparser.Optional{WasSet: true}, Value: "user"}, 235 SSHKnownHosts: argparser.OptionalString{Optional: argparser.Optional{WasSet: true}, Value: knownHosts()}, 236 } 237 } 238 239 func createCommandAll() *sftp.CreateCommand { 240 var b bytes.Buffer 241 242 g := global.Data{ 243 Config: config.File{}, 244 Env: config.Environment{}, 245 Output: &b, 246 } 247 g.APIClient, _ = mock.APIClient(mock.API{ 248 ListVersionsFn: testutil.ListVersions, 249 CloneVersionFn: testutil.CloneVersionResult(4), 250 })("token", "endpoint", false) 251 252 return &sftp.CreateCommand{ 253 Base: argparser.Base{ 254 Globals: &g, 255 }, 256 Manifest: manifest.Data{ 257 Flag: manifest.Flag{ 258 ServiceID: "123", 259 }, 260 }, 261 ServiceVersion: argparser.OptionalServiceVersion{ 262 OptionalString: argparser.OptionalString{Value: "1"}, 263 }, 264 AutoClone: argparser.OptionalAutoClone{ 265 OptionalBool: argparser.OptionalBool{ 266 Optional: argparser.Optional{ 267 WasSet: true, 268 }, 269 Value: true, 270 }, 271 }, 272 EndpointName: argparser.OptionalString{Optional: argparser.Optional{WasSet: true}, Value: "log"}, 273 Address: argparser.OptionalString{Optional: argparser.Optional{WasSet: true}, Value: "127.0.0.1"}, 274 User: argparser.OptionalString{Optional: argparser.Optional{WasSet: true}, Value: "user"}, 275 SSHKnownHosts: argparser.OptionalString{Optional: argparser.Optional{WasSet: true}, Value: knownHosts()}, 276 Port: argparser.OptionalInt{Optional: argparser.Optional{WasSet: true}, Value: 80}, 277 Password: argparser.OptionalString{Optional: argparser.Optional{WasSet: true}, Value: "password"}, 278 PublicKey: argparser.OptionalString{Optional: argparser.Optional{WasSet: true}, Value: pgpPublicKey()}, 279 SecretKey: argparser.OptionalString{Optional: argparser.Optional{WasSet: true}, Value: sshPrivateKey()}, 280 Path: argparser.OptionalString{Optional: argparser.Optional{WasSet: true}, Value: "/log"}, 281 Period: argparser.OptionalInt{Optional: argparser.Optional{WasSet: true}, Value: 3600}, 282 Format: argparser.OptionalString{Optional: argparser.Optional{WasSet: true}, Value: `%h %l %u %t "%r" %>s %b`}, 283 FormatVersion: argparser.OptionalInt{Optional: argparser.Optional{WasSet: true}, Value: 2}, 284 MessageType: argparser.OptionalString{Optional: argparser.Optional{WasSet: true}, Value: "classic"}, 285 ResponseCondition: argparser.OptionalString{Optional: argparser.Optional{WasSet: true}, Value: "Prevent default logging"}, 286 TimestampFormat: argparser.OptionalString{Optional: argparser.Optional{WasSet: true}, Value: "%Y-%m-%dT%H:%M:%S.000"}, 287 Placement: argparser.OptionalString{Optional: argparser.Optional{WasSet: true}, Value: "none"}, 288 CompressionCodec: argparser.OptionalString{Optional: argparser.Optional{WasSet: true}, Value: "zstd"}, 289 } 290 } 291 292 func createCommandMissingServiceID() *sftp.CreateCommand { 293 res := createCommandAll() 294 res.Manifest = manifest.Data{} 295 return res 296 } 297 298 func updateCommandNoUpdates() *sftp.UpdateCommand { 299 var b bytes.Buffer 300 301 g := global.Data{ 302 Config: config.File{}, 303 Env: config.Environment{}, 304 Output: &b, 305 } 306 307 return &sftp.UpdateCommand{ 308 Base: argparser.Base{ 309 Globals: &g, 310 }, 311 Manifest: manifest.Data{ 312 Flag: manifest.Flag{ 313 ServiceID: "123", 314 }, 315 }, 316 EndpointName: "log", 317 ServiceVersion: argparser.OptionalServiceVersion{ 318 OptionalString: argparser.OptionalString{Value: "1"}, 319 }, 320 AutoClone: argparser.OptionalAutoClone{ 321 OptionalBool: argparser.OptionalBool{ 322 Optional: argparser.Optional{ 323 WasSet: true, 324 }, 325 Value: true, 326 }, 327 }, 328 } 329 } 330 331 func updateCommandAll() *sftp.UpdateCommand { 332 var b bytes.Buffer 333 334 g := global.Data{ 335 Config: config.File{}, 336 Env: config.Environment{}, 337 Output: &b, 338 } 339 340 return &sftp.UpdateCommand{ 341 Base: argparser.Base{ 342 Globals: &g, 343 }, 344 Manifest: manifest.Data{ 345 Flag: manifest.Flag{ 346 ServiceID: "123", 347 }, 348 }, 349 EndpointName: "log", 350 ServiceVersion: argparser.OptionalServiceVersion{ 351 OptionalString: argparser.OptionalString{Value: "1"}, 352 }, 353 AutoClone: argparser.OptionalAutoClone{ 354 OptionalBool: argparser.OptionalBool{ 355 Optional: argparser.Optional{ 356 WasSet: true, 357 }, 358 Value: true, 359 }, 360 }, 361 NewName: argparser.OptionalString{Optional: argparser.Optional{WasSet: true}, Value: "new1"}, 362 Address: argparser.OptionalString{Optional: argparser.Optional{WasSet: true}, Value: "new2"}, 363 User: argparser.OptionalString{Optional: argparser.Optional{WasSet: true}, Value: "new3"}, 364 SSHKnownHosts: argparser.OptionalString{Optional: argparser.Optional{WasSet: true}, Value: "new4"}, 365 Port: argparser.OptionalInt{Optional: argparser.Optional{WasSet: true}, Value: 81}, 366 Password: argparser.OptionalString{Optional: argparser.Optional{WasSet: true}, Value: "new5"}, 367 PublicKey: argparser.OptionalString{Optional: argparser.Optional{WasSet: true}, Value: "new6"}, 368 SecretKey: argparser.OptionalString{Optional: argparser.Optional{WasSet: true}, Value: "new7"}, 369 Path: argparser.OptionalString{Optional: argparser.Optional{WasSet: true}, Value: "new8"}, 370 Period: argparser.OptionalInt{Optional: argparser.Optional{WasSet: true}, Value: 3601}, 371 Format: argparser.OptionalString{Optional: argparser.Optional{WasSet: true}, Value: "new9"}, 372 FormatVersion: argparser.OptionalInt{Optional: argparser.Optional{WasSet: true}, Value: 3}, 373 GzipLevel: argparser.OptionalInt{Optional: argparser.Optional{WasSet: true}, Value: 0}, 374 ResponseCondition: argparser.OptionalString{Optional: argparser.Optional{WasSet: true}, Value: "new10"}, 375 TimestampFormat: argparser.OptionalString{Optional: argparser.Optional{WasSet: true}, Value: "new11"}, 376 Placement: argparser.OptionalString{Optional: argparser.Optional{WasSet: true}, Value: "new12"}, 377 MessageType: argparser.OptionalString{Optional: argparser.Optional{WasSet: true}, Value: "new13"}, 378 CompressionCodec: argparser.OptionalString{Optional: argparser.Optional{WasSet: true}, Value: "new14"}, 379 } 380 } 381 382 func updateCommandMissingServiceID() *sftp.UpdateCommand { 383 res := updateCommandAll() 384 res.Manifest = manifest.Data{} 385 return res 386 }