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