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