github.com/cloudfoundry/cli@v7.1.0+incompatible/cf/commands/service/update_user_provided_service_test.go (about)

     1  package service_test
     2  
     3  import (
     4  	"errors"
     5  	"io/ioutil"
     6  	"os"
     7  
     8  	"code.cloudfoundry.org/cli/cf/commandregistry"
     9  	"code.cloudfoundry.org/cli/cf/commands/service"
    10  	"code.cloudfoundry.org/cli/cf/configuration/coreconfig"
    11  	"code.cloudfoundry.org/cli/cf/flags"
    12  	"code.cloudfoundry.org/cli/cf/models"
    13  	"code.cloudfoundry.org/cli/cf/requirements"
    14  	"code.cloudfoundry.org/cli/cf/requirements/requirementsfakes"
    15  	"github.com/blang/semver"
    16  
    17  	"code.cloudfoundry.org/cli/cf/api/apifakes"
    18  	testconfig "code.cloudfoundry.org/cli/cf/util/testhelpers/configuration"
    19  	testterm "code.cloudfoundry.org/cli/cf/util/testhelpers/terminal"
    20  
    21  	. "code.cloudfoundry.org/cli/cf/util/testhelpers/matchers"
    22  	. "github.com/onsi/ginkgo"
    23  	. "github.com/onsi/gomega"
    24  )
    25  
    26  var _ = Describe("UpdateUserProvidedService", func() {
    27  	var (
    28  		ui                  *testterm.FakeUI
    29  		configRepo          coreconfig.Repository
    30  		serviceInstanceRepo *apifakes.FakeUserProvidedServiceInstanceRepository
    31  
    32  		cmd         commandregistry.Command
    33  		deps        commandregistry.Dependency
    34  		factory     *requirementsfakes.FakeFactory
    35  		flagContext flags.FlagContext
    36  
    37  		loginRequirement           requirements.Requirement
    38  		minAPIVersionRequirement   requirements.Requirement
    39  		serviceInstanceRequirement *requirementsfakes.FakeServiceInstanceRequirement
    40  	)
    41  
    42  	BeforeEach(func() {
    43  		ui = &testterm.FakeUI{}
    44  		configRepo = testconfig.NewRepositoryWithDefaults()
    45  		serviceInstanceRepo = new(apifakes.FakeUserProvidedServiceInstanceRepository)
    46  		repoLocator := deps.RepoLocator.SetUserProvidedServiceInstanceRepository(serviceInstanceRepo)
    47  
    48  		deps = commandregistry.Dependency{
    49  			UI:          ui,
    50  			Config:      configRepo,
    51  			RepoLocator: repoLocator,
    52  		}
    53  
    54  		cmd = &service.UpdateUserProvidedService{}
    55  		cmd.SetDependency(deps, false)
    56  
    57  		flagContext = flags.NewFlagContext(cmd.MetaData().Flags)
    58  		factory = new(requirementsfakes.FakeFactory)
    59  
    60  		loginRequirement = &passingRequirement{Name: "login-requirement"}
    61  		factory.NewLoginRequirementReturns(loginRequirement)
    62  
    63  		minAPIVersionRequirement = &passingRequirement{Name: "min-api-version-requirement"}
    64  		factory.NewMinAPIVersionRequirementReturns(minAPIVersionRequirement)
    65  
    66  		serviceInstanceRequirement = new(requirementsfakes.FakeServiceInstanceRequirement)
    67  		factory.NewServiceInstanceRequirementReturns(serviceInstanceRequirement)
    68  	})
    69  
    70  	Describe("Requirements", func() {
    71  		Context("when not provided exactly one arg", func() {
    72  			BeforeEach(func() {
    73  				flagContext.Parse("service-instance", "extra-arg")
    74  			})
    75  
    76  			It("fails with usage", func() {
    77  				_, err := cmd.Requirements(factory, flagContext)
    78  				Expect(err).To(HaveOccurred())
    79  				Expect(ui.Outputs()).To(ContainSubstrings(
    80  					[]string{"FAILED"},
    81  					[]string{"Incorrect Usage. Requires an argument"},
    82  				))
    83  			})
    84  		})
    85  
    86  		Context("when provided exactly one arg", func() {
    87  			BeforeEach(func() {
    88  				flagContext.Parse("service-instance")
    89  			})
    90  
    91  			It("returns a LoginRequirement", func() {
    92  				actualRequirements, err := cmd.Requirements(factory, flagContext)
    93  				Expect(err).NotTo(HaveOccurred())
    94  				Expect(factory.NewLoginRequirementCallCount()).To(Equal(1))
    95  				Expect(actualRequirements).To(ContainElement(loginRequirement))
    96  			})
    97  		})
    98  
    99  		Context("when provided the -t flag", func() {
   100  			BeforeEach(func() {
   101  				flagContext.Parse("service-instance", "-t", "tag,a,service")
   102  			})
   103  
   104  			It("returns a MinAPIVersionRequirement", func() {
   105  				actualRequirements, err := cmd.Requirements(factory, flagContext)
   106  				Expect(err).NotTo(HaveOccurred())
   107  				Expect(factory.NewMinAPIVersionRequirementCallCount()).To(Equal(1))
   108  				Expect(actualRequirements).To(ContainElement(minAPIVersionRequirement))
   109  
   110  				feature, requiredVersion := factory.NewMinAPIVersionRequirementArgsForCall(0)
   111  				Expect(feature).To(Equal("Option '-t'"))
   112  				expectedRequiredVersion, err := semver.Make("2.104.0")
   113  				Expect(err).NotTo(HaveOccurred())
   114  				Expect(requiredVersion).To(Equal(expectedRequiredVersion))
   115  			})
   116  		})
   117  	})
   118  
   119  	Describe("Execute", func() {
   120  		var runCLIErr error
   121  
   122  		BeforeEach(func() {
   123  			err := flagContext.Parse("service-instance")
   124  			Expect(err).NotTo(HaveOccurred())
   125  			cmd.Requirements(factory, flagContext)
   126  		})
   127  
   128  		JustBeforeEach(func() {
   129  			runCLIErr = cmd.Execute(flagContext)
   130  		})
   131  
   132  		Context("when the service instance is not user-provided", func() {
   133  			BeforeEach(func() {
   134  				serviceInstanceRequirement.GetServiceInstanceReturns(models.ServiceInstance{
   135  					ServicePlan: models.ServicePlanFields{
   136  						GUID: "service-plan-guid",
   137  					},
   138  				})
   139  			})
   140  
   141  			It("fails with error", func() {
   142  				Expect(runCLIErr).To(HaveOccurred())
   143  			})
   144  		})
   145  
   146  		Context("when the service instance is user-provided", func() {
   147  			var serviceInstance models.ServiceInstance
   148  
   149  			BeforeEach(func() {
   150  				serviceInstance = models.ServiceInstance{
   151  					ServiceInstanceFields: models.ServiceInstanceFields{
   152  						Name:   "service-instance",
   153  						Params: map[string]interface{}{},
   154  						Type:   "user_provided_service_instance",
   155  					},
   156  					ServicePlan: models.ServicePlanFields{
   157  						GUID:        "",
   158  						Description: "service-plan-description",
   159  					},
   160  				}
   161  				serviceInstanceRequirement.GetServiceInstanceReturns(serviceInstance)
   162  			})
   163  
   164  			It("tells the user it is updating the user provided service", func() {
   165  				Expect(runCLIErr).NotTo(HaveOccurred())
   166  				Expect(ui.Outputs()).To(ContainSubstrings(
   167  					[]string{"Updating user provided service service-instance in org"},
   168  				))
   169  			})
   170  
   171  			It("tries to update the service instance", func() {
   172  				Expect(runCLIErr).NotTo(HaveOccurred())
   173  				Expect(serviceInstanceRepo.UpdateCallCount()).To(Equal(1))
   174  				expectedFields := serviceInstance.ServiceInstanceFields
   175  				expectedFields.Tags = []string{}
   176  				Expect(serviceInstanceRepo.UpdateArgsForCall(0)).To(Equal(expectedFields))
   177  			})
   178  
   179  			It("tells the user no changes were made", func() {
   180  				Expect(runCLIErr).NotTo(HaveOccurred())
   181  				Expect(ui.Outputs()).To(ContainSubstrings(
   182  					[]string{"No flags specified. No changes were made."},
   183  				))
   184  			})
   185  
   186  			Context("when the -p flag is passed with inline JSON", func() {
   187  				BeforeEach(func() {
   188  					flagContext.Parse("service-instance", "-p", `"{"some":"json"}"`)
   189  				})
   190  
   191  				It("tries to update the user provided service instance with the credentials", func() {
   192  					Expect(runCLIErr).NotTo(HaveOccurred())
   193  					Expect(serviceInstanceRepo.UpdateCallCount()).To(Equal(1))
   194  					serviceInstanceFields := serviceInstanceRepo.UpdateArgsForCall(0)
   195  					Expect(serviceInstanceFields.Params).To(Equal(map[string]interface{}{
   196  						"some": "json",
   197  					}))
   198  				})
   199  
   200  				It("does not tell the user that no changes were made", func() {
   201  					Expect(ui.Outputs()).NotTo(ContainSubstrings(
   202  						[]string{"No flags specified. No changes were made."},
   203  					))
   204  				})
   205  			})
   206  
   207  			Context("when the -p flag is passed with a file containing JSON", func() {
   208  				var filename string
   209  
   210  				BeforeEach(func() {
   211  					tempfile, err := ioutil.TempFile("", "update-user-provided-service-test")
   212  					Expect(err).NotTo(HaveOccurred())
   213  					Expect(tempfile.Close()).NotTo(HaveOccurred())
   214  					filename = tempfile.Name()
   215  
   216  					jsonData := `{"some":"json"}`
   217  					ioutil.WriteFile(filename, []byte(jsonData), os.ModePerm)
   218  					flagContext.Parse("service-instance", "-p", filename)
   219  				})
   220  
   221  				AfterEach(func() {
   222  					Expect(os.RemoveAll(filename)).NotTo(HaveOccurred())
   223  				})
   224  
   225  				It("tries to update the user provided service instance with the credentials", func() {
   226  					Expect(runCLIErr).NotTo(HaveOccurred())
   227  					Expect(serviceInstanceRepo.UpdateCallCount()).To(Equal(1))
   228  					serviceInstanceFields := serviceInstanceRepo.UpdateArgsForCall(0)
   229  					Expect(serviceInstanceFields.Params).To(Equal(map[string]interface{}{
   230  						"some": "json",
   231  					}))
   232  				})
   233  
   234  				It("does not tell the user that no changes were made", func() {
   235  					Expect(ui.Outputs()).NotTo(ContainSubstrings(
   236  						[]string{"No flags specified. No changes were made."},
   237  					))
   238  				})
   239  			})
   240  
   241  			Context("when the -p flag is passed with inline JSON", func() {
   242  				BeforeEach(func() {
   243  					flagContext.Parse("service-instance", "-p", `key1,key2`)
   244  					ui.Inputs = []string{"value1", "value2"}
   245  				})
   246  
   247  				It("prompts the user for the values", func() {
   248  					Expect(runCLIErr).NotTo(HaveOccurred())
   249  					Expect(ui.Prompts).To(ContainSubstrings(
   250  						[]string{"key1"},
   251  						[]string{"key2"},
   252  					))
   253  				})
   254  
   255  				It("tries to update the user provided service instance with the credentials", func() {
   256  					Expect(runCLIErr).NotTo(HaveOccurred())
   257  
   258  					Expect(serviceInstanceRepo.UpdateCallCount()).To(Equal(1))
   259  					serviceInstanceFields := serviceInstanceRepo.UpdateArgsForCall(0)
   260  					Expect(serviceInstanceFields.Params).To(Equal(map[string]interface{}{
   261  						"key1": "value1",
   262  						"key2": "value2",
   263  					}))
   264  				})
   265  
   266  				It("does not tell the user that no changes were made", func() {
   267  					Expect(ui.Outputs()).NotTo(ContainSubstrings(
   268  						[]string{"No flags specified. No changes were made."},
   269  					))
   270  				})
   271  			})
   272  
   273  			Context("when passing in tags", func() {
   274  				BeforeEach(func() {
   275  					flagContext.Parse("service-instance", "-t", "tag1, tag2, tag3, tag4")
   276  				})
   277  
   278  				It("sucessfully updates the service instance and passes the tags as json", func() {
   279  					Expect(runCLIErr).NotTo(HaveOccurred())
   280  					Expect(serviceInstanceRepo.UpdateCallCount()).To(Equal(1))
   281  					serviceInstanceFields := serviceInstanceRepo.UpdateArgsForCall(0)
   282  					Expect(serviceInstanceFields.Tags).To(ConsistOf("tag1", "tag2", "tag3", "tag4"))
   283  				})
   284  
   285  				It("does not tell the user that no changes were made", func() {
   286  					Expect(ui.Outputs()).NotTo(ContainSubstrings(
   287  						[]string{"No flags specified. No changes were made."},
   288  					))
   289  				})
   290  			})
   291  
   292  			Context("when updating succeeds", func() {
   293  				BeforeEach(func() {
   294  					serviceInstanceRepo.UpdateReturns(nil)
   295  				})
   296  
   297  				It("tells the user OK", func() {
   298  					Expect(runCLIErr).NotTo(HaveOccurred())
   299  					Expect(ui.Outputs()).To(ContainSubstrings(
   300  						[]string{"OK"},
   301  					))
   302  				})
   303  
   304  				It("prints a tip", func() {
   305  					Expect(runCLIErr).NotTo(HaveOccurred())
   306  					Expect(ui.Outputs()).To(ContainSubstrings(
   307  						[]string{"TIP"},
   308  					))
   309  				})
   310  			})
   311  
   312  			Context("when updating fails", func() {
   313  				BeforeEach(func() {
   314  					serviceInstanceRepo.UpdateReturns(errors.New("update-err"))
   315  				})
   316  
   317  				It("fails with error", func() {
   318  					Expect(runCLIErr).To(HaveOccurred())
   319  					Expect(runCLIErr.Error()).To(Equal("update-err"))
   320  				})
   321  			})
   322  		})
   323  	})
   324  })