github.com/DaAlbrecht/cf-cli@v0.0.0-20231128151943-1fe19bb400b9/actor/v7action/service_app_binding_test.go (about)

     1  package v7action_test
     2  
     3  import (
     4  	"errors"
     5  
     6  	"code.cloudfoundry.org/cli/actor/actionerror"
     7  	. "code.cloudfoundry.org/cli/actor/v7action"
     8  	"code.cloudfoundry.org/cli/actor/v7action/v7actionfakes"
     9  	"code.cloudfoundry.org/cli/api/cloudcontroller/ccerror"
    10  	"code.cloudfoundry.org/cli/api/cloudcontroller/ccv3"
    11  	"code.cloudfoundry.org/cli/api/cloudcontroller/ccv3/constant"
    12  	"code.cloudfoundry.org/cli/resources"
    13  	"code.cloudfoundry.org/cli/types"
    14  	. "github.com/onsi/ginkgo"
    15  	. "github.com/onsi/gomega"
    16  )
    17  
    18  var _ = Describe("Service App Binding Action", func() {
    19  	var (
    20  		actor                     *Actor
    21  		fakeCloudControllerClient *v7actionfakes.FakeCloudControllerClient
    22  	)
    23  
    24  	BeforeEach(func() {
    25  		fakeCloudControllerClient = new(v7actionfakes.FakeCloudControllerClient)
    26  		actor = NewActor(fakeCloudControllerClient, nil, nil, nil, nil, nil)
    27  	})
    28  
    29  	Describe("CreateServiceAppBinding", func() {
    30  		const (
    31  			serviceInstanceName = "fake-service-instance-name"
    32  			serviceInstanceGUID = "fake-service-instance-guid"
    33  			appName             = "fake-app-name"
    34  			appGUID             = "fake-app-guid"
    35  			bindingName         = "fake-binding-name"
    36  			spaceGUID           = "fake-space-guid"
    37  			fakeJobURL          = ccv3.JobURL("fake-job-url")
    38  		)
    39  
    40  		var (
    41  			params         CreateServiceAppBindingParams
    42  			warnings       Warnings
    43  			executionError error
    44  			stream         chan PollJobEvent
    45  		)
    46  
    47  		BeforeEach(func() {
    48  			fakeCloudControllerClient.GetServiceInstanceByNameAndSpaceReturns(
    49  				resources.ServiceInstance{
    50  					Name: serviceInstanceName,
    51  					GUID: serviceInstanceGUID,
    52  				},
    53  				ccv3.IncludedResources{},
    54  				ccv3.Warnings{"get instance warning"},
    55  				nil,
    56  			)
    57  
    58  			fakeCloudControllerClient.GetApplicationByNameAndSpaceReturns(
    59  				resources.Application{
    60  					GUID: appGUID,
    61  					Name: appName,
    62  				},
    63  				ccv3.Warnings{"get app warning"},
    64  				nil,
    65  			)
    66  
    67  			fakeCloudControllerClient.CreateServiceCredentialBindingReturns(
    68  				fakeJobURL,
    69  				ccv3.Warnings{"create binding warning"},
    70  				nil,
    71  			)
    72  
    73  			fakeStream := make(chan ccv3.PollJobEvent)
    74  			fakeCloudControllerClient.PollJobToEventStreamReturns(fakeStream)
    75  			go func() {
    76  				fakeStream <- ccv3.PollJobEvent{
    77  					State:    constant.JobPolling,
    78  					Warnings: ccv3.Warnings{"poll warning"},
    79  				}
    80  			}()
    81  
    82  			params = CreateServiceAppBindingParams{
    83  				SpaceGUID:           spaceGUID,
    84  				ServiceInstanceName: serviceInstanceName,
    85  				AppName:             appName,
    86  				BindingName:         bindingName,
    87  				Parameters: types.NewOptionalObject(map[string]interface{}{
    88  					"foo": "bar",
    89  				}),
    90  			}
    91  		})
    92  
    93  		JustBeforeEach(func() {
    94  			stream, warnings, executionError = actor.CreateServiceAppBinding(params)
    95  		})
    96  
    97  		It("returns an event stream, warnings, and no errors", func() {
    98  			Expect(executionError).NotTo(HaveOccurred())
    99  
   100  			Expect(warnings).To(ConsistOf(Warnings{
   101  				"get instance warning",
   102  				"get app warning",
   103  				"create binding warning",
   104  			}))
   105  
   106  			Eventually(stream).Should(Receive(Equal(PollJobEvent{
   107  				State:    JobPolling,
   108  				Warnings: Warnings{"poll warning"},
   109  				Err:      nil,
   110  			})))
   111  		})
   112  
   113  		Describe("service instance lookup", func() {
   114  			It("makes the correct call", func() {
   115  				Expect(fakeCloudControllerClient.GetServiceInstanceByNameAndSpaceCallCount()).To(Equal(1))
   116  				actualServiceInstanceName, actualSpaceGUID, actualQuery := fakeCloudControllerClient.GetServiceInstanceByNameAndSpaceArgsForCall(0)
   117  				Expect(actualServiceInstanceName).To(Equal(serviceInstanceName))
   118  				Expect(actualSpaceGUID).To(Equal(spaceGUID))
   119  				Expect(actualQuery).To(BeEmpty())
   120  			})
   121  
   122  			When("not found", func() {
   123  				BeforeEach(func() {
   124  					fakeCloudControllerClient.GetServiceInstanceByNameAndSpaceReturns(
   125  						resources.ServiceInstance{},
   126  						ccv3.IncludedResources{},
   127  						ccv3.Warnings{"get instance warning"},
   128  						ccerror.ServiceInstanceNotFoundError{Name: serviceInstanceName},
   129  					)
   130  				})
   131  
   132  				It("returns the error and warning", func() {
   133  					Expect(warnings).To(ContainElement("get instance warning"))
   134  					Expect(executionError).To(MatchError(actionerror.ServiceInstanceNotFoundError{Name: serviceInstanceName}))
   135  				})
   136  			})
   137  
   138  			When("fails", func() {
   139  				BeforeEach(func() {
   140  					fakeCloudControllerClient.GetServiceInstanceByNameAndSpaceReturns(
   141  						resources.ServiceInstance{},
   142  						ccv3.IncludedResources{},
   143  						ccv3.Warnings{"get instance warning"},
   144  						errors.New("boof"),
   145  					)
   146  				})
   147  
   148  				It("returns the error and warning", func() {
   149  					Expect(warnings).To(ContainElement("get instance warning"))
   150  					Expect(executionError).To(MatchError("boof"))
   151  				})
   152  			})
   153  		})
   154  
   155  		Describe("app lookup", func() {
   156  			It("makes the correct call", func() {
   157  				Expect(fakeCloudControllerClient.GetApplicationByNameAndSpaceCallCount()).To(Equal(1))
   158  				actualAppName, actualSpaceGUID := fakeCloudControllerClient.GetApplicationByNameAndSpaceArgsForCall(0)
   159  				Expect(actualAppName).To(Equal(appName))
   160  				Expect(actualSpaceGUID).To(Equal(spaceGUID))
   161  			})
   162  
   163  			When("not found", func() {
   164  				BeforeEach(func() {
   165  					fakeCloudControllerClient.GetApplicationByNameAndSpaceReturns(
   166  						resources.Application{},
   167  						ccv3.Warnings{"get app warning"},
   168  						ccerror.ApplicationNotFoundError{Name: appName},
   169  					)
   170  				})
   171  
   172  				It("returns the error and warning", func() {
   173  					Expect(warnings).To(ContainElement("get app warning"))
   174  					Expect(executionError).To(MatchError(actionerror.ApplicationNotFoundError{Name: appName}))
   175  				})
   176  			})
   177  
   178  			When("fails", func() {
   179  				BeforeEach(func() {
   180  					fakeCloudControllerClient.GetApplicationByNameAndSpaceReturns(
   181  						resources.Application{},
   182  						ccv3.Warnings{"get app warning"},
   183  						errors.New("boom"),
   184  					)
   185  				})
   186  
   187  				It("returns the error and warning", func() {
   188  					Expect(warnings).To(ContainElement("get app warning"))
   189  					Expect(executionError).To(MatchError("boom"))
   190  				})
   191  			})
   192  		})
   193  
   194  		Describe("initiating the create", func() {
   195  			It("makes the correct call", func() {
   196  				Expect(fakeCloudControllerClient.CreateServiceCredentialBindingCallCount()).To(Equal(1))
   197  				Expect(fakeCloudControllerClient.CreateServiceCredentialBindingArgsForCall(0)).To(Equal(resources.ServiceCredentialBinding{
   198  					Type:                resources.AppBinding,
   199  					Name:                bindingName,
   200  					ServiceInstanceGUID: serviceInstanceGUID,
   201  					AppGUID:             appGUID,
   202  					Parameters: types.NewOptionalObject(map[string]interface{}{
   203  						"foo": "bar",
   204  					}),
   205  				}))
   206  			})
   207  
   208  			When("binding already exists", func() {
   209  				BeforeEach(func() {
   210  					fakeCloudControllerClient.CreateServiceCredentialBindingReturns(
   211  						"",
   212  						ccv3.Warnings{"create binding warning"},
   213  						ccerror.ResourceAlreadyExistsError{
   214  							Message: "The app is already bound to the service instance",
   215  						},
   216  					)
   217  				})
   218  
   219  				It("returns an actionerror and warnings", func() {
   220  					Expect(warnings).To(ContainElement("create binding warning"))
   221  					Expect(executionError).To(MatchError(actionerror.ResourceAlreadyExistsError{
   222  						Message: "The app is already bound to the service instance",
   223  					}))
   224  				})
   225  			})
   226  
   227  			When("fails", func() {
   228  				BeforeEach(func() {
   229  					fakeCloudControllerClient.CreateServiceCredentialBindingReturns(
   230  						"",
   231  						ccv3.Warnings{"create binding warning"},
   232  						errors.New("boop"),
   233  					)
   234  				})
   235  
   236  				It("returns the error and warnings", func() {
   237  					Expect(warnings).To(ContainElement("create binding warning"))
   238  					Expect(executionError).To(MatchError("boop"))
   239  				})
   240  			})
   241  		})
   242  
   243  		Describe("polling the job", func() {
   244  			It("polls the job", func() {
   245  				Expect(fakeCloudControllerClient.PollJobToEventStreamCallCount()).To(Equal(1))
   246  				Expect(fakeCloudControllerClient.PollJobToEventStreamArgsForCall(0)).To(Equal(fakeJobURL))
   247  			})
   248  		})
   249  	})
   250  
   251  	Describe("DeleteServiceAppBinding", func() {
   252  		const (
   253  			serviceInstanceName = "fake-service-instance-name"
   254  			serviceInstanceGUID = "fake-service-instance-guid"
   255  			appName             = "fake-app-name"
   256  			appGUID             = "fake-app-guid"
   257  			spaceGUID           = "fake-space-guid"
   258  			bindingGUID         = "fake-binding-guid"
   259  			fakeJobURL          = ccv3.JobURL("fake-job-url")
   260  		)
   261  
   262  		var (
   263  			params         DeleteServiceAppBindingParams
   264  			warnings       Warnings
   265  			executionError error
   266  			stream         chan PollJobEvent
   267  		)
   268  
   269  		BeforeEach(func() {
   270  			fakeCloudControllerClient.GetServiceInstanceByNameAndSpaceReturns(
   271  				resources.ServiceInstance{
   272  					Name: serviceInstanceName,
   273  					GUID: serviceInstanceGUID,
   274  				},
   275  				ccv3.IncludedResources{},
   276  				ccv3.Warnings{"get instance warning"},
   277  				nil,
   278  			)
   279  
   280  			fakeCloudControllerClient.GetApplicationByNameAndSpaceReturns(
   281  				resources.Application{
   282  					GUID: appGUID,
   283  					Name: appName,
   284  				},
   285  				ccv3.Warnings{"get app warning"},
   286  				nil,
   287  			)
   288  
   289  			fakeCloudControllerClient.GetServiceCredentialBindingsReturns(
   290  				[]resources.ServiceCredentialBinding{
   291  					{GUID: bindingGUID},
   292  				},
   293  				ccv3.Warnings{"get bindings warning"},
   294  				nil,
   295  			)
   296  
   297  			fakeCloudControllerClient.DeleteServiceCredentialBindingReturns(
   298  				fakeJobURL,
   299  				ccv3.Warnings{"delete binding warning"},
   300  				nil,
   301  			)
   302  
   303  			fakeStream := make(chan ccv3.PollJobEvent)
   304  			fakeCloudControllerClient.PollJobToEventStreamReturns(fakeStream)
   305  			go func() {
   306  				fakeStream <- ccv3.PollJobEvent{
   307  					State:    constant.JobPolling,
   308  					Warnings: ccv3.Warnings{"poll warning"},
   309  				}
   310  			}()
   311  
   312  			params = DeleteServiceAppBindingParams{
   313  				SpaceGUID:           spaceGUID,
   314  				ServiceInstanceName: serviceInstanceName,
   315  				AppName:             appName,
   316  			}
   317  		})
   318  
   319  		JustBeforeEach(func() {
   320  			stream, warnings, executionError = actor.DeleteServiceAppBinding(params)
   321  		})
   322  
   323  		It("returns an event stream, warnings, and no errors", func() {
   324  			Expect(executionError).NotTo(HaveOccurred())
   325  
   326  			Expect(warnings).To(ConsistOf(Warnings{
   327  				"get instance warning",
   328  				"get app warning",
   329  				"get bindings warning",
   330  				"delete binding warning",
   331  			}))
   332  
   333  			Eventually(stream).Should(Receive(Equal(PollJobEvent{
   334  				State:    JobPolling,
   335  				Warnings: Warnings{"poll warning"},
   336  				Err:      nil,
   337  			})))
   338  		})
   339  
   340  		Describe("service instance lookup", func() {
   341  			It("makes the correct call", func() {
   342  				Expect(fakeCloudControllerClient.GetServiceInstanceByNameAndSpaceCallCount()).To(Equal(1))
   343  				actualServiceInstanceName, actualSpaceGUID, actualQuery := fakeCloudControllerClient.GetServiceInstanceByNameAndSpaceArgsForCall(0)
   344  				Expect(actualServiceInstanceName).To(Equal(serviceInstanceName))
   345  				Expect(actualSpaceGUID).To(Equal(spaceGUID))
   346  				Expect(actualQuery).To(BeEmpty())
   347  			})
   348  
   349  			When("not found", func() {
   350  				BeforeEach(func() {
   351  					fakeCloudControllerClient.GetServiceInstanceByNameAndSpaceReturns(
   352  						resources.ServiceInstance{},
   353  						ccv3.IncludedResources{},
   354  						ccv3.Warnings{"get instance warning"},
   355  						ccerror.ServiceInstanceNotFoundError{Name: serviceInstanceName},
   356  					)
   357  				})
   358  
   359  				It("returns the error and warning", func() {
   360  					Expect(warnings).To(ContainElement("get instance warning"))
   361  					Expect(executionError).To(MatchError(actionerror.ServiceInstanceNotFoundError{Name: serviceInstanceName}))
   362  				})
   363  			})
   364  
   365  			When("fails", func() {
   366  				BeforeEach(func() {
   367  					fakeCloudControllerClient.GetServiceInstanceByNameAndSpaceReturns(
   368  						resources.ServiceInstance{},
   369  						ccv3.IncludedResources{},
   370  						ccv3.Warnings{"get instance warning"},
   371  						errors.New("boof"),
   372  					)
   373  				})
   374  
   375  				It("returns the error and warning", func() {
   376  					Expect(warnings).To(ContainElement("get instance warning"))
   377  					Expect(executionError).To(MatchError("boof"))
   378  				})
   379  			})
   380  		})
   381  
   382  		Describe("app lookup", func() {
   383  			It("makes the correct call", func() {
   384  				Expect(fakeCloudControllerClient.GetApplicationByNameAndSpaceCallCount()).To(Equal(1))
   385  				actualAppName, actualSpaceGUID := fakeCloudControllerClient.GetApplicationByNameAndSpaceArgsForCall(0)
   386  				Expect(actualAppName).To(Equal(appName))
   387  				Expect(actualSpaceGUID).To(Equal(spaceGUID))
   388  			})
   389  
   390  			When("not found", func() {
   391  				BeforeEach(func() {
   392  					fakeCloudControllerClient.GetApplicationByNameAndSpaceReturns(
   393  						resources.Application{},
   394  						ccv3.Warnings{"get app warning"},
   395  						ccerror.ApplicationNotFoundError{Name: appName},
   396  					)
   397  				})
   398  
   399  				It("returns the error and warning", func() {
   400  					Expect(warnings).To(ContainElement("get app warning"))
   401  					Expect(executionError).To(MatchError(actionerror.ApplicationNotFoundError{Name: appName}))
   402  				})
   403  			})
   404  
   405  			When("fails", func() {
   406  				BeforeEach(func() {
   407  					fakeCloudControllerClient.GetApplicationByNameAndSpaceReturns(
   408  						resources.Application{},
   409  						ccv3.Warnings{"get app warning"},
   410  						errors.New("boom"),
   411  					)
   412  				})
   413  
   414  				It("returns the error and warning", func() {
   415  					Expect(warnings).To(ContainElement("get app warning"))
   416  					Expect(executionError).To(MatchError("boom"))
   417  				})
   418  			})
   419  		})
   420  
   421  		Describe("binding lookup", func() {
   422  			It("makes the correct call", func() {
   423  				Expect(fakeCloudControllerClient.GetServiceCredentialBindingsCallCount()).To(Equal(1))
   424  				Expect(fakeCloudControllerClient.GetServiceCredentialBindingsArgsForCall(0)).To(ConsistOf(
   425  					ccv3.Query{Key: ccv3.TypeFilter, Values: []string{"app"}},
   426  					ccv3.Query{Key: ccv3.AppGUIDFilter, Values: []string{appGUID}},
   427  					ccv3.Query{Key: ccv3.ServiceInstanceGUIDFilter, Values: []string{serviceInstanceGUID}},
   428  				))
   429  			})
   430  
   431  			When("not found", func() {
   432  				BeforeEach(func() {
   433  					fakeCloudControllerClient.GetServiceCredentialBindingsReturns(
   434  						[]resources.ServiceCredentialBinding{},
   435  						ccv3.Warnings{"get bindings warning"},
   436  						nil,
   437  					)
   438  				})
   439  
   440  				It("returns the error and warning", func() {
   441  					Expect(warnings).To(ContainElement("get bindings warning"))
   442  					Expect(executionError).To(MatchError(actionerror.ServiceBindingNotFoundError{
   443  						AppGUID:             appGUID,
   444  						ServiceInstanceGUID: serviceInstanceGUID,
   445  					}))
   446  				})
   447  			})
   448  
   449  			When("fails", func() {
   450  				BeforeEach(func() {
   451  					fakeCloudControllerClient.GetServiceCredentialBindingsReturns(
   452  						[]resources.ServiceCredentialBinding{},
   453  						ccv3.Warnings{"get binding warning"},
   454  						errors.New("boom"),
   455  					)
   456  				})
   457  
   458  				It("returns the error and warning", func() {
   459  					Expect(warnings).To(ContainElement("get binding warning"))
   460  					Expect(executionError).To(MatchError("boom"))
   461  				})
   462  			})
   463  		})
   464  
   465  		Describe("initiating the delete", func() {
   466  			It("makes the correct call", func() {
   467  				Expect(fakeCloudControllerClient.DeleteServiceCredentialBindingCallCount()).To(Equal(1))
   468  				Expect(fakeCloudControllerClient.DeleteServiceCredentialBindingArgsForCall(0)).To(Equal(bindingGUID))
   469  			})
   470  
   471  			When("fails", func() {
   472  				BeforeEach(func() {
   473  					fakeCloudControllerClient.DeleteServiceCredentialBindingReturns(
   474  						"",
   475  						ccv3.Warnings{"delete binding warning"},
   476  						errors.New("boop"),
   477  					)
   478  				})
   479  
   480  				It("returns the error and warnings", func() {
   481  					Expect(warnings).To(ContainElement("delete binding warning"))
   482  					Expect(executionError).To(MatchError("boop"))
   483  				})
   484  			})
   485  		})
   486  
   487  		Describe("polling the job", func() {
   488  			It("polls the job", func() {
   489  				Expect(fakeCloudControllerClient.PollJobToEventStreamCallCount()).To(Equal(1))
   490  				Expect(fakeCloudControllerClient.PollJobToEventStreamArgsForCall(0)).To(Equal(fakeJobURL))
   491  			})
   492  		})
   493  	})
   494  })