github.com/mook-as/cf-cli@v7.0.0-beta.28.0.20200120190804-b91c115fae48+incompatible/command/v6/marketplace_command_test.go (about)

     1  package v6_test
     2  
     3  import (
     4  	"errors"
     5  
     6  	"code.cloudfoundry.org/cli/actor/v2action"
     7  	"code.cloudfoundry.org/cli/command/commandfakes"
     8  	"code.cloudfoundry.org/cli/command/translatableerror"
     9  	. "code.cloudfoundry.org/cli/command/v6"
    10  	"code.cloudfoundry.org/cli/command/v6/v6fakes"
    11  	"code.cloudfoundry.org/cli/util/configv3"
    12  	"code.cloudfoundry.org/cli/util/ui"
    13  	. "github.com/onsi/ginkgo"
    14  	. "github.com/onsi/gomega"
    15  	. "github.com/onsi/gomega/gbytes"
    16  )
    17  
    18  var _ = Describe("marketplace Command", func() {
    19  	var (
    20  		cmd             MarketplaceCommand
    21  		testUI          *ui.UI
    22  		fakeConfig      *commandfakes.FakeConfig
    23  		fakeSharedActor *commandfakes.FakeSharedActor
    24  		fakeActor       *v6fakes.FakeServicesSummariesActor
    25  		binaryName      string
    26  		executeErr      error
    27  		extraArgs       []string
    28  	)
    29  
    30  	BeforeEach(func() {
    31  		testUI = ui.NewTestUI(nil, NewBuffer(), NewBuffer())
    32  		fakeConfig = new(commandfakes.FakeConfig)
    33  		fakeSharedActor = new(commandfakes.FakeSharedActor)
    34  		fakeActor = new(v6fakes.FakeServicesSummariesActor)
    35  
    36  		cmd = MarketplaceCommand{
    37  			UI:          testUI,
    38  			Config:      fakeConfig,
    39  			SharedActor: fakeSharedActor,
    40  			Actor:       fakeActor,
    41  		}
    42  
    43  		binaryName = "faceman"
    44  		fakeConfig.BinaryNameReturns(binaryName)
    45  		extraArgs = nil
    46  	})
    47  
    48  	JustBeforeEach(func() {
    49  		executeErr = cmd.Execute(extraArgs)
    50  	})
    51  
    52  	When("too many arguments are provided", func() {
    53  		BeforeEach(func() {
    54  			extraArgs = []string{"extra"}
    55  		})
    56  
    57  		It("returns a TooManyArgumentsError", func() {
    58  			Expect(executeErr).To(MatchError(translatableerror.TooManyArgumentsError{
    59  				ExtraArgument: "extra",
    60  			}))
    61  		})
    62  	})
    63  
    64  	When("the user is not logged in", func() {
    65  		BeforeEach(func() {
    66  			fakeSharedActor.IsLoggedInReturns(false)
    67  		})
    68  
    69  		Context("and the -s flag is passed", func() {
    70  			BeforeEach(func() {
    71  				cmd.ServiceName = "service-a"
    72  			})
    73  
    74  			When("a service exists that has has multiple plans", func() {
    75  				BeforeEach(func() {
    76  					serviceSummary := v2action.ServiceSummary{
    77  						Service: v2action.Service{
    78  							Label:       "service-a",
    79  							Description: "fake service",
    80  						},
    81  						Plans: []v2action.ServicePlanSummary{
    82  							{
    83  								ServicePlan: v2action.ServicePlan{
    84  									Name:        "plan-a",
    85  									Description: "plan-a-description",
    86  									Free:        false,
    87  								},
    88  							},
    89  							{
    90  								ServicePlan: v2action.ServicePlan{
    91  									Name:        "plan-b",
    92  									Description: "plan-b-description",
    93  									Free:        true,
    94  								},
    95  							},
    96  						},
    97  					}
    98  
    99  					fakeActor.GetServiceSummaryByNameReturns(serviceSummary, v2action.Warnings{"warning"}, nil)
   100  				})
   101  
   102  				It("outputs a header", func() {
   103  					Expect(testUI.Out).To(Say("Getting service plan information for service service-a\\.\\.\\."))
   104  				})
   105  
   106  				It("outputs OK", func() {
   107  					Expect(testUI.Out).To(Say("OK"))
   108  				})
   109  
   110  				It("outputs details about the specific service", func() {
   111  					Expect(testUI.Out).Should(Say(
   112  						"service plan\\s+description\\s+free or paid\n" +
   113  							"plan-a\\s+plan-a-description\\s+paid" +
   114  							"\nplan-b\\s+plan-b-description\\s+free"))
   115  				})
   116  
   117  				It("outputs any warnings", func() {
   118  					Expect(testUI.Err).To(Say("warning"))
   119  				})
   120  			})
   121  
   122  			When("there is an error getting the service", func() {
   123  				BeforeEach(func() {
   124  					fakeActor.GetServiceSummaryByNameReturns(v2action.ServiceSummary{}, v2action.Warnings{"warning"}, errors.New("oops"))
   125  				})
   126  
   127  				It("returns the error", func() {
   128  					Expect(executeErr).To(MatchError("oops"))
   129  				})
   130  
   131  				It("outputs any warnings", func() {
   132  					Expect(testUI.Err).To(Say("warning"))
   133  				})
   134  			})
   135  		})
   136  
   137  		Context("and the -s and --no-plans flags are passed", func() {
   138  			BeforeEach(func() {
   139  				cmd.ServiceName = "service-a"
   140  				cmd.NoPlans = true
   141  			})
   142  
   143  			When("a service exists that has has multiple plans", func() {
   144  				BeforeEach(func() {
   145  					serviceSummary := v2action.ServiceSummary{
   146  						Service: v2action.Service{
   147  							Label:       "service-a",
   148  							Description: "fake service",
   149  						},
   150  						Plans: []v2action.ServicePlanSummary{
   151  							{
   152  								ServicePlan: v2action.ServicePlan{
   153  									Name:        "plan-a",
   154  									Description: "plan-a-description",
   155  									Free:        false,
   156  								},
   157  							},
   158  							{
   159  								ServicePlan: v2action.ServicePlan{
   160  									Name:        "plan-b",
   161  									Description: "plan-b-description",
   162  									Free:        true,
   163  								},
   164  							},
   165  						},
   166  					}
   167  
   168  					fakeActor.GetServiceSummaryByNameReturns(serviceSummary, v2action.Warnings{"warning"}, nil)
   169  				})
   170  
   171  				It("outputs a header", func() {
   172  					Expect(testUI.Out).To(Say("Getting service plan information for service service-a\\.\\.\\."))
   173  				})
   174  
   175  				It("outputs OK", func() {
   176  					Expect(testUI.Out).To(Say("OK"))
   177  				})
   178  
   179  				It("outputs details about the specific service", func() {
   180  					Expect(testUI.Out).Should(Say(
   181  						"service plan\\s+description\\s+free or paid\n" +
   182  							"plan-a\\s+plan-a-description\\s+paid" +
   183  							"\nplan-b\\s+plan-b-description\\s+free"))
   184  				})
   185  
   186  				It("outputs any warnings", func() {
   187  					Expect(testUI.Err).To(Say("warning"))
   188  				})
   189  			})
   190  
   191  			When("there is an error getting the service", func() {
   192  				BeforeEach(func() {
   193  					fakeActor.GetServiceSummaryByNameReturns(v2action.ServiceSummary{}, v2action.Warnings{"warning"}, errors.New("oops"))
   194  				})
   195  
   196  				It("returns the error", func() {
   197  					Expect(executeErr).To(MatchError("oops"))
   198  				})
   199  
   200  				It("outputs any warnings", func() {
   201  					Expect(testUI.Err).To(Say("warning"))
   202  				})
   203  			})
   204  		})
   205  
   206  		When("--no-plans is passed", func() {
   207  			BeforeEach(func() {
   208  				cmd.NoPlans = true
   209  			})
   210  
   211  			When("there are no services available", func() {
   212  				BeforeEach(func() {
   213  					fakeActor.GetServicesSummariesReturns([]v2action.ServiceSummary{}, v2action.Warnings{}, nil)
   214  				})
   215  
   216  				It("outputs a header", func() {
   217  					Expect(testUI.Out).To(Say("Getting all services from marketplace\\.\\.\\."))
   218  				})
   219  
   220  				It("outputs OK", func() {
   221  					Expect(testUI.Out).To(Say("OK"))
   222  				})
   223  
   224  				It("outputs that none are available", func() {
   225  					Expect(testUI.Out).To(Say("No service offerings found"))
   226  				})
   227  			})
   228  
   229  			When("there are multiple services available", func() {
   230  				BeforeEach(func() {
   231  					servicesSummaries := []v2action.ServiceSummary{
   232  						{
   233  							Service: v2action.Service{
   234  								Label:             "service-a",
   235  								Description:       "fake service-a",
   236  								ServiceBrokerName: "broker-a",
   237  							},
   238  							Plans: []v2action.ServicePlanSummary{
   239  								{
   240  									ServicePlan: v2action.ServicePlan{Name: "plan-a"},
   241  								},
   242  								{
   243  									ServicePlan: v2action.ServicePlan{Name: "plan-b"},
   244  								},
   245  							},
   246  						},
   247  						{
   248  							Service: v2action.Service{
   249  								Label:             "service-b",
   250  								Description:       "fake service-b",
   251  								ServiceBrokerName: "broker-b",
   252  							},
   253  							Plans: []v2action.ServicePlanSummary{
   254  								{
   255  									ServicePlan: v2action.ServicePlan{Name: "plan-c"},
   256  								},
   257  							},
   258  						},
   259  					}
   260  
   261  					fakeActor.GetServicesSummariesReturns(servicesSummaries, v2action.Warnings{"warning"}, nil)
   262  				})
   263  
   264  				It("outputs a header", func() {
   265  					Expect(testUI.Out).To(Say("Getting all services from marketplace\\.\\.\\."))
   266  				})
   267  
   268  				It("outputs OK", func() {
   269  					Expect(testUI.Out).To(Say("OK"))
   270  				})
   271  
   272  				It("outputs available services and plans", func() {
   273  					Expect(testUI.Out).Should(Say("service\\s+description\\s+broker\n" +
   274  						"service-a\\s+fake service-a\\s+broker-a\n" +
   275  						"service-b\\s+fake service-b\\s+broker-b"))
   276  				})
   277  
   278  				It("outputs a tip to use the -s flag", func() {
   279  					Expect(testUI.Out).To(Say("TIP: Use 'cf marketplace -s SERVICE' to view descriptions of individual plans of a given service."))
   280  				})
   281  
   282  				It("outputs any warnings", func() {
   283  					Expect(testUI.Err).To(Say("warning"))
   284  				})
   285  			})
   286  		})
   287  
   288  		When("there are no flags passed", func() {
   289  			When("there are no services available", func() {
   290  				BeforeEach(func() {
   291  					fakeActor.GetServicesSummariesReturns([]v2action.ServiceSummary{}, v2action.Warnings{}, nil)
   292  				})
   293  
   294  				It("outputs a header", func() {
   295  					Expect(testUI.Out).To(Say("Getting all services from marketplace\\.\\.\\."))
   296  				})
   297  
   298  				It("outputs OK", func() {
   299  					Expect(testUI.Out).To(Say("OK"))
   300  				})
   301  
   302  				It("outputs that none are available", func() {
   303  					Expect(testUI.Out).To(Say("No service offerings found"))
   304  				})
   305  			})
   306  
   307  			When("there are multiple services available", func() {
   308  				BeforeEach(func() {
   309  					servicesSummaries := []v2action.ServiceSummary{
   310  						{
   311  							Service: v2action.Service{
   312  								Label:             "service-a",
   313  								Description:       "fake service-a",
   314  								ServiceBrokerName: "broker-a",
   315  							},
   316  							Plans: []v2action.ServicePlanSummary{
   317  								{
   318  									ServicePlan: v2action.ServicePlan{Name: "plan-a"},
   319  								},
   320  								{
   321  									ServicePlan: v2action.ServicePlan{Name: "plan-b"},
   322  								},
   323  							},
   324  						},
   325  						{
   326  							Service: v2action.Service{
   327  								Label:             "service-b",
   328  								Description:       "fake service-b",
   329  								ServiceBrokerName: "broker-b",
   330  							},
   331  							Plans: []v2action.ServicePlanSummary{
   332  								{
   333  									ServicePlan: v2action.ServicePlan{Name: "plan-c"},
   334  								},
   335  							},
   336  						},
   337  					}
   338  
   339  					fakeActor.GetServicesSummariesReturns(servicesSummaries, v2action.Warnings{"warning"}, nil)
   340  				})
   341  
   342  				It("outputs a header", func() {
   343  					Expect(testUI.Out).To(Say("Getting all services from marketplace\\.\\.\\."))
   344  				})
   345  
   346  				It("outputs OK", func() {
   347  					Expect(testUI.Out).To(Say("OK"))
   348  				})
   349  
   350  				It("outputs available services and plans", func() {
   351  					Expect(testUI.Out).Should(Say("service\\s+plans\\s+description\\s+broker\n" +
   352  						"service-a\\s+plan-a, plan-b\\s+fake service-a\\s+broker-a\n" +
   353  						"service-b\\s+plan-c\\s+fake service-b\\s+broker-b"))
   354  				})
   355  
   356  				It("outputs a tip to use the -s flag", func() {
   357  					Expect(testUI.Out).To(Say("TIP: Use 'cf marketplace -s SERVICE' to view descriptions of individual plans of a given service."))
   358  				})
   359  
   360  				It("outputs any warnings", func() {
   361  					Expect(testUI.Err).To(Say("warning"))
   362  				})
   363  			})
   364  
   365  			When("there is an error getting the available services", func() {
   366  				BeforeEach(func() {
   367  					fakeActor.GetServicesSummariesReturns([]v2action.ServiceSummary{}, v2action.Warnings{"warning"}, errors.New("oops"))
   368  				})
   369  
   370  				It("returns the error", func() {
   371  					Expect(executeErr).To(MatchError("oops"))
   372  				})
   373  
   374  				It("outputs any warnings", func() {
   375  					Expect(testUI.Err).To(Say("warning"))
   376  				})
   377  			})
   378  		})
   379  	})
   380  
   381  	When("the user is logged in but not targeting an org", func() {
   382  		BeforeEach(func() {
   383  			fakeSharedActor.IsLoggedInReturns(true)
   384  			fakeSharedActor.IsOrgTargetedReturns(false)
   385  		})
   386  
   387  		When("no flags are passed", func() {
   388  			It("returns an error saying the user must have a space targeted", func() {
   389  				Expect(executeErr).To(MatchError("Cannot list marketplace services without a targeted space"))
   390  			})
   391  		})
   392  
   393  		When("the -s flag is passed", func() {
   394  			BeforeEach(func() {
   395  				cmd.ServiceName = "service-a"
   396  			})
   397  
   398  			It("returns an error saying the user must have a space targeted", func() {
   399  				Expect(executeErr).To(MatchError("Cannot list plan information for service-a without a targeted space"))
   400  			})
   401  		})
   402  	})
   403  
   404  	When("the user is logged in and targeting and org but not a space", func() {
   405  		BeforeEach(func() {
   406  			fakeSharedActor.IsLoggedInReturns(true)
   407  			fakeSharedActor.IsOrgTargetedReturns(true)
   408  			fakeSharedActor.IsSpaceTargetedReturns(false)
   409  		})
   410  
   411  		When("no flags are passed", func() {
   412  			It("returns an error saying the user must have a space targeted", func() {
   413  				Expect(executeErr).To(MatchError("Cannot list marketplace services without a targeted space"))
   414  			})
   415  		})
   416  
   417  		When("the -s flag is passed", func() {
   418  			BeforeEach(func() {
   419  				cmd.ServiceName = "service-a"
   420  			})
   421  
   422  			It("returns an error saying the user must have a space targeted", func() {
   423  				Expect(executeErr).To(MatchError("Cannot list plan information for service-a without a targeted space"))
   424  			})
   425  		})
   426  	})
   427  
   428  	When("the user is logged in and targeting an org and space", func() {
   429  		BeforeEach(func() {
   430  			fakeSharedActor.IsLoggedInReturns(true)
   431  			fakeSharedActor.IsOrgTargetedReturns(true)
   432  			fakeSharedActor.IsSpaceTargetedReturns(true)
   433  
   434  			fakeConfig.TargetedOrganizationReturns(configv3.Organization{Name: "org-a"})
   435  			fakeConfig.TargetedSpaceReturns(configv3.Space{Name: "space-a", GUID: "space-guid"})
   436  		})
   437  
   438  		When("fetching the current user fails", func() {
   439  			BeforeEach(func() {
   440  				fakeConfig.CurrentUserReturns(configv3.User{}, errors.New("kaboom"))
   441  			})
   442  
   443  			It("returns the error", func() {
   444  				Expect(executeErr).To(MatchError("kaboom"))
   445  			})
   446  		})
   447  
   448  		When("fetching the user succeeds", func() {
   449  			BeforeEach(func() {
   450  				fakeConfig.CurrentUserReturns(configv3.User{Name: "user-a"}, nil)
   451  			})
   452  
   453  			When("the -s flag is passed", func() {
   454  				BeforeEach(func() {
   455  					cmd.ServiceName = "service-a"
   456  				})
   457  
   458  				When("a service exists that has has multiple plans", func() {
   459  					BeforeEach(func() {
   460  						serviceSummary := v2action.ServiceSummary{
   461  							Service: v2action.Service{
   462  								Label:       "service-a",
   463  								Description: "fake service",
   464  							},
   465  							Plans: []v2action.ServicePlanSummary{
   466  								{
   467  									ServicePlan: v2action.ServicePlan{
   468  										Name:        "plan-a",
   469  										Description: "plan-a-description",
   470  										Free:        false,
   471  									},
   472  								},
   473  								{
   474  									ServicePlan: v2action.ServicePlan{
   475  										Name:        "plan-b",
   476  										Description: "plan-b-description",
   477  										Free:        true,
   478  									},
   479  								},
   480  							},
   481  						}
   482  
   483  						fakeActor.GetServiceSummaryForSpaceByNameReturns(serviceSummary, v2action.Warnings{"warning"}, nil)
   484  					})
   485  
   486  					It("outputs a header", func() {
   487  						Expect(testUI.Out).To(Say("Getting service plan information for service service-a as user-a\\.\\.\\."))
   488  					})
   489  
   490  					It("outputs OK", func() {
   491  						Expect(testUI.Out).To(Say("OK"))
   492  					})
   493  
   494  					It("outputs details about the specific service", func() {
   495  						Expect(testUI.Out).Should(Say(
   496  							"service plan\\s+description\\s+free or paid\n" +
   497  								"plan-a\\s+plan-a-description\\s+paid" +
   498  								"\nplan-b\\s+plan-b-description\\s+free"))
   499  					})
   500  
   501  					It("outputs any warnings", func() {
   502  						Expect(testUI.Err).To(Say("warning"))
   503  					})
   504  				})
   505  
   506  				When("there is an error getting the service", func() {
   507  					BeforeEach(func() {
   508  						fakeActor.GetServiceSummaryForSpaceByNameReturns(v2action.ServiceSummary{}, v2action.Warnings{"warning"}, errors.New("oops"))
   509  					})
   510  
   511  					It("returns the error", func() {
   512  						Expect(executeErr).To(MatchError("oops"))
   513  					})
   514  
   515  					It("outputs any warnings", func() {
   516  						Expect(testUI.Err).To(Say("warning"))
   517  					})
   518  				})
   519  			})
   520  
   521  			When("the -s and --no-plans flags are passed", func() {
   522  				BeforeEach(func() {
   523  					cmd.ServiceName = "service-a"
   524  					cmd.NoPlans = true
   525  				})
   526  
   527  				When("a service exists that has has multiple plans", func() {
   528  					BeforeEach(func() {
   529  						serviceSummary := v2action.ServiceSummary{
   530  							Service: v2action.Service{
   531  								Label:       "service-a",
   532  								Description: "fake service",
   533  							},
   534  							Plans: []v2action.ServicePlanSummary{
   535  								{
   536  									ServicePlan: v2action.ServicePlan{
   537  										Name:        "plan-a",
   538  										Description: "plan-a-description",
   539  										Free:        false,
   540  									},
   541  								},
   542  								{
   543  									ServicePlan: v2action.ServicePlan{
   544  										Name:        "plan-b",
   545  										Description: "plan-b-description",
   546  										Free:        true,
   547  									},
   548  								},
   549  							},
   550  						}
   551  
   552  						fakeActor.GetServiceSummaryForSpaceByNameReturns(serviceSummary, v2action.Warnings{"warning"}, nil)
   553  					})
   554  
   555  					It("outputs a header", func() {
   556  						Expect(testUI.Out).To(Say("Getting service plan information for service service-a as user-a\\.\\.\\."))
   557  					})
   558  
   559  					It("outputs OK", func() {
   560  						Expect(testUI.Out).To(Say("OK"))
   561  					})
   562  
   563  					It("outputs details about the specific service", func() {
   564  						Expect(testUI.Out).Should(Say(
   565  							"service plan\\s+description\\s+free or paid\n" +
   566  								"plan-a\\s+plan-a-description\\s+paid" +
   567  								"\nplan-b\\s+plan-b-description\\s+free"))
   568  					})
   569  
   570  					It("outputs any warnings", func() {
   571  						Expect(testUI.Err).To(Say("warning"))
   572  					})
   573  				})
   574  
   575  				When("there is an error getting the service", func() {
   576  					BeforeEach(func() {
   577  						fakeActor.GetServiceSummaryForSpaceByNameReturns(v2action.ServiceSummary{}, v2action.Warnings{"warning"}, errors.New("oops"))
   578  					})
   579  
   580  					It("returns the error", func() {
   581  						Expect(executeErr).To(MatchError("oops"))
   582  					})
   583  
   584  					It("outputs any warnings", func() {
   585  						Expect(testUI.Err).To(Say("warning"))
   586  					})
   587  				})
   588  			})
   589  
   590  			When("--no-plans is passed", func() {
   591  				BeforeEach(func() {
   592  					cmd.NoPlans = true
   593  				})
   594  
   595  				When("there are no services available", func() {
   596  					BeforeEach(func() {
   597  						fakeActor.GetServicesSummariesReturns([]v2action.ServiceSummary{}, v2action.Warnings{}, nil)
   598  					})
   599  
   600  					It("outputs a header", func() {
   601  						Expect(testUI.Out).To(Say("Getting services from marketplace in org org-a / space space-a as user-a\\.\\.\\."))
   602  					})
   603  
   604  					It("outputs OK", func() {
   605  						Expect(testUI.Out).To(Say("OK"))
   606  					})
   607  
   608  					It("outputs that none are available", func() {
   609  						Expect(testUI.Out).To(Say("No service offerings found"))
   610  					})
   611  				})
   612  
   613  				When("there are multiple services available", func() {
   614  					BeforeEach(func() {
   615  						servicesSummaries := []v2action.ServiceSummary{
   616  							{
   617  								Service: v2action.Service{
   618  									Label:             "service-a",
   619  									Description:       "fake service-a",
   620  									ServiceBrokerName: "broker-a",
   621  								},
   622  								Plans: []v2action.ServicePlanSummary{
   623  									{
   624  										ServicePlan: v2action.ServicePlan{Name: "plan-a"},
   625  									},
   626  									{
   627  										ServicePlan: v2action.ServicePlan{Name: "plan-b"},
   628  									},
   629  								},
   630  							},
   631  							{
   632  								Service: v2action.Service{
   633  									Label:             "service-b",
   634  									Description:       "fake service-b",
   635  									ServiceBrokerName: "broker-b",
   636  								},
   637  								Plans: []v2action.ServicePlanSummary{
   638  									{
   639  										ServicePlan: v2action.ServicePlan{Name: "plan-c"},
   640  									},
   641  								},
   642  							},
   643  						}
   644  
   645  						fakeActor.GetServicesSummariesForSpaceReturns(servicesSummaries, v2action.Warnings{"warning"}, nil)
   646  					})
   647  
   648  					It("outputs a header", func() {
   649  						Expect(testUI.Out).To(Say("Getting services from marketplace in org org-a / space space-a as user-a\\.\\.\\."))
   650  					})
   651  
   652  					It("outputs OK", func() {
   653  						Expect(testUI.Out).To(Say("OK"))
   654  					})
   655  
   656  					It("outputs available services and plans", func() {
   657  						Expect(testUI.Out).Should(Say("service\\s+description\\s+broker\n" +
   658  							"service-a\\s+fake service-a\\s+broker-a\n" +
   659  							"service-b\\s+fake service-b\\s+broker-b"))
   660  					})
   661  
   662  					It("outputs a tip to use the -s flag", func() {
   663  						Expect(testUI.Out).To(Say("TIP: Use 'cf marketplace -s SERVICE' to view descriptions of individual plans of a given service."))
   664  					})
   665  
   666  					It("outputs any warnings", func() {
   667  						Expect(testUI.Err).To(Say("warning"))
   668  					})
   669  				})
   670  			})
   671  
   672  			Context("and there are no flags passed", func() {
   673  				When("there are no services available", func() {
   674  					BeforeEach(func() {
   675  						fakeActor.GetServicesSummariesForSpaceReturns([]v2action.ServiceSummary{}, v2action.Warnings{}, nil)
   676  					})
   677  
   678  					It("gets services for the correct space", func() {
   679  						Expect(fakeActor.GetServicesSummariesForSpaceArgsForCall(0)).To(Equal("space-guid"))
   680  					})
   681  
   682  					It("outputs a header", func() {
   683  						Expect(testUI.Out).To(Say("Getting services from marketplace in org org-a / space space-a as user-a\\.\\.\\."))
   684  					})
   685  
   686  					It("outputs OK", func() {
   687  						Expect(testUI.Out).To(Say("OK"))
   688  					})
   689  
   690  					It("outputs that no services are available", func() {
   691  						Expect(testUI.Out).To(Say("No service offerings found"))
   692  					})
   693  				})
   694  
   695  				When("there are multiple services available", func() {
   696  					BeforeEach(func() {
   697  						servicesSummaries := []v2action.ServiceSummary{
   698  							{
   699  								Service: v2action.Service{
   700  									Label:             "service-a",
   701  									Description:       "fake service-a",
   702  									ServiceBrokerName: "broker-a",
   703  								},
   704  								Plans: []v2action.ServicePlanSummary{
   705  									{
   706  										ServicePlan: v2action.ServicePlan{Name: "plan-a"},
   707  									},
   708  									{
   709  										ServicePlan: v2action.ServicePlan{Name: "plan-b"},
   710  									},
   711  								},
   712  							},
   713  							{
   714  								Service: v2action.Service{
   715  									Label:             "service-b",
   716  									Description:       "fake service-b",
   717  									ServiceBrokerName: "broker-b",
   718  								},
   719  								Plans: []v2action.ServicePlanSummary{
   720  									{
   721  										ServicePlan: v2action.ServicePlan{Name: "plan-c"},
   722  									},
   723  								},
   724  							},
   725  						}
   726  
   727  						fakeActor.GetServicesSummariesForSpaceReturns(servicesSummaries, v2action.Warnings{"warning"}, nil)
   728  					})
   729  
   730  					It("gets services for the correct space", func() {
   731  						Expect(fakeActor.GetServicesSummariesForSpaceArgsForCall(0)).To(Equal("space-guid"))
   732  					})
   733  
   734  					It("outputs a header", func() {
   735  						Expect(testUI.Out).To(Say("Getting services from marketplace in org org-a / space space-a as user-a\\.\\.\\."))
   736  					})
   737  
   738  					It("outputs OK", func() {
   739  						Expect(testUI.Out).To(Say("OK"))
   740  					})
   741  
   742  					It("outputs available services and plans", func() {
   743  						Expect(testUI.Out).Should(Say("service\\s+plans\\s+description\\s+broker\n" +
   744  							"service-a\\s+plan-a, plan-b\\s+fake service-a\\s+broker-a\n" +
   745  							"service-b\\s+plan-c\\s+fake service-b\\s+broker-b"))
   746  					})
   747  
   748  					It("outputs a tip to use the -s flag", func() {
   749  						Expect(testUI.Out).To(Say("TIP: Use 'cf marketplace -s SERVICE' to view descriptions of individual plans of a given service."))
   750  					})
   751  
   752  					It("outputs any warnings", func() {
   753  						Expect(testUI.Err).To(Say("warning"))
   754  					})
   755  				})
   756  
   757  				When("there is an error getting the available services", func() {
   758  					BeforeEach(func() {
   759  						fakeActor.GetServicesSummariesForSpaceReturns([]v2action.ServiceSummary{}, v2action.Warnings{"warning"}, errors.New("oops"))
   760  					})
   761  
   762  					It("returns the error", func() {
   763  						Expect(executeErr).To(MatchError("oops"))
   764  					})
   765  
   766  					It("outputs any warnings", func() {
   767  						Expect(testUI.Err).To(Say("warning"))
   768  					})
   769  				})
   770  			})
   771  		})
   772  	})
   773  
   774  })