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

     1  package service_test
     2  
     3  import (
     4  	"io/ioutil"
     5  	"net/http"
     6  	"os"
     7  
     8  	"code.cloudfoundry.org/cli/cf/api/apifakes"
     9  	"code.cloudfoundry.org/cli/cf/commandregistry"
    10  	"code.cloudfoundry.org/cli/cf/configuration/coreconfig"
    11  	"code.cloudfoundry.org/cli/cf/models"
    12  	"code.cloudfoundry.org/cli/cf/requirements"
    13  	"code.cloudfoundry.org/cli/cf/requirements/requirementsfakes"
    14  	testcmd "code.cloudfoundry.org/cli/cf/util/testhelpers/commands"
    15  	testconfig "code.cloudfoundry.org/cli/cf/util/testhelpers/configuration"
    16  	testterm "code.cloudfoundry.org/cli/cf/util/testhelpers/terminal"
    17  	. "github.com/onsi/ginkgo"
    18  	. "github.com/onsi/gomega"
    19  
    20  	"code.cloudfoundry.org/cli/cf/errors"
    21  	. "code.cloudfoundry.org/cli/cf/util/testhelpers/matchers"
    22  )
    23  
    24  var _ = Describe("bind-service command", func() {
    25  	var (
    26  		ui                  *testterm.FakeUI
    27  		requirementsFactory *requirementsfakes.FakeFactory
    28  		config              coreconfig.Repository
    29  		serviceBindingRepo  *apifakes.FakeServiceBindingRepository
    30  		deps                commandregistry.Dependency
    31  	)
    32  
    33  	updateCommandDependency := func(pluginCall bool) {
    34  		deps.UI = ui
    35  		deps.Config = config
    36  		deps.RepoLocator = deps.RepoLocator.SetServiceBindingRepository(serviceBindingRepo)
    37  		commandregistry.Commands.SetCommand(commandregistry.Commands.FindCommand("bind-service").SetDependency(deps, pluginCall))
    38  	}
    39  
    40  	BeforeEach(func() {
    41  		ui = &testterm.FakeUI{}
    42  		config = testconfig.NewRepositoryWithDefaults()
    43  		requirementsFactory = new(requirementsfakes.FakeFactory)
    44  		serviceBindingRepo = new(apifakes.FakeServiceBindingRepository)
    45  	})
    46  
    47  	var callBindService = func(args []string) bool {
    48  		return testcmd.RunCLICommand("bind-service", args, requirementsFactory, updateCommandDependency, false, ui)
    49  	}
    50  
    51  	It("fails requirements when not logged in", func() {
    52  		requirementsFactory.NewLoginRequirementReturns(requirements.Failing{Message: "not logged in"})
    53  		Expect(callBindService([]string{"service", "app"})).To(BeFalse())
    54  	})
    55  
    56  	Context("when logged in", func() {
    57  		var (
    58  			app             models.Application
    59  			serviceInstance models.ServiceInstance
    60  		)
    61  
    62  		BeforeEach(func() {
    63  			requirementsFactory.NewLoginRequirementReturns(requirements.Passing{})
    64  
    65  			app = models.Application{
    66  				ApplicationFields: models.ApplicationFields{
    67  					Name: "my-app",
    68  					GUID: "my-app-guid",
    69  				},
    70  			}
    71  			serviceInstance = models.ServiceInstance{
    72  				ServiceInstanceFields: models.ServiceInstanceFields{
    73  					Name: "my-service",
    74  					GUID: "my-service-guid",
    75  				},
    76  			}
    77  			applicationReq := new(requirementsfakes.FakeApplicationRequirement)
    78  			applicationReq.GetApplicationReturns(app)
    79  			requirementsFactory.NewApplicationRequirementReturns(applicationReq)
    80  
    81  			serviceInstanceReq := new(requirementsfakes.FakeServiceInstanceRequirement)
    82  			serviceInstanceReq.GetServiceInstanceReturns(serviceInstance)
    83  			requirementsFactory.NewServiceInstanceRequirementReturns(serviceInstanceReq)
    84  		})
    85  
    86  		It("binds a service instance to an app", func() {
    87  			callBindService([]string{"my-app", "my-service"})
    88  
    89  			Expect(ui.Outputs()).To(ContainSubstrings(
    90  				[]string{"Binding service", "my-service", "my-app", "my-org", "my-space", "my-user"},
    91  				[]string{"OK"},
    92  				[]string{"TIP", "my-app"},
    93  			))
    94  
    95  			Expect(serviceBindingRepo.CreateCallCount()).To(Equal(1))
    96  			serviceInstanceGUID, applicationGUID, _ := serviceBindingRepo.CreateArgsForCall(0)
    97  			Expect(serviceInstanceGUID).To(Equal("my-service-guid"))
    98  			Expect(applicationGUID).To(Equal("my-app-guid"))
    99  		})
   100  
   101  		It("warns the user when the service instance is already bound to the given app", func() {
   102  			serviceBindingRepo.CreateReturns(errors.NewHTTPError(http.StatusBadRequest, errors.ServiceBindingAppServiceTaken, ""))
   103  			callBindService([]string{"my-app", "my-service"})
   104  
   105  			Expect(ui.Outputs()).To(ContainSubstrings(
   106  				[]string{"Binding service"},
   107  				[]string{"OK"},
   108  				[]string{"my-app", "is already bound", "my-service"},
   109  			))
   110  		})
   111  
   112  		It("warns the user when the error is non HTTPError ", func() {
   113  			serviceBindingRepo.CreateReturns(errors.New("1001"))
   114  			callBindService([]string{"my-app1", "my-service1"})
   115  			Expect(ui.Outputs()).To(ContainSubstrings(
   116  				[]string{"Binding service", "my-service", "my-app", "my-org", "my-space", "my-user"},
   117  				[]string{"FAILED"},
   118  				[]string{"1001"},
   119  			))
   120  		})
   121  
   122  		It("fails with usage when called without a service instance and app", func() {
   123  			callBindService([]string{"my-service"})
   124  			Expect(ui.Outputs()).To(ContainSubstrings(
   125  				[]string{"Incorrect Usage", "Requires", "arguments"},
   126  			))
   127  
   128  			ui = &testterm.FakeUI{}
   129  			callBindService([]string{"my-app"})
   130  			Expect(ui.Outputs()).To(ContainSubstrings(
   131  				[]string{"Incorrect Usage", "Requires", "arguments"},
   132  			))
   133  
   134  			ui = &testterm.FakeUI{}
   135  			callBindService([]string{"my-app", "my-service"})
   136  			Expect(ui.Outputs()).ToNot(ContainSubstrings(
   137  				[]string{"Incorrect Usage", "Requires", "arguments"},
   138  			))
   139  		})
   140  
   141  		Context("when passing arbitrary params", func() {
   142  			Context("as a json string", func() {
   143  				It("successfully creates a service and passes the params as a json string", func() {
   144  					callBindService([]string{"my-app", "my-service", "-c", `{"foo": "bar"}`})
   145  
   146  					Expect(ui.Outputs()).To(ContainSubstrings(
   147  						[]string{"Binding service", "my-service", "my-app", "my-org", "my-space", "my-user"},
   148  						[]string{"OK"},
   149  						[]string{"TIP"},
   150  					))
   151  
   152  					Expect(serviceBindingRepo.CreateCallCount()).To(Equal(1))
   153  					serviceInstanceGUID, applicationGUID, createParams := serviceBindingRepo.CreateArgsForCall(0)
   154  					Expect(serviceInstanceGUID).To(Equal("my-service-guid"))
   155  					Expect(applicationGUID).To(Equal("my-app-guid"))
   156  					Expect(createParams).To(Equal(map[string]interface{}{"foo": "bar"}))
   157  				})
   158  
   159  				Context("that are not valid json", func() {
   160  					It("returns an error to the UI", func() {
   161  						callBindService([]string{"my-app", "my-service", "-c", `bad-json`})
   162  
   163  						Expect(ui.Outputs()).To(ContainSubstrings(
   164  							[]string{"FAILED"},
   165  							[]string{"Invalid configuration provided for -c flag. Please provide a valid JSON object or path to a file containing a valid JSON object."},
   166  						))
   167  					})
   168  				})
   169  			})
   170  
   171  			Context("as a file that contains json", func() {
   172  				var jsonFile *os.File
   173  				var params string
   174  
   175  				BeforeEach(func() {
   176  					params = "{\"foo\": \"bar\"}"
   177  				})
   178  
   179  				AfterEach(func() {
   180  					if jsonFile != nil {
   181  						jsonFile.Close()
   182  						os.Remove(jsonFile.Name())
   183  					}
   184  				})
   185  
   186  				JustBeforeEach(func() {
   187  					var err error
   188  					jsonFile, err = ioutil.TempFile("", "")
   189  					Expect(err).ToNot(HaveOccurred())
   190  
   191  					err = ioutil.WriteFile(jsonFile.Name(), []byte(params), os.ModePerm)
   192  					Expect(err).NotTo(HaveOccurred())
   193  				})
   194  
   195  				It("successfully creates a service and passes the params as a json", func() {
   196  					callBindService([]string{"my-app", "my-service", "-c", jsonFile.Name()})
   197  
   198  					Expect(ui.Outputs()).To(ContainSubstrings(
   199  						[]string{"Binding service", "my-service", "my-app", "my-org", "my-space", "my-user"},
   200  						[]string{"OK"},
   201  						[]string{"TIP"},
   202  					))
   203  
   204  					Expect(serviceBindingRepo.CreateCallCount()).To(Equal(1))
   205  					serviceInstanceGUID, applicationGUID, createParams := serviceBindingRepo.CreateArgsForCall(0)
   206  					Expect(serviceInstanceGUID).To(Equal("my-service-guid"))
   207  					Expect(applicationGUID).To(Equal("my-app-guid"))
   208  					Expect(createParams).To(Equal(map[string]interface{}{"foo": "bar"}))
   209  				})
   210  
   211  				Context("that are not valid json", func() {
   212  					BeforeEach(func() {
   213  						params = "bad-json"
   214  					})
   215  
   216  					It("returns an error to the UI", func() {
   217  						callBindService([]string{"my-app", "my-service", "-c", jsonFile.Name()})
   218  
   219  						Expect(ui.Outputs()).To(ContainSubstrings(
   220  							[]string{"FAILED"},
   221  							[]string{"Invalid configuration provided for -c flag. Please provide a valid JSON object or path to a file containing a valid JSON object."},
   222  						))
   223  					})
   224  				})
   225  			})
   226  		})
   227  	})
   228  })