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