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