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

     1  package v7_test
     2  
     3  import (
     4  	"errors"
     5  	"fmt"
     6  
     7  	"github.com/LukasHeimann/cloudfoundrycli/v8/actor/actionerror"
     8  
     9  	"github.com/LukasHeimann/cloudfoundrycli/v8/actor/v7action"
    10  	"github.com/LukasHeimann/cloudfoundrycli/v8/command/commandfakes"
    11  	v7 "github.com/LukasHeimann/cloudfoundrycli/v8/command/v7"
    12  	"github.com/LukasHeimann/cloudfoundrycli/v8/command/v7/v7fakes"
    13  	"github.com/LukasHeimann/cloudfoundrycli/v8/util/configv3"
    14  	"github.com/LukasHeimann/cloudfoundrycli/v8/util/ui"
    15  	. "github.com/onsi/ginkgo"
    16  	. "github.com/onsi/gomega"
    17  	. "github.com/onsi/gomega/gbytes"
    18  )
    19  
    20  var _ = Describe("unbind-route-service Command", func() {
    21  	var (
    22  		cmd             v7.UnbindRouteServiceCommand
    23  		input           *Buffer
    24  		testUI          *ui.UI
    25  		fakeConfig      *commandfakes.FakeConfig
    26  		fakeSharedActor *commandfakes.FakeSharedActor
    27  		executeErr      error
    28  		fakeActor       *v7fakes.FakeActor
    29  	)
    30  
    31  	const (
    32  		fakeUserName            = "fake-user-name"
    33  		fakeServiceInstanceName = "fake-service-instance-name"
    34  		fakeDomainName          = "fake-domain-name"
    35  		fakeHostname            = "fake-hostname"
    36  		fakePath                = "fake-path"
    37  		fakeOrgName             = "fake-org-name"
    38  		fakeSpaceName           = "fake-space-name"
    39  		fakeSpaceGUID           = "fake-space-guid"
    40  	)
    41  
    42  	BeforeEach(func() {
    43  		input = NewBuffer()
    44  		testUI = ui.NewTestUI(input, NewBuffer(), NewBuffer())
    45  		fakeConfig = new(commandfakes.FakeConfig)
    46  		fakeSharedActor = new(commandfakes.FakeSharedActor)
    47  		fakeActor = new(v7fakes.FakeActor)
    48  
    49  		cmd = v7.UnbindRouteServiceCommand{
    50  			BaseCommand: v7.BaseCommand{
    51  				UI:          testUI,
    52  				Config:      fakeConfig,
    53  				SharedActor: fakeSharedActor,
    54  				Actor:       fakeActor,
    55  			},
    56  		}
    57  
    58  		fakeConfig.TargetedSpaceReturns(configv3.Space{
    59  			Name: fakeSpaceName,
    60  			GUID: fakeSpaceGUID,
    61  		})
    62  
    63  		fakeConfig.TargetedOrganizationReturns(configv3.Organization{Name: fakeOrgName})
    64  
    65  		fakeActor.GetCurrentUserReturns(configv3.User{Name: fakeUserName}, nil)
    66  
    67  		fakeActor.DeleteRouteBindingReturns(
    68  			nil,
    69  			v7action.Warnings{"fake warning"},
    70  			nil,
    71  		)
    72  
    73  		setPositionalFlags(&cmd, fakeDomainName, fakeServiceInstanceName)
    74  		setFlag(&cmd, "--hostname", fakeHostname)
    75  		setFlag(&cmd, "--path", fakePath)
    76  		setFlag(&cmd, "-f")
    77  	})
    78  
    79  	JustBeforeEach(func() {
    80  		executeErr = cmd.Execute(nil)
    81  	})
    82  
    83  	It("succeeds", func() {
    84  		Expect(executeErr).NotTo(HaveOccurred())
    85  	})
    86  
    87  	It("checks the user is logged in, and targeting an org and space", func() {
    88  		Expect(fakeSharedActor.CheckTargetCallCount()).To(Equal(1))
    89  		actualOrg, actualSpace := fakeSharedActor.CheckTargetArgsForCall(0)
    90  		Expect(actualOrg).To(BeTrue())
    91  		Expect(actualSpace).To(BeTrue())
    92  	})
    93  
    94  	It("delegates to the actor", func() {
    95  		Expect(fakeActor.DeleteRouteBindingCallCount()).To(Equal(1))
    96  		Expect(fakeActor.DeleteRouteBindingArgsForCall(0)).To(Equal(v7action.DeleteRouteBindingParams{
    97  			SpaceGUID:           fakeSpaceGUID,
    98  			ServiceInstanceName: fakeServiceInstanceName,
    99  			DomainName:          fakeDomainName,
   100  			Hostname:            fakeHostname,
   101  			Path:                fmt.Sprintf("/%s", fakePath),
   102  		}))
   103  	})
   104  
   105  	When("binding does not exist", func() {
   106  		BeforeEach(func() {
   107  			fakeActor.DeleteRouteBindingReturns(
   108  				nil,
   109  				v7action.Warnings{"fake warning"},
   110  				actionerror.RouteBindingNotFoundError{},
   111  			)
   112  		})
   113  
   114  		It("prints a message and warnings", func() {
   115  			Expect(testUI.Out).To(SatisfyAll(
   116  				Say(
   117  					`Route %s.%s/%s was not bound to service instance %s\.\n`,
   118  					fakeHostname,
   119  					fakeDomainName,
   120  					fakePath,
   121  					fakeServiceInstanceName,
   122  				),
   123  				Say(`OK\n`),
   124  			))
   125  
   126  			Expect(testUI.Err).To(Say("fake warning"))
   127  		})
   128  	})
   129  
   130  	Describe("intro message", func() {
   131  		It("prints an intro and warnings", func() {
   132  			Expect(executeErr).NotTo(HaveOccurred())
   133  			Expect(testUI.Err).To(Say("fake warning"))
   134  			Expect(testUI.Out).To(Say(
   135  				`Unbinding route %s.%s/%s from service instance %s in org %s / space %s as %s\.\.\.\n`,
   136  				fakeHostname,
   137  				fakeDomainName,
   138  				fakePath,
   139  				fakeServiceInstanceName,
   140  				fakeOrgName,
   141  				fakeSpaceName,
   142  				fakeUserName,
   143  			))
   144  		})
   145  
   146  		When("no hostname", func() {
   147  			BeforeEach(func() {
   148  				setFlag(&cmd, "--hostname", "")
   149  			})
   150  
   151  			It("prints an appropriate intro", func() {
   152  				Expect(testUI.Out).To(Say(
   153  					`Unbinding route %s/%s from service instance`,
   154  					fakeDomainName,
   155  					fakePath,
   156  				))
   157  			})
   158  		})
   159  
   160  		When("no path", func() {
   161  			BeforeEach(func() {
   162  				setFlag(&cmd, "--path", "")
   163  			})
   164  
   165  			It("prints an appropriate intro", func() {
   166  				Expect(testUI.Out).To(Say(
   167  					`Unbinding route %s.%s from service instance`,
   168  					fakeHostname,
   169  					fakeDomainName,
   170  				))
   171  			})
   172  		})
   173  
   174  		When("no hostname or path", func() {
   175  			BeforeEach(func() {
   176  				setFlag(&cmd, "--path", "")
   177  				setFlag(&cmd, "--hostname", "")
   178  			})
   179  
   180  			It("prints an appropriate intro", func() {
   181  				Expect(testUI.Out).To(Say(
   182  					`Unbinding route %s from service instance`,
   183  					fakeDomainName,
   184  				))
   185  			})
   186  		})
   187  	})
   188  
   189  	Describe("prompting the user", func() {
   190  		BeforeEach(func() {
   191  			setFlag(&cmd, "-f", false)
   192  		})
   193  
   194  		It("prompts the user", func() {
   195  			Expect(testUI.Out).To(Say(
   196  				`Really unbind route %s.%s/%s from service instance %s\? \[yN\]:`,
   197  				fakeHostname,
   198  				fakeDomainName,
   199  				fakePath,
   200  				fakeServiceInstanceName,
   201  			))
   202  		})
   203  
   204  		When("no hostname", func() {
   205  			BeforeEach(func() {
   206  				setFlag(&cmd, "--hostname", "")
   207  			})
   208  
   209  			It("prompts the user", func() {
   210  				Expect(testUI.Out).To(Say(
   211  					`Really unbind route %s/%s from service instance %s\? \[yN\]:`,
   212  					fakeDomainName,
   213  					fakePath,
   214  					fakeServiceInstanceName,
   215  				))
   216  			})
   217  		})
   218  
   219  		When("no path", func() {
   220  			BeforeEach(func() {
   221  				setFlag(&cmd, "--path", "")
   222  			})
   223  
   224  			It("prompts the user", func() {
   225  				Expect(testUI.Out).To(Say(
   226  					`Really unbind route %s.%s from service instance %s\? \[yN\]:`,
   227  					fakeHostname,
   228  					fakeDomainName,
   229  					fakeServiceInstanceName,
   230  				))
   231  			})
   232  		})
   233  
   234  		When("no hostname or path", func() {
   235  			BeforeEach(func() {
   236  				setFlag(&cmd, "--hostname", "")
   237  				setFlag(&cmd, "--path", "")
   238  			})
   239  
   240  			It("prompts the user", func() {
   241  				Expect(testUI.Out).To(Say(
   242  					`Really unbind route %s from service instance %s\? \[yN\]:`,
   243  					fakeDomainName,
   244  					fakeServiceInstanceName,
   245  				))
   246  			})
   247  		})
   248  
   249  		When("user says no", func() {
   250  			BeforeEach(func() {
   251  				_, err := input.Write([]byte("n\n"))
   252  				Expect(err).NotTo(HaveOccurred())
   253  			})
   254  
   255  			It("does not call the actor", func() {
   256  				Expect(fakeActor.DeleteRouteBindingCallCount()).To(BeZero())
   257  			})
   258  
   259  			It("says the unbind was cancelled", func() {
   260  				Expect(executeErr).NotTo(HaveOccurred())
   261  				Expect(testUI.Out).To(Say("Unbind cancelled\n"))
   262  			})
   263  		})
   264  
   265  		When("user says yes", func() {
   266  			BeforeEach(func() {
   267  				_, err := input.Write([]byte("y\n"))
   268  				Expect(err).NotTo(HaveOccurred())
   269  			})
   270  
   271  			It("calls the actor", func() {
   272  				Expect(fakeActor.DeleteRouteBindingCallCount()).To(Equal(1))
   273  			})
   274  		})
   275  	})
   276  
   277  	Describe("processing the response stream", func() {
   278  		Context("nil stream", func() {
   279  			It("prints a message and warnings", func() {
   280  				Expect(testUI.Out).To(Say(`OK\n`))
   281  				Expect(testUI.Err).To(Say("fake warning"))
   282  			})
   283  		})
   284  
   285  		Context("stream goes to complete", func() {
   286  			BeforeEach(func() {
   287  				eventStream := make(chan v7action.PollJobEvent)
   288  				go func() {
   289  					eventStream <- v7action.PollJobEvent{
   290  						State:    v7action.JobProcessing,
   291  						Warnings: v7action.Warnings{"job processing warning"},
   292  					}
   293  					eventStream <- v7action.PollJobEvent{
   294  						State:    v7action.JobComplete,
   295  						Warnings: v7action.Warnings{"job complete warning"},
   296  					}
   297  					close(eventStream)
   298  				}()
   299  
   300  				fakeActor.DeleteRouteBindingReturns(
   301  					eventStream,
   302  					v7action.Warnings{"fake warning"},
   303  					nil,
   304  				)
   305  			})
   306  
   307  			It("prints a message and warnings", func() {
   308  				Expect(testUI.Out).To(Say(`OK\n`))
   309  
   310  				Expect(testUI.Err).To(SatisfyAll(
   311  					Say("fake warning"),
   312  					Say("job processing warning"),
   313  					Say("job complete warning"),
   314  				))
   315  			})
   316  		})
   317  
   318  		Context("stream goes to polling", func() {
   319  			BeforeEach(func() {
   320  				eventStream := make(chan v7action.PollJobEvent)
   321  				go func() {
   322  					eventStream <- v7action.PollJobEvent{
   323  						State:    v7action.JobProcessing,
   324  						Warnings: v7action.Warnings{"job processing warning"},
   325  					}
   326  					eventStream <- v7action.PollJobEvent{
   327  						State:    v7action.JobPolling,
   328  						Warnings: v7action.Warnings{"job polling warning"},
   329  					}
   330  				}()
   331  
   332  				fakeActor.DeleteRouteBindingReturns(
   333  					eventStream,
   334  					v7action.Warnings{"fake warning"},
   335  					nil,
   336  				)
   337  			})
   338  
   339  			It("prints a message and warnings", func() {
   340  				Expect(testUI.Out).To(SatisfyAll(
   341  					Say(`OK\n`),
   342  					Say(`\n`),
   343  					Say(`Unbinding in progress\.\n`),
   344  				))
   345  
   346  				Expect(testUI.Err).To(SatisfyAll(
   347  					Say("fake warning"),
   348  					Say("job processing warning"),
   349  					Say("job polling warning"),
   350  				))
   351  			})
   352  		})
   353  
   354  		Context("stream goes to error", func() {
   355  			BeforeEach(func() {
   356  				eventStream := make(chan v7action.PollJobEvent)
   357  				go func() {
   358  					eventStream <- v7action.PollJobEvent{
   359  						State:    v7action.JobFailed,
   360  						Warnings: v7action.Warnings{"job failed warning"},
   361  						Err:      errors.New("boom"),
   362  					}
   363  				}()
   364  
   365  				fakeActor.DeleteRouteBindingReturns(
   366  					eventStream,
   367  					v7action.Warnings{"fake warning"},
   368  					nil,
   369  				)
   370  			})
   371  
   372  			It("prints warnings and returns the error", func() {
   373  				Expect(executeErr).To(MatchError("boom"))
   374  
   375  				Expect(testUI.Err).To(SatisfyAll(
   376  					Say("fake warning"),
   377  					Say("job failed warning"),
   378  				))
   379  			})
   380  		})
   381  
   382  		When("--wait flag specified", func() {
   383  			BeforeEach(func() {
   384  				eventStream := make(chan v7action.PollJobEvent)
   385  				go func() {
   386  					eventStream <- v7action.PollJobEvent{
   387  						State:    v7action.JobProcessing,
   388  						Warnings: v7action.Warnings{"job processing warning"},
   389  					}
   390  					eventStream <- v7action.PollJobEvent{
   391  						State:    v7action.JobPolling,
   392  						Warnings: v7action.Warnings{"job polling warning"},
   393  					}
   394  					eventStream <- v7action.PollJobEvent{
   395  						State:    v7action.JobComplete,
   396  						Warnings: v7action.Warnings{"job complete warning"},
   397  					}
   398  					close(eventStream)
   399  				}()
   400  
   401  				fakeActor.DeleteRouteBindingReturns(
   402  					eventStream,
   403  					v7action.Warnings{"fake warning"},
   404  					nil,
   405  				)
   406  
   407  				setFlag(&cmd, "--wait")
   408  			})
   409  
   410  			It("waits for the event stream to complete", func() {
   411  				Expect(testUI.Out).To(SatisfyAll(
   412  					Say(`Waiting for the operation to complete\.\.\.\n`),
   413  					Say(`\n`),
   414  					Say(`OK\n`),
   415  				))
   416  
   417  				Expect(testUI.Err).To(SatisfyAll(
   418  					Say("fake warning"),
   419  					Say("job processing warning"),
   420  					Say("job polling warning"),
   421  					Say("job complete warning"),
   422  				))
   423  			})
   424  		})
   425  	})
   426  
   427  	Describe("error scenarios", func() {
   428  		When("checking the target returns an error", func() {
   429  			BeforeEach(func() {
   430  				fakeSharedActor.CheckTargetReturns(errors.New("explode"))
   431  			})
   432  
   433  			It("returns the error", func() {
   434  				Expect(executeErr).To(MatchError("explode"))
   435  			})
   436  		})
   437  
   438  		When("actor returns error", func() {
   439  			BeforeEach(func() {
   440  				fakeActor.DeleteRouteBindingReturns(
   441  					nil,
   442  					v7action.Warnings{"fake warning"},
   443  					errors.New("boom"),
   444  				)
   445  			})
   446  
   447  			It("prints warnings and returns the error", func() {
   448  				Expect(testUI.Err).To(Say("fake warning"))
   449  				Expect(executeErr).To(MatchError("boom"))
   450  			})
   451  		})
   452  
   453  		When("getting the username returns an error", func() {
   454  			BeforeEach(func() {
   455  				fakeActor.GetCurrentUserReturns(configv3.User{}, errors.New("bad thing"))
   456  			})
   457  
   458  			It("returns the error", func() {
   459  				Expect(executeErr).To(MatchError("bad thing"))
   460  			})
   461  		})
   462  	})
   463  })