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  })