github.com/LukasHeimann/cloudfoundrycli/v8@v8.4.4/command/v7/marketplace_command_test.go (about) 1 package v7_test 2 3 import ( 4 "github.com/LukasHeimann/cloudfoundrycli/v8/actor/v7action" 5 "github.com/LukasHeimann/cloudfoundrycli/v8/command/commandfakes" 6 "github.com/LukasHeimann/cloudfoundrycli/v8/command/translatableerror" 7 . "github.com/LukasHeimann/cloudfoundrycli/v8/command/v7" 8 "github.com/LukasHeimann/cloudfoundrycli/v8/command/v7/v7fakes" 9 "github.com/LukasHeimann/cloudfoundrycli/v8/resources" 10 "github.com/LukasHeimann/cloudfoundrycli/v8/util/configv3" 11 "github.com/LukasHeimann/cloudfoundrycli/v8/util/ui" 12 . "github.com/onsi/ginkgo" 13 . "github.com/onsi/ginkgo/extensions/table" 14 . "github.com/onsi/gomega" 15 . "github.com/onsi/gomega/gbytes" 16 "github.com/pkg/errors" 17 ) 18 19 var _ = Describe("marketplace command", func() { 20 var ( 21 cmd MarketplaceCommand 22 testUI *ui.UI 23 fakeConfig *commandfakes.FakeConfig 24 fakeSharedActor *commandfakes.FakeSharedActor 25 fakeActor *v7fakes.FakeActor 26 ) 27 28 BeforeEach(func() { 29 testUI = ui.NewTestUI(nil, NewBuffer(), NewBuffer()) 30 fakeConfig = new(commandfakes.FakeConfig) 31 fakeSharedActor = new(commandfakes.FakeSharedActor) 32 fakeActor = new(v7fakes.FakeActor) 33 34 cmd = MarketplaceCommand{ 35 BaseCommand: BaseCommand{ 36 UI: testUI, 37 Config: fakeConfig, 38 SharedActor: fakeSharedActor, 39 Actor: fakeActor, 40 }, 41 } 42 43 fakeConfig.TargetedSpaceReturns(configv3.Space{ 44 GUID: "fake-space-guid", 45 Name: "fake-space-name", 46 }) 47 48 fakeConfig.TargetedOrganizationReturns(configv3.Organization{ 49 GUID: "fake-org-guid", 50 Name: "fake-org-name", 51 }) 52 53 fakeActor.GetCurrentUserReturns(configv3.User{Name: "fake-username"}, nil) 54 }) 55 56 Describe("pre-flight checks", func() { 57 var executeErr error 58 59 JustBeforeEach(func() { 60 executeErr = cmd.Execute(nil) 61 }) 62 63 It("checks the login status", func() { 64 Expect(fakeSharedActor.IsLoggedInCallCount()).To(Equal(1)) 65 }) 66 67 When("logged in", func() { 68 BeforeEach(func() { 69 fakeSharedActor.IsLoggedInReturns(true) 70 }) 71 72 It("gets the user", func() { 73 Expect(fakeActor.GetCurrentUserCallCount()).To(Equal(1)) 74 }) 75 76 It("checks the target", func() { 77 Expect(fakeSharedActor.CheckTargetCallCount()).To(Equal(1)) 78 checkOrg, checkSpace := fakeSharedActor.CheckTargetArgsForCall(0) 79 Expect(checkOrg).To(BeTrue()) 80 Expect(checkSpace).To(BeTrue()) 81 }) 82 83 When("getting the user fails", func() { 84 BeforeEach(func() { 85 fakeActor.GetCurrentUserReturns(configv3.User{}, errors.New("fake get user error")) 86 }) 87 88 It("returns an error", func() { 89 Expect(executeErr).To(MatchError("fake get user error")) 90 }) 91 }) 92 93 When("checking the target fails", func() { 94 BeforeEach(func() { 95 fakeSharedActor.CheckTargetReturns(errors.New("fake target error")) 96 }) 97 98 It("returns an error", func() { 99 Expect(executeErr).To(MatchError("fake target error")) 100 }) 101 }) 102 }) 103 104 When("not logged in", func() { 105 BeforeEach(func() { 106 fakeSharedActor.IsLoggedInReturns(false) 107 }) 108 109 It("does not try to get the username or check the target", func() { 110 Expect(fakeActor.GetCurrentUserCallCount()).To(Equal(0)) 111 Expect(fakeSharedActor.CheckTargetCallCount()).To(Equal(0)) 112 }) 113 }) 114 115 When("the -e and --no-plans flags to be specified together", func() { 116 BeforeEach(func() { 117 setFlag(&cmd, "--no-plans") 118 setFlag(&cmd, "-e", "foo") 119 }) 120 121 It("returns an error", func() { 122 Expect(executeErr).To(MatchError(translatableerror.ArgumentCombinationError{ 123 Args: []string{"--no-plans", "-e"}, 124 })) 125 }) 126 }) 127 }) 128 129 DescribeTable( 130 "printing the action", 131 func(loggedIn bool, flags map[string]interface{}, message string) { 132 fakeSharedActor.IsLoggedInReturns(loggedIn) 133 134 for k, v := range flags { 135 setFlag(&cmd, k, v) 136 } 137 138 err := cmd.Execute(nil) 139 Expect(err).NotTo(HaveOccurred()) 140 141 Expect(testUI.Out).To(Say(message)) 142 }, 143 Entry( 144 "not logged in with no flags", 145 false, 146 map[string]interface{}{}, 147 `Getting all service offerings from marketplace\.\.\.`, 148 ), 149 Entry( 150 "not logged in with -e flag", 151 false, 152 map[string]interface{}{ 153 "-e": "fake-service-offering-name", 154 }, 155 `Getting service plan information for service offering fake-service-offering-name\.\.\.`, 156 ), 157 Entry( 158 "not logged in with -b flag", 159 false, 160 map[string]interface{}{ 161 "-b": "fake-service-broker-name", 162 }, 163 `Getting all service offerings from marketplace for service broker fake-service-broker-name\.\.\.`, 164 ), 165 Entry( 166 "not logged in with -e and -b flag", 167 false, 168 map[string]interface{}{ 169 "-b": "fake-service-broker-name", 170 "-e": "fake-service-offering-name", 171 }, 172 `Getting service plan information for service offering fake-service-offering-name from service broker fake-service-broker-name\.\.\.`, 173 ), 174 Entry( 175 "logged in with no flags", 176 true, 177 map[string]interface{}{}, 178 `Getting all service offerings from marketplace in org fake-org-name / space fake-space-name as fake-username\.\.\.`, 179 ), 180 Entry( 181 "logged in with -e flag", 182 true, 183 map[string]interface{}{ 184 "-e": "fake-service-offering-name", 185 }, 186 `Getting service plan information for service offering fake-service-offering-name in org fake-org-name / space fake-space-name as fake-username\.\.\.`, 187 ), 188 Entry( 189 "logged in with -b flag", 190 true, 191 map[string]interface{}{ 192 "-b": "fake-service-broker-name", 193 }, 194 `Getting all service offerings from marketplace for service broker fake-service-broker-name in org fake-org-name / space fake-space-name as fake-username\.\.\.`, 195 ), 196 Entry( 197 "logged in with -e and -b flag", 198 true, 199 map[string]interface{}{ 200 "-e": "fake-service-offering-name", 201 "-b": "fake-service-broker-name", 202 }, 203 `Getting service plan information for service offering fake-service-offering-name from service broker fake-service-broker-name in org fake-org-name / space fake-space-name as fake-username\.\.\.`, 204 ), 205 ) 206 207 DescribeTable( 208 "sending the filter to the actor", 209 func(loggedIn bool, flags map[string]interface{}, expectedFilter v7action.MarketplaceFilter) { 210 fakeSharedActor.IsLoggedInReturns(loggedIn) 211 212 for k, v := range flags { 213 setFlag(&cmd, k, v) 214 } 215 216 err := cmd.Execute(nil) 217 Expect(err).NotTo(HaveOccurred()) 218 219 Expect(fakeActor.MarketplaceCallCount()).To(Equal(1)) 220 Expect(fakeActor.MarketplaceArgsForCall(0)).To(Equal(expectedFilter)) 221 }, 222 Entry( 223 "not logged in with no flags", 224 false, 225 map[string]interface{}{}, 226 v7action.MarketplaceFilter{}, 227 ), 228 Entry( 229 "not logged in with -e flag", 230 false, 231 map[string]interface{}{ 232 "-e": "fake-service-offering-name", 233 }, 234 v7action.MarketplaceFilter{ 235 ServiceOfferingName: "fake-service-offering-name", 236 }, 237 ), 238 Entry( 239 "not logged in with -b flag", 240 false, 241 map[string]interface{}{ 242 "-b": "fake-service-broker-name", 243 }, 244 v7action.MarketplaceFilter{ 245 ServiceBrokerName: "fake-service-broker-name", 246 }, 247 ), 248 Entry( 249 "not logged in with -e and -b flag", 250 false, 251 map[string]interface{}{ 252 "-b": "fake-service-broker-name", 253 "-e": "fake-service-offering-name", 254 }, 255 v7action.MarketplaceFilter{ 256 ServiceOfferingName: "fake-service-offering-name", 257 ServiceBrokerName: "fake-service-broker-name", 258 }, 259 ), 260 Entry( 261 "not logged in with --show-unavailable", 262 false, 263 map[string]interface{}{ 264 "--show-unavailable": true, 265 }, 266 v7action.MarketplaceFilter{ 267 ShowUnavailable: true, 268 }, 269 ), 270 Entry( 271 "logged in with no flags", 272 true, 273 map[string]interface{}{}, 274 v7action.MarketplaceFilter{ 275 SpaceGUID: "fake-space-guid", 276 }, 277 ), 278 Entry( 279 "logged in with -e flag", 280 true, 281 map[string]interface{}{ 282 "-e": "fake-service-offering-name", 283 }, 284 v7action.MarketplaceFilter{ 285 SpaceGUID: "fake-space-guid", 286 ServiceOfferingName: "fake-service-offering-name", 287 }, 288 ), 289 Entry( 290 "logged in with -b flag", 291 true, 292 map[string]interface{}{ 293 "-b": "fake-service-broker-name", 294 }, 295 v7action.MarketplaceFilter{ 296 SpaceGUID: "fake-space-guid", 297 ServiceBrokerName: "fake-service-broker-name", 298 }, 299 ), 300 Entry( 301 "logged in with -e and -b flag", 302 true, 303 map[string]interface{}{ 304 "-e": "fake-service-offering-name", 305 "-b": "fake-service-broker-name", 306 }, 307 v7action.MarketplaceFilter{ 308 SpaceGUID: "fake-space-guid", 309 ServiceOfferingName: "fake-service-offering-name", 310 ServiceBrokerName: "fake-service-broker-name", 311 }, 312 ), 313 Entry( 314 "logged in with --show-unavailable", 315 true, 316 map[string]interface{}{ 317 "--show-unavailable": true, 318 }, 319 v7action.MarketplaceFilter{ 320 SpaceGUID: "fake-space-guid", 321 ShowUnavailable: true, 322 }, 323 ), 324 ) 325 326 Describe("handling the result from the actor", func() { 327 var executeErr error 328 329 JustBeforeEach(func() { 330 executeErr = cmd.Execute(nil) 331 }) 332 333 When("the actor returns warnings", func() { 334 BeforeEach(func() { 335 fakeActor.MarketplaceReturns( 336 []v7action.ServiceOfferingWithPlans{{}}, 337 v7action.Warnings{"warning 1", "warning 2"}, 338 nil, 339 ) 340 }) 341 342 It("prints then", func() { 343 Expect(testUI.Err).To(Say(`warning 1`)) 344 Expect(testUI.Err).To(Say(`warning 2`)) 345 }) 346 }) 347 348 When("the actor returns an error", func() { 349 BeforeEach(func() { 350 fakeActor.MarketplaceReturns( 351 []v7action.ServiceOfferingWithPlans{{}}, 352 v7action.Warnings{"warning 1", "warning 2"}, 353 errors.New("awful error"), 354 ) 355 }) 356 357 It("prints warnings and returns an error", func() { 358 Expect(testUI.Err).To(Say(`warning 1`)) 359 Expect(testUI.Err).To(Say(`warning 2`)) 360 Expect(executeErr).To(MatchError("awful error")) 361 }) 362 }) 363 364 When("no offerings are returned", func() { 365 BeforeEach(func() { 366 fakeActor.MarketplaceReturns( 367 []v7action.ServiceOfferingWithPlans{}, 368 v7action.Warnings{"warning 1", "warning 2"}, 369 nil, 370 ) 371 }) 372 373 It("says that no service offerings were found", func() { 374 Expect(executeErr).NotTo(HaveOccurred()) 375 376 Expect(testUI.Out).To(Say(`\n\n`)) 377 Expect(testUI.Out).To(Say(`No service offerings found.`)) 378 379 Expect(testUI.Err).To(Say("warning 1")) 380 Expect(testUI.Err).To(Say("warning 2")) 381 }) 382 }) 383 384 When("showing the service offerings table", func() { 385 BeforeEach(func() { 386 fakeActor.MarketplaceReturns( 387 []v7action.ServiceOfferingWithPlans{ 388 { 389 GUID: "offering-guid-1", 390 Name: "offering-1", 391 Description: "about offering 1", 392 ServiceBrokerName: "service-broker-1", 393 Plans: []resources.ServicePlan{ 394 { 395 GUID: "plan-guid-1", 396 Name: "plan-1", 397 }, 398 }, 399 }, 400 { 401 GUID: "offering-guid-2", 402 Name: "offering-2", 403 Description: "about offering 2", 404 ServiceBrokerName: "service-broker-2", 405 Plans: []resources.ServicePlan{ 406 { 407 GUID: "plan-guid-2", 408 Name: "plan-2", 409 }, 410 { 411 GUID: "plan-guid-3", 412 Name: "plan-3", 413 }, 414 }, 415 }, 416 }, 417 v7action.Warnings{"warning 1", "warning 2"}, 418 nil, 419 ) 420 }) 421 422 It("prints a table showing service offerings", func() { 423 Expect(executeErr).NotTo(HaveOccurred()) 424 425 Expect(testUI.Out).To(Say(`\n\n`)) 426 Expect(testUI.Out).To(Say(`offering\s+plans\s+description\s+broker`)) 427 Expect(testUI.Out).To(Say(`offering-1\s+plan-1\s+about offering 1\s+service-broker-1`)) 428 Expect(testUI.Out).To(Say(`offering-2\s+plan-2, plan-3\s+about offering 2\s+service-broker-2`)) 429 Expect(testUI.Out).To(Say(`\n\n`)) 430 Expect(testUI.Out).To(Say(`TIP: Use 'cf marketplace -e SERVICE_OFFERING' to view descriptions of individual plans of a given service offering\.`)) 431 432 Expect(testUI.Err).To(Say("warning 1")) 433 Expect(testUI.Err).To(Say("warning 2")) 434 }) 435 436 When("the --no-plans flag is specified", func() { 437 BeforeEach(func() { 438 setFlag(&cmd, "--no-plans") 439 }) 440 441 It("prints a table showing service offerings without plan names", func() { 442 Expect(executeErr).NotTo(HaveOccurred()) 443 444 Expect(testUI.Out).To(Say(`\n\n`)) 445 Expect(testUI.Out).To(Say(`offering\s+description\s+broker`)) 446 Expect(testUI.Out).To(Say(`offering-1\s+about offering 1\s+service-broker-1`)) 447 Expect(testUI.Out).To(Say(`offering-2\s+about offering 2\s+service-broker-2`)) 448 Expect(testUI.Out).To(Say(`\n\n`)) 449 Expect(testUI.Out).To(Say(`TIP: Use 'cf marketplace -e SERVICE_OFFERING' to view descriptions of individual plans of a given service offering\.`)) 450 451 Expect(testUI.Err).To(Say("warning 1")) 452 Expect(testUI.Err).To(Say("warning 2")) 453 }) 454 }) 455 }) 456 457 When("showing the service plans table", func() { 458 BeforeEach(func() { 459 setFlag(&cmd, "-e", "fake-service-offering-name") 460 461 fakeActor.MarketplaceReturns( 462 []v7action.ServiceOfferingWithPlans{ 463 { 464 GUID: "offering-guid-1", 465 Name: "interesting-name", 466 Description: "about offering 1", 467 ServiceBrokerName: "service-broker-1", 468 Plans: []resources.ServicePlan{ 469 { 470 GUID: "plan-guid-1", 471 Name: "plan-1", 472 Description: "best imaginable plan", 473 Available: true, 474 Free: true, 475 }, 476 }, 477 }, 478 { 479 GUID: "offering-guid-2", 480 Name: "interesting-name", 481 Description: "about offering 2", 482 ServiceBrokerName: "service-broker-2", 483 Plans: []resources.ServicePlan{ 484 { 485 GUID: "plan-guid-2", 486 Name: "plan-2", 487 Description: "just another plan", 488 Available: true, 489 Free: false, 490 Costs: []resources.ServicePlanCost{ 491 { 492 Currency: "USD", 493 Amount: 100, 494 Unit: "Monthly", 495 }, 496 { 497 Currency: "USD", 498 Amount: 0.999, 499 Unit: "1GB of messages over 20GB", 500 }, 501 }, 502 }, 503 { 504 GUID: "plan-guid-3", 505 Name: "plan-3", 506 Free: true, 507 Available: true, 508 }, 509 { 510 GUID: "plan-guid-4", 511 Name: "plan-4", 512 Free: false, 513 Available: true, 514 }, 515 }, 516 }, 517 }, 518 v7action.Warnings{"warning 1", "warning 2"}, 519 nil, 520 ) 521 }) 522 523 It("prints a table showing service plans", func() { 524 Expect(executeErr).NotTo(HaveOccurred()) 525 526 Expect(testUI.Out).To(SatisfyAll( 527 Say(`\n\n`), 528 Say(`broker: service-broker-1`), 529 Say(`plan\s+description\s+free or paid\s+costs`), 530 Not(Say(`available`)), 531 Say(`plan-1\s+best imaginable plan\s+free`), 532 Say(`\n\n`), 533 Say(`broker: service-broker-2`), 534 Say(`plan\s+description\s+free or paid\s+costs`), 535 Not(Say(`available`)), 536 Say(`plan-2\s+just another plan\s+paid\s+USD 100.00/Monthly, USD 1.00/1GB of messages over 20GB`), 537 Say(`plan-3\s+free`), 538 Say(`plan-4\s+paid`), 539 )) 540 541 Expect(testUI.Err).To(SatisfyAll( 542 Say("warning 1"), 543 Say("warning 2"), 544 )) 545 }) 546 }) 547 548 When("showing the service plans table with availability", func() { 549 BeforeEach(func() { 550 setFlag(&cmd, "-e", "fake-service-offering-name") 551 setFlag(&cmd, "--show-unavailable", true) 552 553 fakeActor.MarketplaceReturns( 554 []v7action.ServiceOfferingWithPlans{ 555 { 556 GUID: "offering-guid-1", 557 Name: "interesting-name", 558 Description: "about offering 1", 559 ServiceBrokerName: "service-broker-1", 560 Plans: []resources.ServicePlan{ 561 { 562 GUID: "plan-guid-1", 563 Name: "plan-1", 564 Description: "best imaginable plan", 565 Available: true, 566 Free: true, 567 }, 568 }, 569 }, 570 { 571 GUID: "offering-guid-2", 572 Name: "interesting-name", 573 Description: "about offering 2", 574 ServiceBrokerName: "service-broker-2", 575 Plans: []resources.ServicePlan{ 576 { 577 GUID: "plan-guid-2", 578 Name: "plan-2", 579 Description: "just another plan", 580 Available: true, 581 Free: false, 582 Costs: []resources.ServicePlanCost{ 583 { 584 Currency: "USD", 585 Amount: 100, 586 Unit: "Monthly", 587 }, 588 { 589 Currency: "USD", 590 Amount: 0.999, 591 Unit: "1GB of messages over 20GB", 592 }, 593 }, 594 }, 595 { 596 GUID: "plan-guid-3", 597 Name: "plan-3", 598 Free: true, 599 Available: false, 600 }, 601 { 602 GUID: "plan-guid-4", 603 Name: "plan-4", 604 Free: false, 605 Available: true, 606 }, 607 }, 608 }, 609 }, 610 v7action.Warnings{"warning 1", "warning 2"}, 611 nil, 612 ) 613 }) 614 615 It("prints a table showing service plans with availability", func() { 616 Expect(executeErr).NotTo(HaveOccurred()) 617 618 Expect(testUI.Out).To(Say(`\n\n`)) 619 Expect(testUI.Out).To(Say(`broker: service-broker-1`)) 620 Expect(testUI.Out).To(Say(`plan\s+description\s+free or paid\s+costs\s+available`)) 621 Expect(testUI.Out).To(Say(`plan-1\s+best imaginable plan\s+free\s+yes`)) 622 Expect(testUI.Out).To(Say(`\n\n`)) 623 Expect(testUI.Out).To(Say(`broker: service-broker-2`)) 624 Expect(testUI.Out).To(Say(`plan\s+description\s+free or paid\s+costs\s+available`)) 625 Expect(testUI.Out).To(Say(`plan-2\s+just another plan\s+paid\s+USD 100.00/Monthly, USD 1.00/1GB of messages over 20GB\s+yes`)) 626 Expect(testUI.Out).To(Say(`plan-3\s+free\s+no`)) 627 Expect(testUI.Out).To(Say(`plan-4\s+paid\s+yes`)) 628 629 Expect(testUI.Err).To(Say("warning 1")) 630 Expect(testUI.Err).To(Say("warning 2")) 631 }) 632 }) 633 }) 634 })