github.com/willmadison/cli@v6.40.1-0.20181018160101-29d5937903ff+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  					},
   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  				expectedFields := serviceInstance.ServiceInstanceFields
   174  				expectedFields.Tags = []string{}
   175  				Expect(serviceInstanceRepo.UpdateArgsForCall(0)).To(Equal(expectedFields))
   176  			})
   177  
   178  			It("tells the user no changes were made", func() {
   179  				Expect(runCLIErr).NotTo(HaveOccurred())
   180  				Expect(ui.Outputs()).To(ContainSubstrings(
   181  					[]string{"No flags specified. No changes were made."},
   182  				))
   183  			})
   184  
   185  			Context("when the -p flag is passed with inline JSON", func() {
   186  				BeforeEach(func() {
   187  					flagContext.Parse("service-instance", "-p", `"{"some":"json"}"`)
   188  				})
   189  
   190  				It("tries to update the user provided service instance with the credentials", func() {
   191  					Expect(runCLIErr).NotTo(HaveOccurred())
   192  					Expect(serviceInstanceRepo.UpdateCallCount()).To(Equal(1))
   193  					serviceInstanceFields := serviceInstanceRepo.UpdateArgsForCall(0)
   194  					Expect(serviceInstanceFields.Params).To(Equal(map[string]interface{}{
   195  						"some": "json",
   196  					}))
   197  				})
   198  
   199  				It("does not tell the user that no changes were made", func() {
   200  					Expect(ui.Outputs()).NotTo(ContainSubstrings(
   201  						[]string{"No flags specified. No changes were made."},
   202  					))
   203  				})
   204  			})
   205  
   206  			Context("when the -p flag is passed with a file containing JSON", func() {
   207  				var filename string
   208  
   209  				BeforeEach(func() {
   210  					tempfile, err := ioutil.TempFile("", "update-user-provided-service-test")
   211  					Expect(err).NotTo(HaveOccurred())
   212  					Expect(tempfile.Close()).NotTo(HaveOccurred())
   213  					filename = tempfile.Name()
   214  
   215  					jsonData := `{"some":"json"}`
   216  					ioutil.WriteFile(filename, []byte(jsonData), os.ModePerm)
   217  					flagContext.Parse("service-instance", "-p", filename)
   218  				})
   219  
   220  				AfterEach(func() {
   221  					Expect(os.RemoveAll(filename)).NotTo(HaveOccurred())
   222  				})
   223  
   224  				It("tries to update the user provided service instance with the credentials", func() {
   225  					Expect(runCLIErr).NotTo(HaveOccurred())
   226  					Expect(serviceInstanceRepo.UpdateCallCount()).To(Equal(1))
   227  					serviceInstanceFields := serviceInstanceRepo.UpdateArgsForCall(0)
   228  					Expect(serviceInstanceFields.Params).To(Equal(map[string]interface{}{
   229  						"some": "json",
   230  					}))
   231  				})
   232  
   233  				It("does not tell the user that no changes were made", func() {
   234  					Expect(ui.Outputs()).NotTo(ContainSubstrings(
   235  						[]string{"No flags specified. No changes were made."},
   236  					))
   237  				})
   238  			})
   239  
   240  			Context("when the -p flag is passed with inline JSON", func() {
   241  				BeforeEach(func() {
   242  					flagContext.Parse("service-instance", "-p", `key1,key2`)
   243  					ui.Inputs = []string{"value1", "value2"}
   244  				})
   245  
   246  				It("prompts the user for the values", func() {
   247  					Expect(runCLIErr).NotTo(HaveOccurred())
   248  					Expect(ui.Prompts).To(ContainSubstrings(
   249  						[]string{"key1"},
   250  						[]string{"key2"},
   251  					))
   252  				})
   253  
   254  				It("tries to update the user provided service instance with the credentials", func() {
   255  					Expect(runCLIErr).NotTo(HaveOccurred())
   256  
   257  					Expect(serviceInstanceRepo.UpdateCallCount()).To(Equal(1))
   258  					serviceInstanceFields := serviceInstanceRepo.UpdateArgsForCall(0)
   259  					Expect(serviceInstanceFields.Params).To(Equal(map[string]interface{}{
   260  						"key1": "value1",
   261  						"key2": "value2",
   262  					}))
   263  				})
   264  
   265  				It("does not tell the user that no changes were made", func() {
   266  					Expect(ui.Outputs()).NotTo(ContainSubstrings(
   267  						[]string{"No flags specified. No changes were made."},
   268  					))
   269  				})
   270  			})
   271  
   272  			Context("when passing in tags", func() {
   273  				BeforeEach(func() {
   274  					flagContext.Parse("service-instance", "-t", "tag1, tag2, tag3, tag4")
   275  				})
   276  
   277  				It("sucessfully updates the service instance and passes the tags as json", func() {
   278  					Expect(runCLIErr).NotTo(HaveOccurred())
   279  					Expect(serviceInstanceRepo.UpdateCallCount()).To(Equal(1))
   280  					serviceInstanceFields := serviceInstanceRepo.UpdateArgsForCall(0)
   281  					Expect(serviceInstanceFields.Tags).To(ConsistOf("tag1", "tag2", "tag3", "tag4"))
   282  				})
   283  
   284  				It("does not tell the user that no changes were made", func() {
   285  					Expect(ui.Outputs()).NotTo(ContainSubstrings(
   286  						[]string{"No flags specified. No changes were made."},
   287  					))
   288  				})
   289  			})
   290  
   291  			Context("when updating succeeds", func() {
   292  				BeforeEach(func() {
   293  					serviceInstanceRepo.UpdateReturns(nil)
   294  				})
   295  
   296  				It("tells the user OK", func() {
   297  					Expect(runCLIErr).NotTo(HaveOccurred())
   298  					Expect(ui.Outputs()).To(ContainSubstrings(
   299  						[]string{"OK"},
   300  					))
   301  				})
   302  
   303  				It("prints a tip", func() {
   304  					Expect(runCLIErr).NotTo(HaveOccurred())
   305  					Expect(ui.Outputs()).To(ContainSubstrings(
   306  						[]string{"TIP"},
   307  					))
   308  				})
   309  			})
   310  
   311  			Context("when updating fails", func() {
   312  				BeforeEach(func() {
   313  					serviceInstanceRepo.UpdateReturns(errors.New("update-err"))
   314  				})
   315  
   316  				It("fails with error", func() {
   317  					Expect(runCLIErr).To(HaveOccurred())
   318  					Expect(runCLIErr.Error()).To(Equal("update-err"))
   319  				})
   320  			})
   321  		})
   322  	})
   323  })