github.com/nimakaviani/cli@v6.37.1-0.20180619223813-e734901a73fa+incompatible/command/v2/create_route_command_test.go (about)

     1  package v2_test
     2  
     3  import (
     4  	"errors"
     5  
     6  	"code.cloudfoundry.org/cli/actor/actionerror"
     7  	"code.cloudfoundry.org/cli/actor/v2action"
     8  	"code.cloudfoundry.org/cli/api/cloudcontroller/ccversion"
     9  	"code.cloudfoundry.org/cli/command/commandfakes"
    10  	"code.cloudfoundry.org/cli/command/flag"
    11  	"code.cloudfoundry.org/cli/command/translatableerror"
    12  	. "code.cloudfoundry.org/cli/command/v2"
    13  	"code.cloudfoundry.org/cli/command/v2/v2fakes"
    14  	"code.cloudfoundry.org/cli/types"
    15  	"code.cloudfoundry.org/cli/util/configv3"
    16  	"code.cloudfoundry.org/cli/util/ui"
    17  	. "github.com/onsi/ginkgo"
    18  	. "github.com/onsi/ginkgo/extensions/table"
    19  	. "github.com/onsi/gomega"
    20  	. "github.com/onsi/gomega/gbytes"
    21  )
    22  
    23  var _ = Describe("Create Route Command", func() {
    24  	var (
    25  		cmd             CreateRouteCommand
    26  		testUI          *ui.UI
    27  		fakeConfig      *commandfakes.FakeConfig
    28  		fakeSharedActor *commandfakes.FakeSharedActor
    29  		fakeActor       *v2fakes.FakeCreateRouteActor
    30  		binaryName      string
    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.FakeCreateRouteActor)
    38  
    39  		cmd = CreateRouteCommand{
    40  			UI:          testUI,
    41  			Config:      fakeConfig,
    42  			SharedActor: fakeSharedActor,
    43  			Actor:       fakeActor,
    44  		}
    45  
    46  		cmd.RequiredArgs.Space = "some-space"
    47  		cmd.RequiredArgs.Domain = "some-domain"
    48  
    49  		binaryName = "faceman"
    50  		fakeConfig.BinaryNameReturns(binaryName)
    51  		fakeActor.CloudControllerAPIVersionReturns(ccversion.MinVersionTCPRouting)
    52  	})
    53  
    54  	DescribeTable("argument combinations",
    55  		func(expectedErr error, hostname string, path string, port flag.Port, randomPort bool) {
    56  			cmd.Port = port
    57  			cmd.Hostname = hostname
    58  			cmd.Path = path
    59  			cmd.RandomPort = randomPort
    60  
    61  			executeErr := cmd.Execute(nil)
    62  			if expectedErr == nil {
    63  				Expect(executeErr).To(BeNil())
    64  			} else {
    65  				Expect(executeErr).To(Equal(expectedErr))
    66  			}
    67  		},
    68  		Entry("hostname", nil, "some-hostname", "", flag.Port{NullInt: types.NullInt{IsSet: false}}, false),
    69  		Entry("path", nil, "", "some-path", flag.Port{NullInt: types.NullInt{IsSet: false}}, false),
    70  		Entry("hostname and path", nil, "some-hostname", "some-path", flag.Port{NullInt: types.NullInt{IsSet: false}}, false),
    71  		Entry("hostname and port", translatableerror.ArgumentCombinationError{Args: []string{"--hostname", "--port"}}, "some-hostname", "", flag.Port{NullInt: types.NullInt{IsSet: true}}, false),
    72  		Entry("path and port", translatableerror.ArgumentCombinationError{Args: []string{"--path", "--port"}}, "", "some-path", flag.Port{NullInt: types.NullInt{IsSet: true}}, false),
    73  		Entry("hostname, path, and port", translatableerror.ArgumentCombinationError{Args: []string{"--hostname", "--path", "--port"}}, "some-hostname", "some-path", flag.Port{NullInt: types.NullInt{IsSet: true}}, false),
    74  		Entry("hostname and random port", translatableerror.ArgumentCombinationError{Args: []string{"--hostname", "--random-port"}}, "some-hostname", "", flag.Port{NullInt: types.NullInt{IsSet: false}}, true),
    75  		Entry("path and random port", translatableerror.ArgumentCombinationError{Args: []string{"--path", "--random-port"}}, "", "some-path", flag.Port{NullInt: types.NullInt{IsSet: false}}, true),
    76  		Entry("hostname, path, and random port", translatableerror.ArgumentCombinationError{Args: []string{"--hostname", "--path", "--random-port"}}, "some-hostname", "some-path", flag.Port{NullInt: types.NullInt{IsSet: false}}, true),
    77  		Entry("port", nil, "", "", flag.Port{NullInt: types.NullInt{IsSet: true}}, false),
    78  		Entry("random port", nil, "", "", flag.Port{NullInt: types.NullInt{IsSet: false}}, true),
    79  		Entry("port and random port", translatableerror.ArgumentCombinationError{Args: []string{"--port", "--random-port"}}, "", "", flag.Port{NullInt: types.NullInt{IsSet: true}}, true),
    80  	)
    81  
    82  	DescribeTable("minimum api version checks",
    83  		func(expectedErr error, port flag.Port, randomPort bool, path string, apiVersion string) {
    84  			cmd.Port = port
    85  			cmd.RandomPort = randomPort
    86  			cmd.Path = path
    87  			fakeActor.CloudControllerAPIVersionReturns(apiVersion)
    88  
    89  			executeErr := cmd.Execute(nil)
    90  			if expectedErr == nil {
    91  				Expect(executeErr).To(BeNil())
    92  			} else {
    93  				Expect(executeErr).To(Equal(expectedErr))
    94  			}
    95  		},
    96  
    97  		Entry("port, CC Version 2.52.0", translatableerror.MinimumAPIVersionNotMetError{
    98  			Command:        "Option '--port'",
    99  			CurrentVersion: "2.52.0",
   100  			MinimumVersion: ccversion.MinVersionTCPRouting,
   101  		}, flag.Port{NullInt: types.NullInt{IsSet: true}}, false, "", "2.52.0"),
   102  
   103  		Entry("port, CC Version 2.53.0", nil, flag.Port{NullInt: types.NullInt{IsSet: true}}, false, "", ccversion.MinVersionTCPRouting),
   104  
   105  		Entry("random-port, CC Version 2.52.0", translatableerror.MinimumAPIVersionNotMetError{
   106  			Command:        "Option '--random-port'",
   107  			CurrentVersion: "2.52.0",
   108  			MinimumVersion: ccversion.MinVersionTCPRouting,
   109  		}, flag.Port{}, true, "", "2.52.0"),
   110  
   111  		Entry("random-port, CC Version 2.53.0", nil, flag.Port{}, true, "", ccversion.MinVersionTCPRouting),
   112  
   113  		Entry("path, CC Version 2.35.0", translatableerror.MinimumAPIVersionNotMetError{
   114  			Command:        "Option '--path'",
   115  			CurrentVersion: "2.35.0",
   116  			MinimumVersion: ccversion.MinVersionHTTPRoutePath,
   117  		}, flag.Port{}, false, "some-path", "2.35.0"),
   118  
   119  		Entry("path, CC Version 2.36.0", nil, flag.Port{}, false, "some-path", ccversion.MinVersionHTTPRoutePath),
   120  	)
   121  
   122  	Context("when all the arguments check out", func() {
   123  		var executeErr error
   124  
   125  		JustBeforeEach(func() {
   126  			executeErr = cmd.Execute(nil)
   127  		})
   128  
   129  		Context("when checking target fails", func() {
   130  			BeforeEach(func() {
   131  				fakeSharedActor.CheckTargetReturns(translatableerror.NotLoggedInError{BinaryName: binaryName})
   132  			})
   133  
   134  			It("returns an error if the check fails", func() {
   135  				Expect(executeErr).To(MatchError(translatableerror.NotLoggedInError{BinaryName: "faceman"}))
   136  
   137  				Expect(fakeSharedActor.CheckTargetCallCount()).To(Equal(1))
   138  				checkTargetedOrg, checkTargetedSpace := fakeSharedActor.CheckTargetArgsForCall(0)
   139  				Expect(checkTargetedOrg).To(BeTrue())
   140  				Expect(checkTargetedSpace).To(BeFalse())
   141  			})
   142  		})
   143  
   144  		Context("when getting the current user returns an error", func() {
   145  			var expectedErr error
   146  
   147  			BeforeEach(func() {
   148  				expectedErr = errors.New("getting current user error")
   149  				fakeConfig.CurrentUserReturns(
   150  					configv3.User{},
   151  					expectedErr)
   152  			})
   153  
   154  			It("returns the error", func() {
   155  				Expect(executeErr).To(MatchError(expectedErr))
   156  			})
   157  		})
   158  
   159  		Context("when the user is logged in, and the org is targeted", func() {
   160  			BeforeEach(func() {
   161  				fakeConfig.HasTargetedOrganizationReturns(true)
   162  				fakeConfig.TargetedOrganizationReturns(configv3.Organization{GUID: "some-org-guid", Name: "some-org"})
   163  				fakeConfig.CurrentUserReturns(
   164  					configv3.User{Name: "some-user"},
   165  					nil)
   166  			})
   167  
   168  			Context("when no flags are provided", func() {
   169  				BeforeEach(func() {
   170  					fakeActor.CreateRouteWithExistenceCheckReturns(v2action.Route{
   171  						Domain: v2action.Domain{
   172  							Name: "some-domain",
   173  						}}, v2action.Warnings{"create-route-warning-1", "create-route-warning-2"}, nil)
   174  				})
   175  
   176  				It("creates a route with existence check", func() {
   177  					Expect(executeErr).ToNot(HaveOccurred())
   178  					Expect(testUI.Out).To(Say("Creating route some-domain for org some-org / space some-space as some-user\\.\\.\\."))
   179  					Expect(testUI.Err).To(Say("create-route-warning-1"))
   180  					Expect(testUI.Err).To(Say("create-route-warning-2"))
   181  					Expect(testUI.Out).To(Say("Route some-domain has been created\\."))
   182  					Expect(testUI.Out).To(Say("OK"))
   183  
   184  					Expect(fakeActor.CreateRouteWithExistenceCheckCallCount()).To(Equal(1))
   185  					orgGUID, spaceName, route, generatePort := fakeActor.CreateRouteWithExistenceCheckArgsForCall(0)
   186  					Expect(orgGUID).To(Equal("some-org-guid"))
   187  					Expect(spaceName).To(Equal("some-space"))
   188  					Expect(route.Host).To(BeEmpty())
   189  					Expect(route.Path).To(BeEmpty())
   190  					Expect(route.Port).To(Equal(types.NullInt{IsSet: false}))
   191  					Expect(generatePort).To(BeFalse())
   192  				})
   193  			})
   194  
   195  			Context("when host and path flags are provided", func() {
   196  				BeforeEach(func() {
   197  					cmd.Hostname = "some-host"
   198  					cmd.Path = "some-path"
   199  
   200  					fakeActor.CreateRouteWithExistenceCheckReturns(v2action.Route{
   201  						Domain: v2action.Domain{
   202  							Name: "some-domain",
   203  						},
   204  						Host: "some-host",
   205  						Path: "some-path",
   206  					}, v2action.Warnings{"create-route-warning-1", "create-route-warning-2"}, nil)
   207  				})
   208  
   209  				It("creates a route with existence check", func() {
   210  					Expect(executeErr).ToNot(HaveOccurred())
   211  					Expect(testUI.Out).To(Say("Creating route some-host.some-domain/some-path for org some-org / space some-space as some-user\\.\\.\\."))
   212  					Expect(testUI.Err).To(Say("create-route-warning-1"))
   213  					Expect(testUI.Err).To(Say("create-route-warning-2"))
   214  					Expect(testUI.Out).To(Say("Route some-host.some-domain/some-path has been created\\."))
   215  					Expect(testUI.Out).To(Say("OK"))
   216  
   217  					Expect(fakeActor.CreateRouteWithExistenceCheckCallCount()).To(Equal(1))
   218  					orgGUID, spaceName, route, generatePort := fakeActor.CreateRouteWithExistenceCheckArgsForCall(0)
   219  					Expect(orgGUID).To(Equal("some-org-guid"))
   220  					Expect(spaceName).To(Equal("some-space"))
   221  					Expect(route.Host).To(Equal("some-host"))
   222  					Expect(route.Path).To(Equal("some-path"))
   223  					Expect(route.Port).To(Equal(types.NullInt{IsSet: false}))
   224  					Expect(generatePort).To(BeFalse())
   225  				})
   226  			})
   227  
   228  			Context("when port flag is provided", func() {
   229  				BeforeEach(func() {
   230  					cmd.Port = flag.Port{NullInt: types.NullInt{Value: 42, IsSet: true}}
   231  
   232  					fakeActor.CreateRouteWithExistenceCheckReturns(v2action.Route{
   233  						Domain: v2action.Domain{
   234  							Name: "some-domain",
   235  						},
   236  						Port: types.NullInt{IsSet: true, Value: 42},
   237  					}, v2action.Warnings{"create-route-warning-1", "create-route-warning-2"}, nil)
   238  				})
   239  
   240  				It("creates a route with existence check", func() {
   241  					Expect(executeErr).ToNot(HaveOccurred())
   242  					Expect(testUI.Out).To(Say("Creating route some-domain:42 for org some-org / space some-space as some-user\\.\\.\\."))
   243  					Expect(testUI.Err).To(Say("create-route-warning-1"))
   244  					Expect(testUI.Err).To(Say("create-route-warning-2"))
   245  					Expect(testUI.Out).To(Say("Route some-domain:42 has been created\\."))
   246  					Expect(testUI.Out).To(Say("OK"))
   247  
   248  					Expect(fakeActor.CreateRouteWithExistenceCheckCallCount()).To(Equal(1))
   249  					orgGUID, spaceName, route, generatePort := fakeActor.CreateRouteWithExistenceCheckArgsForCall(0)
   250  					Expect(orgGUID).To(Equal("some-org-guid"))
   251  					Expect(spaceName).To(Equal("some-space"))
   252  					Expect(route.Host).To(BeEmpty())
   253  					Expect(route.Path).To(BeEmpty())
   254  					Expect(route.Port).To(Equal(types.NullInt{IsSet: true, Value: 42}))
   255  					Expect(generatePort).To(BeFalse())
   256  				})
   257  			})
   258  
   259  			Context("when random-port flag is provided", func() {
   260  				BeforeEach(func() {
   261  					cmd.RandomPort = true
   262  					fakeActor.CreateRouteWithExistenceCheckReturns(v2action.Route{
   263  						Domain: v2action.Domain{
   264  							Name: "some-domain",
   265  						},
   266  						Port: types.NullInt{IsSet: true, Value: 1115},
   267  					}, v2action.Warnings{"create-route-warning-1", "create-route-warning-2"}, nil)
   268  				})
   269  
   270  				It("creates a route with existence check", func() {
   271  					Expect(executeErr).ToNot(HaveOccurred())
   272  					Expect(testUI.Out).To(Say("Creating route some-domain for org some-org / space some-space as some-user\\.\\.\\."))
   273  					Expect(testUI.Err).To(Say("create-route-warning-1"))
   274  					Expect(testUI.Err).To(Say("create-route-warning-2"))
   275  					Expect(testUI.Out).To(Say("Route some-domain:1115 has been created\\."))
   276  					Expect(testUI.Out).To(Say("OK"))
   277  
   278  					Expect(fakeActor.CreateRouteWithExistenceCheckCallCount()).To(Equal(1))
   279  					orgGUID, spaceName, route, generatePort := fakeActor.CreateRouteWithExistenceCheckArgsForCall(0)
   280  					Expect(orgGUID).To(Equal("some-org-guid"))
   281  					Expect(spaceName).To(Equal("some-space"))
   282  					Expect(route.Host).To(BeEmpty())
   283  					Expect(route.Path).To(BeEmpty())
   284  					Expect(route.Port).To(Equal(types.NullInt{IsSet: false}))
   285  					Expect(generatePort).To(BeTrue())
   286  				})
   287  			})
   288  
   289  			Context("when creating route returns a DomainNotFoundError error", func() {
   290  				BeforeEach(func() {
   291  					fakeActor.CreateRouteWithExistenceCheckReturns(
   292  						v2action.Route{},
   293  						v2action.Warnings{"create-route-warning-1", "create-route-warning-2"},
   294  						actionerror.DomainNotFoundError{Name: "some-domain"},
   295  					)
   296  				})
   297  
   298  				It("prints warnings and returns an error", func() {
   299  					Expect(executeErr).To(HaveOccurred())
   300  					Expect(executeErr).To(MatchError(actionerror.DomainNotFoundError{Name: "some-domain"}))
   301  
   302  					Expect(testUI.Out).To(Say("Creating route some-domain for org some-org / space some-space as some-user\\.\\.\\."))
   303  					Expect(testUI.Err).To(Say("create-route-warning-1"))
   304  					Expect(testUI.Err).To(Say("create-route-warning-2"))
   305  					Expect(testUI.Out).NotTo(Say("OK"))
   306  
   307  					Expect(fakeActor.CreateRouteWithExistenceCheckCallCount()).To(Equal(1))
   308  				})
   309  			})
   310  
   311  			Context("when creating route returns a RouteAlreadyExistsError error", func() {
   312  				BeforeEach(func() {
   313  					cmd.Hostname = "some-host"
   314  
   315  					fakeActor.CreateRouteWithExistenceCheckReturns(
   316  						v2action.Route{},
   317  						v2action.Warnings{"create-route-warning-1", "create-route-warning-2"},
   318  						actionerror.RouteAlreadyExistsError{
   319  							Route: v2action.Route{Host: "some-host"}.String(),
   320  						},
   321  					)
   322  				})
   323  
   324  				It("prints warnings and returns an error", func() {
   325  					Expect(executeErr).NotTo(HaveOccurred())
   326  
   327  					Expect(testUI.Out).To(Say("Creating route some-host\\.some-domain for org some-org / space some-space as some-user\\.\\.\\."))
   328  					Expect(testUI.Err).To(Say("create-route-warning-1"))
   329  					Expect(testUI.Err).To(Say("create-route-warning-2"))
   330  					Expect(testUI.Err).To(Say("Route some-host\\.some-domain already exists\\."))
   331  					Expect(testUI.Out).To(Say("OK"))
   332  
   333  					Expect(fakeActor.CreateRouteWithExistenceCheckCallCount()).To(Equal(1))
   334  				})
   335  			})
   336  
   337  			Context("when creating route returns a generic error", func() {
   338  				var createRouteErr error
   339  				BeforeEach(func() {
   340  					createRouteErr = errors.New("Oh nooes")
   341  					fakeActor.CreateRouteWithExistenceCheckReturns(v2action.Route{}, v2action.Warnings{"create-route-warning-1", "create-route-warning-2"}, createRouteErr)
   342  				})
   343  
   344  				It("prints warnings and returns an error", func() {
   345  					Expect(executeErr).To(HaveOccurred())
   346  					Expect(executeErr).To(MatchError(createRouteErr))
   347  
   348  					Expect(testUI.Out).To(Say("Creating route some-domain for org some-org / space some-space as some-user\\.\\.\\."))
   349  					Expect(testUI.Err).To(Say("create-route-warning-1"))
   350  					Expect(testUI.Err).To(Say("create-route-warning-2"))
   351  					Expect(testUI.Out).NotTo(Say("OK"))
   352  
   353  					Expect(fakeActor.CreateRouteWithExistenceCheckCallCount()).To(Equal(1))
   354  				})
   355  			})
   356  		})
   357  	})
   358  })