github.com/liamawhite/cli-with-i18n@v6.32.1-0.20171122084555-dede0a5c3448+incompatible/command/v2/space_command_test.go (about) 1 package v2_test 2 3 import ( 4 "errors" 5 6 "github.com/liamawhite/cli-with-i18n/actor/sharedaction" 7 "github.com/liamawhite/cli-with-i18n/actor/v2action" 8 "github.com/liamawhite/cli-with-i18n/actor/v3action" 9 "github.com/liamawhite/cli-with-i18n/api/cloudcontroller/ccversion" 10 "github.com/liamawhite/cli-with-i18n/command/commandfakes" 11 "github.com/liamawhite/cli-with-i18n/command/translatableerror" 12 . "github.com/liamawhite/cli-with-i18n/command/v2" 13 "github.com/liamawhite/cli-with-i18n/command/v2/v2fakes" 14 "github.com/liamawhite/cli-with-i18n/util/configv3" 15 "github.com/liamawhite/cli-with-i18n/util/ui" 16 . "github.com/onsi/ginkgo" 17 . "github.com/onsi/gomega" 18 . "github.com/onsi/gomega/gbytes" 19 ) 20 21 var _ = Describe("space Command", func() { 22 var ( 23 cmd SpaceCommand 24 testUI *ui.UI 25 fakeConfig *commandfakes.FakeConfig 26 fakeSharedActor *commandfakes.FakeSharedActor 27 fakeActor *v2fakes.FakeSpaceActor 28 fakeActorV3 *v2fakes.FakeSpaceActorV3 29 binaryName string 30 executeErr error 31 ) 32 33 BeforeEach(func() { 34 testUI = ui.NewTestUI(nil, NewBuffer(), NewBuffer()) 35 fakeConfig = new(commandfakes.FakeConfig) 36 fakeSharedActor = new(commandfakes.FakeSharedActor) 37 fakeActor = new(v2fakes.FakeSpaceActor) 38 fakeActorV3 = new(v2fakes.FakeSpaceActorV3) 39 40 cmd = SpaceCommand{ 41 UI: testUI, 42 Config: fakeConfig, 43 SharedActor: fakeSharedActor, 44 Actor: fakeActor, 45 ActorV3: fakeActorV3, 46 } 47 48 binaryName = "faceman" 49 fakeConfig.BinaryNameReturns(binaryName) 50 fakeActor.CloudControllerAPIVersionReturns(ccversion.MinVersionLifecyleStagingV2) 51 fakeActorV3.CloudControllerAPIVersionReturns(ccversion.MinVersionIsolationSegmentV3) 52 }) 53 54 JustBeforeEach(func() { 55 executeErr = cmd.Execute(nil) 56 }) 57 58 Context("when checking the target fails", func() { 59 BeforeEach(func() { 60 fakeSharedActor.CheckTargetReturns( 61 sharedaction.NotLoggedInError{BinaryName: binaryName}) 62 }) 63 64 It("returns an error", func() { 65 Expect(executeErr).To(MatchError(translatableerror.NotLoggedInError{BinaryName: binaryName})) 66 67 Expect(fakeSharedActor.CheckTargetCallCount()).To(Equal(1)) 68 config, targetedOrganizationRequired, targetedSpaceRequired := fakeSharedActor.CheckTargetArgsForCall(0) 69 Expect(config).To(Equal(fakeConfig)) 70 Expect(targetedOrganizationRequired).To(Equal(true)) 71 Expect(targetedSpaceRequired).To(Equal(false)) 72 }) 73 }) 74 75 Context("when the --guid flag is provided", func() { 76 BeforeEach(func() { 77 cmd.RequiredArgs.Space = "some-space" 78 cmd.GUID = true 79 }) 80 81 Context("when no errors occur", func() { 82 BeforeEach(func() { 83 fakeConfig.TargetedOrganizationReturns( 84 configv3.Organization{GUID: "some-org-guid"}, 85 ) 86 fakeActor.GetSpaceByOrganizationAndNameReturns( 87 v2action.Space{GUID: "some-space-guid"}, 88 v2action.Warnings{"warning-1", "warning-2"}, 89 nil) 90 }) 91 92 It("displays the space guid and outputs all warnings", func() { 93 Expect(executeErr).ToNot(HaveOccurred()) 94 95 Expect(testUI.Out).To(Say("some-space-guid")) 96 Expect(testUI.Err).To(Say("warning-1")) 97 Expect(testUI.Err).To(Say("warning-2")) 98 99 Expect(fakeActor.GetSpaceByOrganizationAndNameCallCount()).To(Equal(1)) 100 orgGUID, spaceName := fakeActor.GetSpaceByOrganizationAndNameArgsForCall(0) 101 Expect(orgGUID).To(Equal("some-org-guid")) 102 Expect(spaceName).To(Equal("some-space")) 103 }) 104 }) 105 106 Context("when getting the space returns an error", func() { 107 Context("when the error is translatable", func() { 108 BeforeEach(func() { 109 fakeActor.GetSpaceByOrganizationAndNameReturns( 110 v2action.Space{}, 111 v2action.Warnings{"warning-1", "warning-2"}, 112 v2action.SpaceNotFoundError{Name: "some-space"}) 113 }) 114 115 It("returns a translatable error and outputs all warnings", func() { 116 Expect(executeErr).To(MatchError(translatableerror.SpaceNotFoundError{Name: "some-space"})) 117 118 Expect(testUI.Err).To(Say("warning-1")) 119 Expect(testUI.Err).To(Say("warning-2")) 120 }) 121 }) 122 123 Context("when the error is not translatable", func() { 124 var expectedErr error 125 126 BeforeEach(func() { 127 expectedErr = errors.New("get space error") 128 fakeActor.GetSpaceByOrganizationAndNameReturns( 129 v2action.Space{}, 130 v2action.Warnings{"warning-1", "warning-2"}, 131 expectedErr) 132 }) 133 134 It("returns the error and all warnings", func() { 135 Expect(executeErr).To(MatchError(expectedErr)) 136 137 Expect(testUI.Err).To(Say("warning-1")) 138 Expect(testUI.Err).To(Say("warning-2")) 139 }) 140 }) 141 }) 142 }) 143 144 Context("when the --guid flag is not provided", func() { 145 Context("when no errors occur", func() { 146 BeforeEach(func() { 147 fakeConfig.CurrentUserReturns( 148 configv3.User{ 149 Name: "some-user", 150 }, 151 nil) 152 153 cmd.RequiredArgs.Space = "some-space" 154 155 fakeConfig.TargetedOrganizationReturns( 156 configv3.Organization{ 157 GUID: "some-org-guid", 158 Name: "some-org", 159 }, 160 ) 161 162 fakeActor.GetSpaceSummaryByOrganizationAndNameReturns( 163 v2action.SpaceSummary{ 164 Space: v2action.Space{ 165 Name: "some-space", 166 GUID: "some-space-guid", 167 }, 168 OrgName: "some-org", 169 OrgDefaultIsolationSegmentGUID: "some-org-default-isolation-segment-guid", 170 AppNames: []string{"app1", "app2", "app3"}, 171 ServiceInstanceNames: []string{"service1", "service2", "service3"}, 172 SpaceQuotaName: "some-space-quota", 173 RunningSecurityGroupNames: []string{"public_networks", "dns", "load_balancer"}, 174 StagingSecurityGroupNames: []string{"staging-sec-1", "staging-sec-2"}, 175 }, 176 v2action.Warnings{"warning-1", "warning-2"}, 177 nil, 178 ) 179 }) 180 181 Context("when there is no v3 API", func() { 182 BeforeEach(func() { 183 cmd.ActorV3 = nil 184 }) 185 186 It("displays the space summary with no isolation segment row", func() { 187 Expect(executeErr).To(BeNil()) 188 Expect(testUI.Out).ToNot(Say("isolation segment:")) 189 }) 190 }) 191 192 Context("when there is a v3 API", func() { 193 BeforeEach(func() { 194 fakeActorV3.GetEffectiveIsolationSegmentBySpaceReturns( 195 v3action.IsolationSegment{ 196 Name: "some-isolation-segment", 197 }, 198 v3action.Warnings{"v3-warning-1", "v3-warning-2"}, 199 nil, 200 ) 201 }) 202 203 It("displays warnings and a table with space name, org, apps, services, isolation segment, space quota and security groups", func() { 204 Expect(executeErr).To(BeNil()) 205 206 Expect(testUI.Out).To(Say("Getting info for space some-space in org some-org as some-user\\.\\.\\.")) 207 Expect(testUI.Out).To(Say("name:\\s+some-space")) 208 Expect(testUI.Out).To(Say("org:\\s+some-org")) 209 Expect(testUI.Out).To(Say("apps:\\s+app1, app2, app3")) 210 Expect(testUI.Out).To(Say("services:\\s+service1, service2, service3")) 211 Expect(testUI.Out).To(Say("isolation segment:\\s+some-isolation-segment")) 212 Expect(testUI.Out).To(Say("space quota:\\s+some-space-quota")) 213 Expect(testUI.Out).To(Say("running security groups:\\s+public_networks, dns, load_balancer")) 214 Expect(testUI.Out).To(Say("staging security groups:\\s+staging-sec-1, staging-sec-2")) 215 216 Expect(testUI.Err).To(Say("warning-1")) 217 Expect(testUI.Err).To(Say("warning-2")) 218 Expect(testUI.Err).To(Say("v3-warning-1")) 219 Expect(testUI.Err).To(Say("v3-warning-2")) 220 221 Expect(fakeConfig.CurrentUserCallCount()).To(Equal(1)) 222 Expect(fakeActor.GetSpaceSummaryByOrganizationAndNameCallCount()).To(Equal(1)) 223 orgGUID, spaceName, includeStagingSecurityGroupRules := fakeActor.GetSpaceSummaryByOrganizationAndNameArgsForCall(0) 224 Expect(orgGUID).To(Equal("some-org-guid")) 225 Expect(spaceName).To(Equal("some-space")) 226 Expect(includeStagingSecurityGroupRules).To(BeTrue()) 227 Expect(fakeActorV3.GetEffectiveIsolationSegmentBySpaceCallCount()).To(Equal(1)) 228 spaceGUID, orgDefaultIsolationSegmentGUID := fakeActorV3.GetEffectiveIsolationSegmentBySpaceArgsForCall(0) 229 Expect(spaceGUID).To(Equal("some-space-guid")) 230 Expect(orgDefaultIsolationSegmentGUID).To(Equal("some-org-default-isolation-segment-guid")) 231 }) 232 }) 233 234 Context("when v3 api version is below 3.11.0 and the v2 api version is no less than 2.68.0", func() { 235 BeforeEach(func() { 236 fakeActor.CloudControllerAPIVersionReturns(ccversion.MinVersionLifecyleStagingV2) 237 fakeActorV3.CloudControllerAPIVersionReturns("3.10.0") 238 }) 239 240 It("displays warnings and a table with space name, org, apps, services, space quota and security groups", func() { 241 Expect(executeErr).To(BeNil()) 242 243 Expect(testUI.Out).NotTo(Say("isolation segment:")) 244 245 orgGUID, spaceName, includeStagingSecurityGroupRules := fakeActor.GetSpaceSummaryByOrganizationAndNameArgsForCall(0) 246 Expect(orgGUID).To(Equal("some-org-guid")) 247 Expect(spaceName).To(Equal("some-space")) 248 Expect(includeStagingSecurityGroupRules).To(BeTrue()) 249 Expect(fakeActorV3.GetEffectiveIsolationSegmentBySpaceCallCount()).To(Equal(0)) 250 }) 251 }) 252 253 Context("when v3 api version is below 3.11.0 and the v2 api version is less than 2.68.0 (v2 will never be above 2.68.0 if v3 is lower than 3.11.0)", func() { 254 BeforeEach(func() { 255 fakeActor.CloudControllerAPIVersionReturns("2.54.0") 256 fakeActorV3.CloudControllerAPIVersionReturns("3.10.0") 257 }) 258 259 It("displays warnings and a table with no values for staging security groups", func() { 260 Expect(executeErr).To(BeNil()) 261 262 Expect(testUI.Out).NotTo(Say("isolation segment:")) 263 264 orgGUID, spaceName, includeStagingSecurityGroupRules := fakeActor.GetSpaceSummaryByOrganizationAndNameArgsForCall(0) 265 Expect(orgGUID).To(Equal("some-org-guid")) 266 Expect(spaceName).To(Equal("some-space")) 267 Expect(includeStagingSecurityGroupRules).To(BeFalse()) 268 Expect(fakeActorV3.GetEffectiveIsolationSegmentBySpaceCallCount()).To(Equal(0)) 269 }) 270 }) 271 }) 272 }) 273 274 Context("when getting the current user returns an error", func() { 275 var expectedErr error 276 277 BeforeEach(func() { 278 expectedErr = errors.New("getting current user error") 279 fakeConfig.CurrentUserReturns( 280 configv3.User{}, 281 expectedErr) 282 }) 283 284 It("returns the error", func() { 285 Expect(executeErr).To(MatchError(expectedErr)) 286 }) 287 }) 288 289 Context("when getting the space summary returns an error", func() { 290 Context("when the error is translatable", func() { 291 BeforeEach(func() { 292 fakeActor.GetSpaceSummaryByOrganizationAndNameReturns( 293 v2action.SpaceSummary{}, 294 v2action.Warnings{"warning-1", "warning-2"}, 295 v2action.SpaceNotFoundError{Name: "some-space"}) 296 }) 297 298 It("returns a translatable error and outputs all warnings", func() { 299 Expect(executeErr).To(MatchError(translatableerror.SpaceNotFoundError{Name: "some-space"})) 300 301 Expect(testUI.Err).To(Say("warning-1")) 302 Expect(testUI.Err).To(Say("warning-2")) 303 }) 304 }) 305 306 Context("when the error is not translatable", func() { 307 var expectedErr error 308 309 BeforeEach(func() { 310 expectedErr = errors.New("get space summary error") 311 fakeActor.GetSpaceSummaryByOrganizationAndNameReturns( 312 v2action.SpaceSummary{}, 313 v2action.Warnings{"warning-1", "warning-2"}, 314 expectedErr) 315 }) 316 317 It("returns the error and all warnings", func() { 318 Expect(executeErr).To(MatchError(expectedErr)) 319 320 Expect(testUI.Err).To(Say("warning-1")) 321 Expect(testUI.Err).To(Say("warning-2")) 322 }) 323 }) 324 }) 325 326 Context("when getting the isolation segment returns an error", func() { 327 Context("a generic error", func() { 328 var expectedErr error 329 330 BeforeEach(func() { 331 expectedErr = errors.New("get isolation segment error") 332 fakeActorV3.GetEffectiveIsolationSegmentBySpaceReturns( 333 v3action.IsolationSegment{}, 334 v3action.Warnings{"v3-warning-1", "v3-warning-2"}, 335 expectedErr) 336 }) 337 338 It("returns the error and all warnings", func() { 339 Expect(executeErr).To(MatchError(expectedErr)) 340 341 Expect(testUI.Err).To(Say("v3-warning-1")) 342 Expect(testUI.Err).To(Say("v3-warning-2")) 343 }) 344 }) 345 346 Context("a NoRelationshipError", func() { 347 BeforeEach(func() { 348 fakeActorV3.GetEffectiveIsolationSegmentBySpaceReturns( 349 v3action.IsolationSegment{}, 350 v3action.Warnings{"v3-warning-1", "v3-warning-2"}, 351 v3action.NoRelationshipError{}) 352 }) 353 354 It("does not fill in the isolation segment", func() { 355 Expect(executeErr).ToNot(HaveOccurred()) 356 Expect(testUI.Out).To(Say("(?m)isolation segment:\\s*$")) 357 }) 358 }) 359 }) 360 361 Context("when the --security-group-rules flag is provided", func() { 362 BeforeEach(func() { 363 fakeConfig.CurrentUserReturns( 364 configv3.User{ 365 Name: "some-user", 366 }, 367 nil) 368 369 cmd.RequiredArgs.Space = "some-space" 370 cmd.SecurityGroupRules = true 371 372 fakeConfig.TargetedOrganizationReturns( 373 configv3.Organization{ 374 GUID: "some-org-guid", 375 Name: "some-org", 376 }, 377 ) 378 379 fakeActor.GetSpaceSummaryByOrganizationAndNameReturns( 380 v2action.SpaceSummary{ 381 Space: v2action.Space{ 382 Name: "some-space", 383 }, 384 OrgName: "some-org", 385 AppNames: []string{"app1", "app2", "app3"}, 386 ServiceInstanceNames: []string{"service1", "service2", "service3"}, 387 SpaceQuotaName: "some-space-quota", 388 RunningSecurityGroupNames: []string{"public_networks", "dns", "load_balancer"}, 389 StagingSecurityGroupNames: []string{"staging-sec-1", "staging-sec-2"}, 390 SecurityGroupRules: []v2action.SecurityGroupRule{ 391 { 392 Description: "Public networks", 393 Destination: "0.0.0.0-9.255.255.255", 394 Lifecycle: "staging", 395 Name: "public_networks", 396 Ports: "12345", 397 Protocol: "tcp", 398 }, 399 { 400 Description: "Public networks", 401 Destination: "0.0.0.0-9.255.255.255", 402 Lifecycle: "running", 403 Name: "public_networks", 404 Ports: "12345", 405 Protocol: "tcp", 406 }, 407 { 408 Description: "More public networks", 409 Destination: "11.0.0.0-169.253.255.255", 410 Lifecycle: "staging", 411 Name: "more_public_networks", 412 Ports: "54321", 413 Protocol: "udp", 414 }, 415 { 416 Description: "More public networks", 417 Destination: "11.0.0.0-169.253.255.255", 418 Lifecycle: "running", 419 Name: "more_public_networks", 420 Ports: "54321", 421 Protocol: "udp", 422 }, 423 }, 424 }, 425 v2action.Warnings{"warning-1", "warning-2"}, 426 nil, 427 ) 428 }) 429 430 It("displays warnings and security group rules", func() { 431 Expect(executeErr).To(BeNil()) 432 433 orgGUID, spaceName, includeStagingSecurityGroupRules := fakeActor.GetSpaceSummaryByOrganizationAndNameArgsForCall(0) 434 Expect(orgGUID).To(Equal("some-org-guid")) 435 Expect(spaceName).To(Equal("some-space")) 436 Expect(includeStagingSecurityGroupRules).To(BeTrue()) 437 438 Expect(testUI.Out).To(Say("name:\\s+some-space")) 439 Expect(testUI.Out).To(Say("running security groups:\\s+public_networks, dns, load_balancer")) 440 Expect(testUI.Out).To(Say("staging security groups:\\s+staging-sec-1, staging-sec-2")) 441 Expect(testUI.Out).To(Say("(?m)^\n^\\s+security group\\s+destination\\s+ports\\s+protocol\\s+lifecycle\\s+description$")) 442 Expect(testUI.Out).To(Say("#0\\s+public_networks\\s+0.0.0.0-9.255.255.255\\s+12345\\s+tcp\\s+staging\\s+Public networks")) 443 Expect(testUI.Out).To(Say("(?m)^\\s+public_networks\\s+0.0.0.0-9.255.255.255\\s+12345\\s+tcp\\s+running\\s+Public networks")) 444 Expect(testUI.Out).To(Say("#1\\s+more_public_networks\\s+11.0.0.0-169.253.255.255\\s+54321\\s+udp\\s+staging\\s+More public networks")) 445 Expect(testUI.Out).To(Say("(?m)\\s+more_public_networks\\s+11.0.0.0-169.253.255.255\\s+54321\\s+udp\\s+running\\s+More public networks")) 446 }) 447 }) 448 })