github.com/LukasHeimann/cloudfoundrycli/v8@v8.4.4/command/v7/bind_service_command_test.go (about)

     1  package v7_test
     2  
     3  import (
     4  	"errors"
     5  
     6  	"github.com/LukasHeimann/cloudfoundrycli/v8/actor/actionerror"
     7  	"github.com/LukasHeimann/cloudfoundrycli/v8/actor/v7action"
     8  	"github.com/LukasHeimann/cloudfoundrycli/v8/command/commandfakes"
     9  	v7 "github.com/LukasHeimann/cloudfoundrycli/v8/command/v7"
    10  	"github.com/LukasHeimann/cloudfoundrycli/v8/command/v7/v7fakes"
    11  	"github.com/LukasHeimann/cloudfoundrycli/v8/types"
    12  	"github.com/LukasHeimann/cloudfoundrycli/v8/util/configv3"
    13  	"github.com/LukasHeimann/cloudfoundrycli/v8/util/ui"
    14  	. "github.com/onsi/ginkgo"
    15  	. "github.com/onsi/gomega"
    16  	. "github.com/onsi/gomega/gbytes"
    17  )
    18  
    19  var _ = Describe("bind-service Command", func() {
    20  	var (
    21  		cmd             v7.BindServiceCommand
    22  		testUI          *ui.UI
    23  		fakeConfig      *commandfakes.FakeConfig
    24  		fakeSharedActor *commandfakes.FakeSharedActor
    25  		executeErr      error
    26  		fakeActor       *v7fakes.FakeActor
    27  	)
    28  
    29  	const (
    30  		fakeUserName            = "fake-user-name"
    31  		fakeServiceInstanceName = "fake-service-instance-name"
    32  		fakeBindingName         = "fake-binding-name"
    33  		fakeAppName             = "fake-app-name"
    34  		fakeOrgName             = "fake-org-name"
    35  		fakeSpaceName           = "fake-space-name"
    36  		fakeSpaceGUID           = "fake-space-guid"
    37  	)
    38  
    39  	BeforeEach(func() {
    40  		testUI = ui.NewTestUI(NewBuffer(), NewBuffer(), NewBuffer())
    41  		fakeConfig = new(commandfakes.FakeConfig)
    42  		fakeSharedActor = new(commandfakes.FakeSharedActor)
    43  		fakeActor = new(v7fakes.FakeActor)
    44  
    45  		cmd = v7.BindServiceCommand{
    46  			BaseCommand: v7.BaseCommand{
    47  				UI:          testUI,
    48  				Config:      fakeConfig,
    49  				SharedActor: fakeSharedActor,
    50  				Actor:       fakeActor,
    51  			},
    52  		}
    53  
    54  		fakeConfig.TargetedSpaceReturns(configv3.Space{
    55  			Name: fakeSpaceName,
    56  			GUID: fakeSpaceGUID,
    57  		})
    58  
    59  		fakeConfig.TargetedOrganizationReturns(configv3.Organization{Name: fakeOrgName})
    60  
    61  		fakeActor.GetCurrentUserReturns(configv3.User{Name: fakeUserName}, nil)
    62  
    63  		fakeActor.CreateServiceAppBindingReturns(
    64  			nil,
    65  			v7action.Warnings{"fake warning"},
    66  			nil,
    67  		)
    68  
    69  		setPositionalFlags(&cmd, fakeAppName, fakeServiceInstanceName)
    70  		setFlag(&cmd, "--binding-name", fakeBindingName)
    71  		setFlag(&cmd, "-c", `{"foo": "bar"}`)
    72  	})
    73  
    74  	JustBeforeEach(func() {
    75  		executeErr = cmd.Execute(nil)
    76  	})
    77  
    78  	It("checks the user is logged in, and targeting an org and space", func() {
    79  		Expect(executeErr).NotTo(HaveOccurred())
    80  
    81  		Expect(fakeSharedActor.CheckTargetCallCount()).To(Equal(1))
    82  		actualOrg, actualSpace := fakeSharedActor.CheckTargetArgsForCall(0)
    83  		Expect(actualOrg).To(BeTrue())
    84  		Expect(actualSpace).To(BeTrue())
    85  	})
    86  
    87  	It("delegates to the actor", func() {
    88  		Expect(fakeActor.CreateServiceAppBindingCallCount()).To(Equal(1))
    89  		Expect(fakeActor.CreateServiceAppBindingArgsForCall(0)).To(Equal(v7action.CreateServiceAppBindingParams{
    90  			SpaceGUID:           fakeSpaceGUID,
    91  			ServiceInstanceName: fakeServiceInstanceName,
    92  			AppName:             fakeAppName,
    93  			BindingName:         fakeBindingName,
    94  			Parameters:          types.NewOptionalObject(map[string]interface{}{"foo": "bar"}),
    95  		}))
    96  	})
    97  
    98  	Describe("intro message", func() {
    99  		It("prints an intro and warnings", func() {
   100  			Expect(executeErr).NotTo(HaveOccurred())
   101  			Expect(testUI.Err).To(Say("fake warning"))
   102  			Expect(testUI.Out).To(Say(
   103  				`Binding service instance %s to app %s in org %s / space %s as %s\.\.\.\n`,
   104  				fakeServiceInstanceName,
   105  				fakeAppName,
   106  				fakeOrgName,
   107  				fakeSpaceName,
   108  				fakeUserName,
   109  			))
   110  		})
   111  	})
   112  
   113  	When("binding already exists", func() {
   114  		BeforeEach(func() {
   115  			fakeActor.CreateServiceAppBindingReturns(
   116  				nil,
   117  				v7action.Warnings{"fake warning"},
   118  				actionerror.ResourceAlreadyExistsError{},
   119  			)
   120  		})
   121  
   122  		It("prints a message and warnings", func() {
   123  			Expect(testUI.Out).To(SatisfyAll(
   124  				Say(
   125  					`App %s is already bound to service instance %s\.\n`,
   126  					fakeAppName,
   127  					fakeServiceInstanceName,
   128  				),
   129  				Say(`OK\n`),
   130  			))
   131  
   132  			Expect(testUI.Err).To(Say("fake warning"))
   133  		})
   134  	})
   135  
   136  	Describe("processing the response stream", func() {
   137  		Context("nil stream", func() {
   138  			It("prints a message and warnings", func() {
   139  				Expect(testUI.Out).To(SatisfyAll(
   140  					Say(`OK\n`),
   141  					Say(`\n`),
   142  					Say(`TIP: Use 'cf restage %s' to ensure your env variable changes take effect\n`, fakeAppName),
   143  				))
   144  
   145  				Expect(testUI.Err).To(Say("fake warning"))
   146  			})
   147  		})
   148  
   149  		Context("stream goes to complete", func() {
   150  			BeforeEach(func() {
   151  				eventStream := make(chan v7action.PollJobEvent)
   152  				go func() {
   153  					eventStream <- v7action.PollJobEvent{
   154  						State:    v7action.JobProcessing,
   155  						Warnings: v7action.Warnings{"job processing warning"},
   156  					}
   157  					eventStream <- v7action.PollJobEvent{
   158  						State:    v7action.JobComplete,
   159  						Warnings: v7action.Warnings{"job complete warning"},
   160  					}
   161  					close(eventStream)
   162  				}()
   163  
   164  				fakeActor.CreateServiceAppBindingReturns(
   165  					eventStream,
   166  					v7action.Warnings{"fake warning"},
   167  					nil,
   168  				)
   169  			})
   170  
   171  			It("prints a message and warnings", func() {
   172  				Expect(testUI.Out).To(SatisfyAll(
   173  					Say(`OK\n`),
   174  					Say(`\n`),
   175  					Say(`TIP: Use 'cf restage %s' to ensure your env variable changes take effect\n`, fakeAppName),
   176  				))
   177  
   178  				Expect(testUI.Err).To(SatisfyAll(
   179  					Say("fake warning"),
   180  					Say("job processing warning"),
   181  					Say("job complete warning"),
   182  				))
   183  			})
   184  		})
   185  
   186  		Context("stream goes to polling", func() {
   187  			BeforeEach(func() {
   188  				eventStream := make(chan v7action.PollJobEvent)
   189  				go func() {
   190  					eventStream <- v7action.PollJobEvent{
   191  						State:    v7action.JobProcessing,
   192  						Warnings: v7action.Warnings{"job processing warning"},
   193  					}
   194  					eventStream <- v7action.PollJobEvent{
   195  						State:    v7action.JobPolling,
   196  						Warnings: v7action.Warnings{"job polling warning"},
   197  					}
   198  				}()
   199  
   200  				fakeActor.CreateServiceAppBindingReturns(
   201  					eventStream,
   202  					v7action.Warnings{"fake warning"},
   203  					nil,
   204  				)
   205  			})
   206  
   207  			It("prints a message and warnings", func() {
   208  				Expect(testUI.Out).To(SatisfyAll(
   209  					Say(`OK\n`),
   210  					Say(`\n`),
   211  					Say(`Binding in progress. Use 'cf service %s' to check operation status.\n`, fakeServiceInstanceName),
   212  					Say(`\n`),
   213  					Say(`TIP: Once this operation succeeds, use 'cf restage %s' to ensure your env variable changes take effect\n`, fakeAppName),
   214  				))
   215  
   216  				Expect(testUI.Err).To(SatisfyAll(
   217  					Say("fake warning"),
   218  					Say("job processing warning"),
   219  					Say("job polling warning"),
   220  				))
   221  			})
   222  		})
   223  
   224  		Context("stream goes to error", func() {
   225  			BeforeEach(func() {
   226  				eventStream := make(chan v7action.PollJobEvent)
   227  				go func() {
   228  					eventStream <- v7action.PollJobEvent{
   229  						State:    v7action.JobFailed,
   230  						Warnings: v7action.Warnings{"job failed warning"},
   231  						Err:      errors.New("boom"),
   232  					}
   233  				}()
   234  
   235  				fakeActor.CreateServiceAppBindingReturns(
   236  					eventStream,
   237  					v7action.Warnings{"fake warning"},
   238  					nil,
   239  				)
   240  			})
   241  
   242  			It("prints warnings and returns the error", func() {
   243  				Expect(executeErr).To(MatchError("boom"))
   244  
   245  				Expect(testUI.Err).To(SatisfyAll(
   246  					Say("fake warning"),
   247  					Say("job failed warning"),
   248  				))
   249  			})
   250  		})
   251  
   252  		When("--wait flag specified", func() {
   253  			BeforeEach(func() {
   254  				eventStream := make(chan v7action.PollJobEvent)
   255  				go func() {
   256  					eventStream <- v7action.PollJobEvent{
   257  						State:    v7action.JobProcessing,
   258  						Warnings: v7action.Warnings{"job processing warning"},
   259  					}
   260  					eventStream <- v7action.PollJobEvent{
   261  						State:    v7action.JobPolling,
   262  						Warnings: v7action.Warnings{"job polling warning"},
   263  					}
   264  					eventStream <- v7action.PollJobEvent{
   265  						State:    v7action.JobComplete,
   266  						Warnings: v7action.Warnings{"job complete warning"},
   267  					}
   268  					close(eventStream)
   269  				}()
   270  
   271  				fakeActor.CreateServiceAppBindingReturns(
   272  					eventStream,
   273  					v7action.Warnings{"fake warning"},
   274  					nil,
   275  				)
   276  
   277  				setFlag(&cmd, "--wait")
   278  			})
   279  
   280  			It("waits for the event stream to complete", func() {
   281  				Expect(testUI.Out).To(SatisfyAll(
   282  					Say(`Waiting for the operation to complete\.\.\.\n`),
   283  					Say(`\n`),
   284  					Say(`OK\n`),
   285  					Say(`\n`),
   286  					Say(`TIP: Use 'cf restage %s' to ensure your env variable changes take effect\n`, fakeAppName),
   287  				))
   288  
   289  				Expect(testUI.Err).To(SatisfyAll(
   290  					Say("fake warning"),
   291  					Say("job processing warning"),
   292  					Say("job polling warning"),
   293  					Say("job complete warning"),
   294  				))
   295  			})
   296  		})
   297  	})
   298  
   299  	When("checking the target returns an error", func() {
   300  		BeforeEach(func() {
   301  			fakeSharedActor.CheckTargetReturns(errors.New("explode"))
   302  		})
   303  
   304  		It("returns the error", func() {
   305  			Expect(executeErr).To(MatchError("explode"))
   306  		})
   307  	})
   308  
   309  	When("actor returns error", func() {
   310  		BeforeEach(func() {
   311  			fakeActor.CreateServiceAppBindingReturns(
   312  				nil,
   313  				v7action.Warnings{"fake warning"},
   314  				errors.New("boom"),
   315  			)
   316  		})
   317  
   318  		It("prints warnings and returns the error", func() {
   319  			Expect(testUI.Err).To(Say("fake warning"))
   320  			Expect(executeErr).To(MatchError("boom"))
   321  		})
   322  	})
   323  
   324  	When("getting the username returns an error", func() {
   325  		BeforeEach(func() {
   326  			fakeActor.GetCurrentUserReturns(configv3.User{}, errors.New("bad thing"))
   327  		})
   328  
   329  		It("returns the error", func() {
   330  			Expect(executeErr).To(MatchError("bad thing"))
   331  		})
   332  	})
   333  })