github.com/elopio/cli@v6.21.2-0.20160902224010-ea909d1fdb2f+incompatible/commands/v2/help_command_test.go (about) 1 package v2_test 2 3 import ( 4 "code.cloudfoundry.org/cli/actors/v2actions" 5 "code.cloudfoundry.org/cli/commands/commandsfakes" 6 "code.cloudfoundry.org/cli/commands/flags" 7 "code.cloudfoundry.org/cli/commands/ui" 8 . "code.cloudfoundry.org/cli/commands/v2" 9 "code.cloudfoundry.org/cli/commands/v2/v2fakes" 10 "code.cloudfoundry.org/cli/utils/config" 11 12 . "github.com/onsi/ginkgo" 13 . "github.com/onsi/gomega" 14 . "github.com/onsi/gomega/gbytes" 15 ) 16 17 var _ = Describe("Help Command", func() { 18 var ( 19 fakeUI ui.UI 20 fakeActor *v2fakes.FakeHelpActor 21 cmd HelpCommand 22 fakeConfig *commandsfakes.FakeConfig 23 ) 24 25 BeforeEach(func() { 26 fakeUI = ui.NewTestUI(NewBuffer()) 27 fakeActor = new(v2fakes.FakeHelpActor) 28 fakeConfig = new(commandsfakes.FakeConfig) 29 fakeConfig.BinaryNameReturns("faceman") 30 31 cmd = HelpCommand{ 32 UI: fakeUI, 33 Actor: fakeActor, 34 Config: fakeConfig, 35 } 36 }) 37 38 Context("providing help for a specific command", func() { 39 Describe("built-in command", func() { 40 BeforeEach(func() { 41 cmd.OptionalArgs = flags.CommandName{ 42 CommandName: "help", 43 } 44 45 commandInfo := v2actions.CommandInfo{ 46 Name: "help", 47 Description: "Show help", 48 Usage: "CF_NAME help [COMMAND]", 49 Alias: "h", 50 } 51 fakeActor.CommandInfoByNameReturns(commandInfo, nil) 52 }) 53 54 It("displays the name for help", func() { 55 err := cmd.Execute(nil) 56 Expect(err).ToNot(HaveOccurred()) 57 58 Expect(fakeUI.Out).To(Say("NAME:")) 59 Expect(fakeUI.Out).To(Say(" help - Show help")) 60 61 Expect(fakeActor.CommandInfoByNameCallCount()).To(Equal(1)) 62 _, commandName := fakeActor.CommandInfoByNameArgsForCall(0) 63 Expect(commandName).To(Equal("help")) 64 }) 65 66 It("displays the usage for help", func() { 67 err := cmd.Execute(nil) 68 Expect(err).ToNot(HaveOccurred()) 69 70 Expect(fakeUI.Out).To(Say("NAME:")) 71 Expect(fakeUI.Out).To(Say("USAGE:")) 72 Expect(fakeUI.Out).To(Say(" faceman help \\[COMMAND\\]")) 73 }) 74 75 Describe("related commands", func() { 76 Context("when the command has related commands", func() { 77 BeforeEach(func() { 78 commandInfo := v2actions.CommandInfo{ 79 Name: "app", 80 RelatedCommands: []string{"broccoli", "tomato"}, 81 } 82 fakeActor.CommandInfoByNameReturns(commandInfo, nil) 83 }) 84 85 It("displays the related commands for help", func() { 86 err := cmd.Execute(nil) 87 Expect(err).ToNot(HaveOccurred()) 88 89 Expect(fakeUI.Out).To(Say("NAME:")) 90 Expect(fakeUI.Out).To(Say("SEE ALSO:")) 91 Expect(fakeUI.Out).To(Say(" broccoli, tomato")) 92 }) 93 }) 94 95 Context("when the command does not have related commands", func() { 96 It("displays the related commands for help", func() { 97 err := cmd.Execute(nil) 98 Expect(err).ToNot(HaveOccurred()) 99 100 Expect(fakeUI.Out).To(Say("NAME:")) 101 Expect(fakeUI.Out).NotTo(Say("SEE ALSO:")) 102 }) 103 }) 104 }) 105 106 Describe("aliases", func() { 107 Context("when the command has an alias", func() { 108 It("displays the alias for help", func() { 109 err := cmd.Execute(nil) 110 Expect(err).ToNot(HaveOccurred()) 111 112 Expect(fakeUI.Out).To(Say("USAGE:")) 113 Expect(fakeUI.Out).To(Say("ALIAS:")) 114 Expect(fakeUI.Out).To(Say(" h")) 115 }) 116 }) 117 118 Context("when the command does not have an alias", func() { 119 BeforeEach(func() { 120 cmd.OptionalArgs = flags.CommandName{ 121 CommandName: "app", 122 } 123 124 commandInfo := v2actions.CommandInfo{ 125 Name: "app", 126 } 127 fakeActor.CommandInfoByNameReturns(commandInfo, nil) 128 }) 129 130 It("no alias is displayed", func() { 131 err := cmd.Execute(nil) 132 Expect(err).ToNot(HaveOccurred()) 133 134 Expect(fakeUI.Out).ToNot(Say("ALIAS:")) 135 }) 136 }) 137 }) 138 139 Describe("options", func() { 140 Context("when the command has options", func() { 141 BeforeEach(func() { 142 cmd.OptionalArgs = flags.CommandName{ 143 CommandName: "push", 144 } 145 commandInfo := v2actions.CommandInfo{ 146 Name: "push", 147 Flags: []v2actions.CommandFlag{ 148 { 149 Long: "no-hostname", 150 Description: "Map the root domain to this app", 151 }, 152 { 153 Short: "b", 154 Description: "Custom buildpack by name (e.g. my-buildpack) or Git URL (e.g. 'https://github.com/cloudfoundry/java-buildpack.git') or Git URL with a branch or tag (e.g. 'https://github.com/cloudfoundry/java-buildpack.git#v3.3.0' for 'v3.3.0' tag). To use built-in buildpacks only, specify 'default' or 'null'", 155 }, 156 { 157 Long: "hostname", 158 Short: "n", 159 Description: "Hostname (e.g. my-subdomain)", 160 }, 161 }, 162 } 163 fakeActor.CommandInfoByNameReturns(commandInfo, nil) 164 }) 165 166 Context("only has a long option", func() { 167 It("displays the options for app", func() { 168 err := cmd.Execute(nil) 169 Expect(err).ToNot(HaveOccurred()) 170 171 Expect(fakeUI.Out).To(Say("USAGE:")) 172 Expect(fakeUI.Out).To(Say("OPTIONS:")) 173 Expect(fakeUI.Out).To(Say("--no-hostname\\s+Map the root domain to this app")) 174 }) 175 }) 176 177 Context("only has a short option", func() { 178 It("displays the options for app", func() { 179 err := cmd.Execute(nil) 180 Expect(err).ToNot(HaveOccurred()) 181 182 Expect(fakeUI.Out).To(Say("USAGE:")) 183 Expect(fakeUI.Out).To(Say("OPTIONS:")) 184 Expect(fakeUI.Out).To(Say("-b\\s+Custom buildpack by name \\(e.g. my-buildpack\\) or Git URL \\(e.g. 'https://github.com/cloudfoundry/java-buildpack.git'\\) or Git URL with a branch or tag \\(e.g. 'https://github.com/cloudfoundry/java-buildpack.git#v3.3.0' for 'v3.3.0' tag\\). To use built-in buildpacks only, specify 'default' or 'null'")) 185 }) 186 }) 187 188 Context("has long and short options", func() { 189 It("displays the options for app", func() { 190 err := cmd.Execute(nil) 191 Expect(err).ToNot(HaveOccurred()) 192 193 Expect(fakeUI.Out).To(Say("USAGE:")) 194 Expect(fakeUI.Out).To(Say("OPTIONS:")) 195 Expect(fakeUI.Out).To(Say("--hostname, -n\\s+Hostname \\(e.g. my-subdomain\\)")) 196 }) 197 }) 198 199 Context("has hidden options", func() { 200 It("does not display the hidden option", func() { 201 err := cmd.Execute(nil) 202 Expect(err).ToNot(HaveOccurred()) 203 204 Expect(fakeUI.Out).ToNot(Say("--app-ports")) 205 }) 206 }) 207 }) 208 }) 209 }) 210 211 Describe("plug-in command", func() { 212 BeforeEach(func() { 213 cmd.OptionalArgs = flags.CommandName{ 214 CommandName: "enable-diego", 215 } 216 217 fakeConfig.PluginConfigReturns(map[string]config.PluginConfig{ 218 "Diego-Enabler": config.PluginConfig{ 219 Commands: []config.PluginCommand{ 220 { 221 Name: "enable-diego", 222 Alias: "ed", 223 HelpText: "enable Diego support for an app", 224 UsageDetails: config.PluginUsageDetails{ 225 Usage: "faceman diego-enabler this and that and a little stuff", 226 Options: map[string]string{ 227 "--first": "foobar", 228 "--second-third": "baz", 229 }, 230 }, 231 }, 232 }, 233 }, 234 }) 235 236 fakeActor.CommandInfoByNameReturns(v2actions.CommandInfo{}, 237 v2actions.ErrorInvalidCommand{CommandName: "enable-diego"}) 238 }) 239 240 It("displays the plugin's help", func() { 241 err := cmd.Execute(nil) 242 Expect(err).ToNot(HaveOccurred()) 243 244 Expect(fakeUI.Out).To(Say("enable-diego - enable Diego support for an app")) 245 Expect(fakeUI.Out).To(Say("faceman diego-enabler this and that and a little stuff")) 246 Expect(fakeUI.Out).To(Say("ALIAS:")) 247 Expect(fakeUI.Out).To(Say("ed")) 248 Expect(fakeUI.Out).To(Say("--first\\s+foobar")) 249 Expect(fakeUI.Out).To(Say("--second-third\\s+baz")) 250 }) 251 }) 252 }) 253 254 Describe("help for common commands", func() { 255 BeforeEach(func() { 256 cmd.OptionalArgs = flags.CommandName{ 257 CommandName: "", 258 } 259 cmd.AllCommands = false 260 cmd.Actor = v2actions.NewActor() 261 }) 262 263 It("returns a list of only the common commands", func() { 264 err := cmd.Execute(nil) 265 Expect(err).ToNot(HaveOccurred()) 266 267 Expect(fakeUI.Out).To(Say("Before getting started:")) 268 Expect(fakeUI.Out).To(Say("help,h\\s+logout,lo")) 269 270 Expect(fakeUI.Out).To(Say("Application lifecycle:")) 271 Expect(fakeUI.Out).To(Say("apps,a\\s+logs\\s+set-env,se")) 272 273 Expect(fakeUI.Out).To(Say("Services integration:")) 274 Expect(fakeUI.Out).To(Say("marketplace,m\\s+create-user-provided-service,cups")) 275 Expect(fakeUI.Out).To(Say("services,s\\s+update-user-provided-service,uups")) 276 277 Expect(fakeUI.Out).To(Say("Route and domain management:")) 278 Expect(fakeUI.Out).To(Say("routes,r\\s+delete-route\\s+create-domain")) 279 Expect(fakeUI.Out).To(Say("domains\\s+map-route")) 280 281 Expect(fakeUI.Out).To(Say("Space management:")) 282 Expect(fakeUI.Out).To(Say("spaces\\s+create-space\\s+set-space-role")) 283 284 Expect(fakeUI.Out).To(Say("Org management:")) 285 Expect(fakeUI.Out).To(Say("orgs,o\\s+set-org-role")) 286 287 Expect(fakeUI.Out).To(Say("CLI plugin management:")) 288 Expect(fakeUI.Out).To(Say("plugins\\s+add-plugin-repo\\s+repo-plugins")) 289 290 Expect(fakeUI.Out).To(Say("Global options:")) 291 Expect(fakeUI.Out).To(Say("--help, -h\\s+Show help")) 292 293 Expect(fakeUI.Out).To(Say("'cf help -a' lists all commands with short descriptions. See 'cf help <command>'")) 294 }) 295 296 Context("when there are multiple installed plugins", func() { 297 BeforeEach(func() { 298 fakeConfig.PluginConfigReturns(map[string]config.PluginConfig{ 299 "some-plugin": config.PluginConfig{ 300 Commands: []config.PluginCommand{ 301 { 302 Name: "enable", 303 HelpText: "enable command", 304 }, 305 { 306 Name: "disable", 307 HelpText: "disable command", 308 }, 309 { 310 Name: "some-other-command", 311 HelpText: "does something", 312 }, 313 }, 314 }, 315 "Some-other-plugin": config.PluginConfig{ 316 Commands: []config.PluginCommand{ 317 { 318 Name: "some-other-plugin-command", 319 HelpText: "does some other thing", 320 }, 321 }, 322 }, 323 "the-last-plugin": config.PluginConfig{ 324 Commands: []config.PluginCommand{ 325 { 326 Name: "last-plugin-command", 327 HelpText: "does the last thing", 328 }, 329 }, 330 }, 331 }) 332 }) 333 334 It("returns the plugin commands organized by plugin and sorted in alphabetical order", func() { 335 err := cmd.Execute(nil) 336 Expect(err).ToNot(HaveOccurred()) 337 338 Expect(fakeUI.Out).To(Say("Commands offered by installed plugins:")) 339 Expect(fakeUI.Out).To(Say("some-other-plugin-command\\s+enable\\s+last-plugin-command")) 340 Expect(fakeUI.Out).To(Say("disable\\s+some-other-command")) 341 342 }) 343 }) 344 }) 345 346 Describe("providing help for all commands", func() { 347 Context("when a command is not provided", func() { 348 BeforeEach(func() { 349 cmd.OptionalArgs = flags.CommandName{ 350 CommandName: "", 351 } 352 cmd.AllCommands = true 353 354 cmd.Actor = v2actions.NewActor() 355 fakeConfig.PluginConfigReturns(map[string]config.PluginConfig{ 356 "Diego-Enabler": config.PluginConfig{ 357 Commands: []config.PluginCommand{ 358 { 359 Name: "enable-diego", 360 HelpText: "enable Diego support for an app", 361 }, 362 }, 363 }, 364 }) 365 }) 366 367 It("returns a list of all commands", func() { 368 err := cmd.Execute(nil) 369 Expect(err).ToNot(HaveOccurred()) 370 371 Expect(fakeUI.Out).To(Say("NAME:")) 372 Expect(fakeUI.Out).To(Say("faceman - A command line tool to interact with Cloud Foundry")) 373 Expect(fakeUI.Out).To(Say("USAGE:")) 374 Expect(fakeUI.Out).To(Say("faceman \\[global options\\] command \\[arguments...\\] \\[command options\\]")) 375 Expect(fakeUI.Out).To(Say("VERSION:")) 376 Expect(fakeUI.Out).To(Say("BUILT_FROM_SOURCE-BUILT_AT_UNKNOWN_TIME")) 377 378 Expect(fakeUI.Out).To(Say("GETTING STARTED:")) 379 Expect(fakeUI.Out).To(Say("help\\s+Show help")) 380 Expect(fakeUI.Out).To(Say("api\\s+Set or view target api url")) 381 382 Expect(fakeUI.Out).To(Say("APPS:")) 383 Expect(fakeUI.Out).To(Say("apps\\s+List all apps in the target space")) 384 Expect(fakeUI.Out).To(Say("ssh-enabled\\s+Reports whether SSH is enabled on an application container instance")) 385 386 Expect(fakeUI.Out).To(Say("SERVICES:")) 387 Expect(fakeUI.Out).To(Say("marketplace\\s+List available offerings in the marketplace")) 388 Expect(fakeUI.Out).To(Say("create-service\\s+Create a service instance")) 389 390 Expect(fakeUI.Out).To(Say("ORGS:")) 391 Expect(fakeUI.Out).To(Say("orgs\\s+List all orgs")) 392 Expect(fakeUI.Out).To(Say("delete-org\\s+Delete an org")) 393 394 Expect(fakeUI.Out).To(Say("SPACES:")) 395 Expect(fakeUI.Out).To(Say("spaces\\s+List all spaces in an org")) 396 Expect(fakeUI.Out).To(Say("allow-space-ssh\\s+Allow SSH access for the space")) 397 398 Expect(fakeUI.Out).To(Say("DOMAINS:")) 399 Expect(fakeUI.Out).To(Say("domains\\s+List domains in the target org")) 400 Expect(fakeUI.Out).To(Say("router-groups\\s+List router groups")) 401 402 Expect(fakeUI.Out).To(Say("ROUTES:")) 403 Expect(fakeUI.Out).To(Say("routes\\s+List all routes in the current space or the current organization")) 404 Expect(fakeUI.Out).To(Say("unmap-route\\s+Remove a url route from an app")) 405 406 Expect(fakeUI.Out).To(Say("BUILDPACKS:")) 407 Expect(fakeUI.Out).To(Say("buildpacks\\s+List all buildpacks")) 408 Expect(fakeUI.Out).To(Say("delete-buildpack\\s+Delete a buildpack")) 409 410 Expect(fakeUI.Out).To(Say("USER ADMIN:")) 411 Expect(fakeUI.Out).To(Say("create-user\\s+Create a new user")) 412 Expect(fakeUI.Out).To(Say("space-users\\s+Show space users by role")) 413 414 Expect(fakeUI.Out).To(Say("ORG ADMIN:")) 415 Expect(fakeUI.Out).To(Say("quotas\\s+List available usage quotas")) 416 Expect(fakeUI.Out).To(Say("delete-quota\\s+Delete a quota")) 417 418 Expect(fakeUI.Out).To(Say("SPACE ADMIN:")) 419 Expect(fakeUI.Out).To(Say("space-quotas\\s+List available space resource quotas")) 420 Expect(fakeUI.Out).To(Say("set-space-quota\\s+Assign a space quota definition to a space")) 421 422 Expect(fakeUI.Out).To(Say("SERVICE ADMIN:")) 423 Expect(fakeUI.Out).To(Say("service-auth-tokens\\s+List service auth tokens")) 424 Expect(fakeUI.Out).To(Say("service-access\\s+List service access settings")) 425 426 Expect(fakeUI.Out).To(Say("SECURITY GROUP:")) 427 Expect(fakeUI.Out).To(Say("security-group\\s+Show a single security group")) 428 Expect(fakeUI.Out).To(Say("staging-security-groups\\s+List security groups in the staging set for applications")) 429 430 Expect(fakeUI.Out).To(Say("ENVIRONMENT VARIABLE GROUPS:")) 431 Expect(fakeUI.Out).To(Say("running-environment-variable-group\\s+Retrieve the contents of the running environment variable group")) 432 Expect(fakeUI.Out).To(Say("set-running-environment-variable-group\\s+Pass parameters as JSON to create a running environment variable group")) 433 434 Expect(fakeUI.Out).To(Say("FEATURE FLAGS:")) 435 Expect(fakeUI.Out).To(Say("feature-flags\\s+Retrieve list of feature flags with status of each flag-able feature")) 436 Expect(fakeUI.Out).To(Say("disable-feature-flag\\s+Disable the use of a feature so that users have access to and can use the feature")) 437 438 Expect(fakeUI.Out).To(Say("ADVANCED:")) 439 Expect(fakeUI.Out).To(Say("curl\\s+Executes a request to the targeted API endpoint")) 440 Expect(fakeUI.Out).To(Say("ssh-code\\s+Get a one time password for ssh clients")) 441 442 Expect(fakeUI.Out).To(Say("ADD/REMOVE PLUGIN REPOSITORY:")) 443 Expect(fakeUI.Out).To(Say("add-plugin-repo\\s+Add a new plugin repository")) 444 Expect(fakeUI.Out).To(Say("repo-plugins\\s+List all available plugins in specified repository or in all added repositories")) 445 446 Expect(fakeUI.Out).To(Say("ADD/REMOVE PLUGIN:")) 447 Expect(fakeUI.Out).To(Say("plugins\\s+List all available plugin commands")) 448 Expect(fakeUI.Out).To(Say("uninstall-plugin\\s+Uninstall the plugin defined in command argument")) 449 450 Expect(fakeUI.Out).To(Say("INSTALLED PLUGIN COMMANDS:")) 451 Expect(fakeUI.Out).To(Say("enable-diego\\s+enable Diego support for an app")) 452 453 Expect(fakeUI.Out).To(Say("ENVIRONMENT VARIABLES:")) 454 Expect(fakeUI.Out).To(Say("CF_COLOR=false\\s+Do not colorize output")) 455 456 Expect(fakeUI.Out).To(Say("GLOBAL OPTIONS:")) 457 Expect(fakeUI.Out).To(Say("--help, -h\\s+Show help")) 458 }) 459 460 Context("when there are multiple installed plugins", func() { 461 BeforeEach(func() { 462 fakeConfig.PluginConfigReturns(map[string]config.PluginConfig{ 463 "some-plugin": config.PluginConfig{ 464 Commands: []config.PluginCommand{ 465 { 466 Name: "enable", 467 HelpText: "enable command", 468 }, 469 { 470 Name: "disable", 471 HelpText: "disable command", 472 }, 473 { 474 Name: "some-other-command", 475 HelpText: "does something", 476 }, 477 }, 478 }, 479 "Some-other-plugin": config.PluginConfig{ 480 Commands: []config.PluginCommand{ 481 { 482 Name: "some-other-plugin-command", 483 HelpText: "does some other thing", 484 }, 485 }, 486 }, 487 "the-last-plugin": config.PluginConfig{ 488 Commands: []config.PluginCommand{ 489 { 490 Name: "last-plugin-command", 491 HelpText: "does the last thing", 492 }, 493 }, 494 }, 495 }) 496 }) 497 498 It("returns the plugin commands organized by plugin and sorted in alphabetical order", func() { 499 err := cmd.Execute(nil) 500 Expect(err).ToNot(HaveOccurred()) 501 502 Expect(fakeUI.Out).To(Say(`INSTALLED PLUGIN COMMANDS:.* 503 \s+some-other-plugin-command\s+does some other thing.* 504 \s+disable\s+disable command.* 505 \s+enable\s+enable command.* 506 \s+some-other-command\s+does something.* 507 \s+last-plugin-command\s+does the last thing`)) 508 }) 509 }) 510 }) 511 }) 512 })