github.com/loggregator/cli@v6.33.1-0.20180224010324-82334f081791+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/util/testhelpers/configuration"
    19  	testterm "code.cloudfoundry.org/cli/util/testhelpers/terminal"
    20  
    21  	. "code.cloudfoundry.org/cli/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 -r flag", func() {
   100  			BeforeEach(func() {
   101  				flagContext.Parse("service-instance", "-r", "route-service-url")
   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 '-r'"))
   112  				expectedRequiredVersion, err := semver.Make("2.51.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  					},
   155  					ServicePlan: models.ServicePlanFields{
   156  						GUID:        "",
   157  						Description: "service-plan-description",
   158  					},
   159  				}
   160  				serviceInstanceRequirement.GetServiceInstanceReturns(serviceInstance)
   161  			})
   162  
   163  			It("tells the user it is updating the user provided service", func() {
   164  				Expect(runCLIErr).NotTo(HaveOccurred())
   165  				Expect(ui.Outputs()).To(ContainSubstrings(
   166  					[]string{"Updating user provided service service-instance in org"},
   167  				))
   168  			})
   169  
   170  			It("tries to update the service instance", func() {
   171  				Expect(runCLIErr).NotTo(HaveOccurred())
   172  				Expect(serviceInstanceRepo.UpdateCallCount()).To(Equal(1))
   173  				Expect(serviceInstanceRepo.UpdateArgsForCall(0)).To(Equal(serviceInstance.ServiceInstanceFields))
   174  			})
   175  
   176  			It("tells the user no changes were made", func() {
   177  				Expect(runCLIErr).NotTo(HaveOccurred())
   178  				Expect(ui.Outputs()).To(ContainSubstrings(
   179  					[]string{"No flags specified. No changes were made."},
   180  				))
   181  			})
   182  
   183  			Context("when the -p flag is passed with inline JSON", func() {
   184  				BeforeEach(func() {
   185  					flagContext.Parse("service-instance", "-p", `"{"some":"json"}"`)
   186  				})
   187  
   188  				It("tries to update the user provided service instance with the credentials", func() {
   189  					Expect(runCLIErr).NotTo(HaveOccurred())
   190  					Expect(serviceInstanceRepo.UpdateCallCount()).To(Equal(1))
   191  					serviceInstanceFields := serviceInstanceRepo.UpdateArgsForCall(0)
   192  					Expect(serviceInstanceFields.Params).To(Equal(map[string]interface{}{
   193  						"some": "json",
   194  					}))
   195  				})
   196  			})
   197  
   198  			Context("when the -p flag is passed with a file containing JSON", func() {
   199  				var filename string
   200  
   201  				BeforeEach(func() {
   202  					tempfile, err := ioutil.TempFile("", "update-user-provided-service-test")
   203  					Expect(err).NotTo(HaveOccurred())
   204  					Expect(tempfile.Close()).NotTo(HaveOccurred())
   205  					filename = tempfile.Name()
   206  
   207  					jsonData := `{"some":"json"}`
   208  					ioutil.WriteFile(filename, []byte(jsonData), os.ModePerm)
   209  					flagContext.Parse("service-instance", "-p", filename)
   210  				})
   211  
   212  				AfterEach(func() {
   213  					Expect(os.RemoveAll(filename)).NotTo(HaveOccurred())
   214  				})
   215  
   216  				It("tries to update the user provided service instance with the credentials", func() {
   217  					Expect(runCLIErr).NotTo(HaveOccurred())
   218  					Expect(serviceInstanceRepo.UpdateCallCount()).To(Equal(1))
   219  					serviceInstanceFields := serviceInstanceRepo.UpdateArgsForCall(0)
   220  					Expect(serviceInstanceFields.Params).To(Equal(map[string]interface{}{
   221  						"some": "json",
   222  					}))
   223  				})
   224  			})
   225  
   226  			Context("when the -p flag is passed with inline JSON", func() {
   227  				BeforeEach(func() {
   228  					flagContext.Parse("service-instance", "-p", `key1,key2`)
   229  					ui.Inputs = []string{"value1", "value2"}
   230  				})
   231  
   232  				It("prompts the user for the values", func() {
   233  					Expect(runCLIErr).NotTo(HaveOccurred())
   234  					Expect(ui.Prompts).To(ContainSubstrings(
   235  						[]string{"key1"},
   236  						[]string{"key2"},
   237  					))
   238  				})
   239  
   240  				It("tries to update the user provided service instance with the credentials", func() {
   241  					Expect(runCLIErr).NotTo(HaveOccurred())
   242  
   243  					Expect(serviceInstanceRepo.UpdateCallCount()).To(Equal(1))
   244  					serviceInstanceFields := serviceInstanceRepo.UpdateArgsForCall(0)
   245  					Expect(serviceInstanceFields.Params).To(Equal(map[string]interface{}{
   246  						"key1": "value1",
   247  						"key2": "value2",
   248  					}))
   249  				})
   250  			})
   251  
   252  			Context("when updating succeeds", func() {
   253  				BeforeEach(func() {
   254  					serviceInstanceRepo.UpdateReturns(nil)
   255  				})
   256  
   257  				It("tells the user OK", func() {
   258  					Expect(runCLIErr).NotTo(HaveOccurred())
   259  					Expect(ui.Outputs()).To(ContainSubstrings(
   260  						[]string{"OK"},
   261  					))
   262  				})
   263  
   264  				It("prints a tip", func() {
   265  					Expect(runCLIErr).NotTo(HaveOccurred())
   266  					Expect(ui.Outputs()).To(ContainSubstrings(
   267  						[]string{"TIP"},
   268  					))
   269  				})
   270  			})
   271  
   272  			Context("when updating fails", func() {
   273  				BeforeEach(func() {
   274  					serviceInstanceRepo.UpdateReturns(errors.New("update-err"))
   275  				})
   276  
   277  				It("fails with error", func() {
   278  					Expect(runCLIErr).To(HaveOccurred())
   279  					Expect(runCLIErr.Error()).To(Equal("update-err"))
   280  				})
   281  			})
   282  		})
   283  	})
   284  })