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

     1  package v6_test
     2  
     3  import (
     4  	"encoding/json"
     5  	"errors"
     6  	"fmt"
     7  
     8  	"code.cloudfoundry.org/cli/actor/v2action"
     9  	"code.cloudfoundry.org/cli/api/cloudcontroller/ccv2/constant"
    10  	"code.cloudfoundry.org/cli/command/commandfakes"
    11  	"code.cloudfoundry.org/cli/command/flag"
    12  	. "code.cloudfoundry.org/cli/command/v6"
    13  	"code.cloudfoundry.org/cli/command/v6/v6fakes"
    14  	"code.cloudfoundry.org/cli/util/configv3"
    15  	"code.cloudfoundry.org/cli/util/ui"
    16  	. "github.com/onsi/ginkgo"
    17  	. "github.com/onsi/gomega"
    18  	. "github.com/onsi/gomega/gbytes"
    19  	. "github.com/onsi/gomega/gstruct"
    20  )
    21  
    22  var _ = Describe("update-user-provided-service Command", func() {
    23  	const (
    24  		fakeServiceInstanceName = "fake-service-instance-name"
    25  	)
    26  
    27  	var (
    28  		cmd             *UpdateUserProvidedServiceCommand
    29  		fakeConfig      *commandfakes.FakeConfig
    30  		fakeSharedActor *commandfakes.FakeSharedActor
    31  		fakeActor       *v6fakes.FakeUpdateUserProvidedServiceActor
    32  		input           *Buffer
    33  		testUI          *ui.UI
    34  		executeErr      error
    35  		extraArgs       []string
    36  	)
    37  
    38  	BeforeEach(func() {
    39  		input = NewBuffer()
    40  		testUI = ui.NewTestUI(input, NewBuffer(), NewBuffer())
    41  		fakeConfig = new(commandfakes.FakeConfig)
    42  		fakeActor = new(v6fakes.FakeUpdateUserProvidedServiceActor)
    43  		fakeSharedActor = new(commandfakes.FakeSharedActor)
    44  
    45  		cmd = &UpdateUserProvidedServiceCommand{
    46  			UI:           testUI,
    47  			Config:       fakeConfig,
    48  			SharedActor:  fakeSharedActor,
    49  			Actor:        fakeActor,
    50  			RequiredArgs: flag.ServiceInstance{ServiceInstance: fakeServiceInstanceName},
    51  		}
    52  	})
    53  
    54  	JustBeforeEach(func() {
    55  		executeErr = cmd.Execute(extraArgs)
    56  	})
    57  
    58  	It("checks the user is logged in, and targeting an org and space", func() {
    59  		Expect(fakeSharedActor.CheckTargetCallCount()).To(Equal(1))
    60  		orgChecked, spaceChecked := fakeSharedActor.CheckTargetArgsForCall(0)
    61  		Expect(orgChecked).To(BeTrue())
    62  		Expect(spaceChecked).To(BeTrue())
    63  	})
    64  
    65  	When("checking the target returns an error", func() {
    66  		BeforeEach(func() {
    67  			fakeSharedActor.CheckTargetReturns(errors.New("explode"))
    68  		})
    69  
    70  		It("returns the error", func() {
    71  			Expect(executeErr).To(MatchError("explode"))
    72  		})
    73  	})
    74  
    75  	When("the user is logged in, and is targeting an org and space", func() {
    76  		const (
    77  			fakeOrgName   = "fake-org-name"
    78  			fakeSpaceName = "fake-space-name"
    79  			fakeSpaceGUID = "fake-space-guid"
    80  			fakeUserName  = "fake-user-name"
    81  		)
    82  
    83  		BeforeEach(func() {
    84  			fakeConfig.TargetedSpaceReturns(configv3.Space{
    85  				Name: fakeSpaceName,
    86  				GUID: fakeSpaceGUID,
    87  			})
    88  
    89  			fakeConfig.TargetedOrganizationReturns(configv3.Organization{
    90  				Name: fakeOrgName,
    91  			})
    92  
    93  			fakeConfig.CurrentUserReturns(configv3.User{Name: fakeUserName}, nil) //TODO: test errors
    94  		})
    95  
    96  		It("looks up the service instance GUID", func() {
    97  			Expect(fakeActor.GetServiceInstanceByNameAndSpaceCallCount()).To(Equal(1))
    98  			name, spaceGUID := fakeActor.GetServiceInstanceByNameAndSpaceArgsForCall(0)
    99  			Expect(name).To(Equal(fakeServiceInstanceName))
   100  			Expect(spaceGUID).To(Equal(fakeSpaceGUID))
   101  		})
   102  
   103  		When("looking up the service instance GUID returns warnings", func() {
   104  			BeforeEach(func() {
   105  				fakeActor.GetServiceInstanceByNameAndSpaceReturns(
   106  					v2action.ServiceInstance{},
   107  					v2action.Warnings{"something obstreperous"},
   108  					nil,
   109  				)
   110  			})
   111  
   112  			It("reports the warning", func() {
   113  				Expect(testUI.Err).To(Say("something obstreperous"))
   114  			})
   115  		})
   116  
   117  		When("looking up the service instance GUID fails", func() {
   118  			BeforeEach(func() {
   119  				fakeActor.GetServiceInstanceByNameAndSpaceReturns(
   120  					v2action.ServiceInstance{},
   121  					v2action.Warnings{"something obstreperous"},
   122  					errors.New("something awful"),
   123  				)
   124  			})
   125  
   126  			It("returns the error and warnings", func() {
   127  				Expect(testUI.Err).To(Say("something obstreperous"))
   128  				Expect(executeErr).To(MatchError("something awful"))
   129  			})
   130  		})
   131  
   132  		When("the service instance is not user-provided", func() {
   133  			It("fails with an error", func() {
   134  				Expect(executeErr).To(MatchError(fmt.Sprintf("The service instance '%s' is not user-provided", fakeServiceInstanceName)))
   135  			})
   136  		})
   137  
   138  		When("looking up the service instance GUID succeeds, and it is user-provided", func() {
   139  			const (
   140  				fakeServiceInstanceGUID = "fake-service-instance-guid"
   141  			)
   142  
   143  			BeforeEach(func() {
   144  				fakeActor.GetServiceInstanceByNameAndSpaceReturns(
   145  					v2action.ServiceInstance{
   146  						GUID: fakeServiceInstanceGUID,
   147  						Type: constant.UserProvidedService,
   148  					},
   149  					nil,
   150  					nil,
   151  				)
   152  			})
   153  
   154  			When("no flags are provided", func() {
   155  				It("succeeds", func() {
   156  					Expect(executeErr).NotTo(HaveOccurred())
   157  				})
   158  
   159  				It("says that no flags were provided", func() {
   160  					Expect(testUI.Out).To(Say("No flags specified. No changes were made"))
   161  					Expect(testUI.Out).To(Say("OK"))
   162  				})
   163  			})
   164  
   165  			Context("updating log URL", func() {
   166  				BeforeEach(func() {
   167  					cmd.SyslogDrainURL.IsSet = true
   168  					cmd.SyslogDrainURL.Value = "fake-syslog-drain-url"
   169  				})
   170  
   171  				It("succeeds", func() {
   172  					Expect(executeErr).NotTo(HaveOccurred())
   173  				})
   174  
   175  				It("displays messages to the user", func() {
   176  					expectOKMessage(testUI, fakeServiceInstanceName, fakeOrgName, fakeSpaceName, fakeUserName)
   177  				})
   178  
   179  				It("updates the syslog URL", func() {
   180  					Expect(fakeActor.UpdateUserProvidedServiceInstanceCallCount()).To(Equal(1))
   181  					guid, instanceChanges := fakeActor.UpdateUserProvidedServiceInstanceArgsForCall(0)
   182  					Expect(guid).To(Equal(fakeServiceInstanceGUID))
   183  					Expect(instanceChanges).To(MatchAllFields(Fields{
   184  						"SyslogDrainURL":  PointTo(Equal("fake-syslog-drain-url")),
   185  						"RouteServiceURL": BeNil(),
   186  						"Tags":            BeNil(),
   187  						"Credentials":     BeNil(),
   188  					}))
   189  				})
   190  			})
   191  
   192  			Context("updating credentials", func() {
   193  				BeforeEach(func() {
   194  					cmd.Credentials.IsSet = true
   195  					cmd.Credentials.UserPromptCredentials = []string{"pass phrase", "cred"}
   196  
   197  					input.Write([]byte("very secret passphrase\nsecret cred\n"))
   198  				})
   199  
   200  				It("prompts the user for credentials", func() {
   201  					Expect(testUI.Out).To(Say("pass phrase: "))
   202  					Expect(testUI.Out).To(Say("cred: "))
   203  				})
   204  
   205  				It("does not echo the credentials", func() {
   206  					Expect(testUI.Out).NotTo(Say("secret"))
   207  					Expect(testUI.Err).NotTo(Say("secret"))
   208  				})
   209  
   210  				It("succeeds", func() {
   211  					Expect(executeErr).NotTo(HaveOccurred())
   212  				})
   213  
   214  				It("displays messages to the user", func() {
   215  					expectOKMessage(testUI, fakeServiceInstanceName, fakeOrgName, fakeSpaceName, fakeUserName)
   216  				})
   217  
   218  				It("updates the credentials", func() {
   219  					Expect(fakeActor.UpdateUserProvidedServiceInstanceCallCount()).To(Equal(1))
   220  					guid, instanceChanges := fakeActor.UpdateUserProvidedServiceInstanceArgsForCall(0)
   221  					Expect(guid).To(Equal(fakeServiceInstanceGUID))
   222  					Expect(instanceChanges).To(MatchAllFields(Fields{
   223  						"Credentials": Equal(map[string]interface{}{
   224  							"pass phrase": "very secret passphrase",
   225  							"cred":        "secret cred",
   226  						}),
   227  						"RouteServiceURL": BeNil(),
   228  						"Tags":            BeNil(),
   229  						"SyslogDrainURL":  BeNil(),
   230  					}))
   231  				})
   232  			})
   233  
   234  			Context("updating routes URL", func() {
   235  				BeforeEach(func() {
   236  					cmd.RouteServiceURL.IsSet = true
   237  					cmd.RouteServiceURL.Value = "fake-route-url"
   238  				})
   239  
   240  				It("succeeds", func() {
   241  					Expect(executeErr).NotTo(HaveOccurred())
   242  				})
   243  
   244  				It("displays messages to the user", func() {
   245  					expectOKMessage(testUI, fakeServiceInstanceName, fakeOrgName, fakeSpaceName, fakeUserName)
   246  				})
   247  
   248  				It("updates the routes URL", func() {
   249  					Expect(fakeActor.UpdateUserProvidedServiceInstanceCallCount()).To(Equal(1))
   250  					guid, instanceChanges := fakeActor.UpdateUserProvidedServiceInstanceArgsForCall(0)
   251  					Expect(guid).To(Equal(fakeServiceInstanceGUID))
   252  					Expect(instanceChanges).To(MatchAllFields(Fields{
   253  						"RouteServiceURL": PointTo(Equal("fake-route-url")),
   254  						"Tags":            BeNil(),
   255  						"SyslogDrainURL":  BeNil(),
   256  						"Credentials":     BeNil(),
   257  					}))
   258  				})
   259  			})
   260  
   261  			Context("updating tags", func() {
   262  				BeforeEach(func() {
   263  					cmd.Tags.IsSet = true
   264  					cmd.Tags.Value = []string{"foo", "bar"}
   265  				})
   266  
   267  				It("succeeds", func() {
   268  					Expect(executeErr).NotTo(HaveOccurred())
   269  				})
   270  
   271  				It("displays messages to the user", func() {
   272  					expectOKMessage(testUI, fakeServiceInstanceName, fakeOrgName, fakeSpaceName, fakeUserName)
   273  				})
   274  
   275  				It("updates the tags", func() {
   276  					Expect(fakeActor.UpdateUserProvidedServiceInstanceCallCount()).To(Equal(1))
   277  					guid, instanceChanges := fakeActor.UpdateUserProvidedServiceInstanceArgsForCall(0)
   278  					Expect(guid).To(Equal(fakeServiceInstanceGUID))
   279  					Expect(instanceChanges).To(MatchAllFields(Fields{
   280  						"Tags":            PointTo(ConsistOf("foo", "bar")),
   281  						"SyslogDrainURL":  BeNil(),
   282  						"RouteServiceURL": BeNil(),
   283  						"Credentials":     BeNil(),
   284  					}))
   285  				})
   286  			})
   287  
   288  			When("unsetting values", func() {
   289  				BeforeEach(func() {
   290  					cmd.RouteServiceURL.IsSet = true
   291  					cmd.Credentials.IsSet = true
   292  					cmd.SyslogDrainURL.IsSet = true
   293  					cmd.Tags.IsSet = true
   294  				})
   295  
   296  				It("sends empty values", func() {
   297  					Expect(fakeActor.UpdateUserProvidedServiceInstanceCallCount()).To(Equal(1))
   298  					guid, instanceChanges := fakeActor.UpdateUserProvidedServiceInstanceArgsForCall(0)
   299  					Expect(guid).To(Equal(fakeServiceInstanceGUID))
   300  					bytes, err := json.Marshal(instanceChanges)
   301  					Expect(err).NotTo(HaveOccurred())
   302  					Expect(bytes).To(MatchJSON(`
   303            {
   304  					  "tags": [],
   305  						"syslog_drain_url": "",
   306  						"route_service_url": "",
   307  						"credentials": {}
   308  					}`))
   309  				})
   310  			})
   311  
   312  			When("the action returns warnings", func() {
   313  				BeforeEach(func() {
   314  					cmd.Tags.IsSet = true
   315  					cmd.Tags.Value = []string{"foo", "bar"}
   316  
   317  					fakeActor.UpdateUserProvidedServiceInstanceReturns(v2action.Warnings{"some", "warnings"}, nil)
   318  				})
   319  
   320  				It("reports the warnings to the user", func() {
   321  					Expect(testUI.Err).To(Say("some"))
   322  					Expect(testUI.Err).To(Say("warnings"))
   323  				})
   324  			})
   325  
   326  			When("the action fails", func() {
   327  				BeforeEach(func() {
   328  					cmd.Tags.IsSet = true
   329  					cmd.Tags.Value = []string{"foo", "bar"}
   330  
   331  					fakeActor.UpdateUserProvidedServiceInstanceReturns(
   332  						v2action.Warnings{"some", "warnings"},
   333  						errors.New("utterly awful happenings"),
   334  					)
   335  				})
   336  
   337  				It("reports the failure and warnings", func() {
   338  					Expect(testUI.Err).To(Say("some"))
   339  					Expect(testUI.Err).To(Say("warnings"))
   340  					Expect(executeErr).To(MatchError("utterly awful happenings"))
   341  				})
   342  			})
   343  		})
   344  	})
   345  })
   346  
   347  func expectOKMessage(testUI *ui.UI, serviceName, orgName, spaceName, userName string) {
   348  	Expect(testUI.Out).To(Say("Updating user provided service %s in org %s / space %s as %s...", serviceName, orgName, spaceName, userName))
   349  	Expect(testUI.Out).To(Say("OK"))
   350  	Expect(testUI.Out).To(Say("TIP: Use 'cf restage' for any bound apps to ensure your env variable changes take effect"))
   351  }