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 })