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