github.com/rakutentech/cli@v6.12.5-0.20151006231303-24468b65536e+incompatible/cf/terminal/ui_test.go (about)

     1  package terminal_test
     2  
     3  import (
     4  	"io"
     5  	"os"
     6  	"strings"
     7  
     8  	"github.com/cloudfoundry/cli/cf"
     9  	"github.com/cloudfoundry/cli/cf/configuration/core_config"
    10  	"github.com/cloudfoundry/cli/cf/i18n"
    11  	"github.com/cloudfoundry/cli/cf/i18n/detection"
    12  	"github.com/cloudfoundry/cli/cf/models"
    13  	testassert "github.com/cloudfoundry/cli/testhelpers/assert"
    14  	"github.com/cloudfoundry/cli/testhelpers/configuration"
    15  	testconfig "github.com/cloudfoundry/cli/testhelpers/configuration"
    16  	io_helpers "github.com/cloudfoundry/cli/testhelpers/io"
    17  
    18  	. "github.com/cloudfoundry/cli/cf/terminal"
    19  	. "github.com/cloudfoundry/cli/testhelpers/matchers"
    20  	. "github.com/onsi/ginkgo"
    21  	. "github.com/onsi/gomega"
    22  )
    23  
    24  var _ = Describe("UI", func() {
    25  
    26  	Describe("Printing message to stdout with PrintCapturingNoOutput", func() {
    27  		It("prints strings without using the TeePrinter", func() {
    28  			bucket := &[]string{}
    29  
    30  			printer := NewTeePrinter()
    31  			printer.SetOutputBucket(bucket)
    32  
    33  			io_helpers.SimulateStdin("", func(reader io.Reader) {
    34  				output := io_helpers.CaptureOutput(func() {
    35  					ui := NewUI(reader, printer)
    36  					ui.PrintCapturingNoOutput("Hello")
    37  				})
    38  
    39  				Expect("Hello").To(Equal(strings.Join(output, "")))
    40  				Expect(len(*bucket)).To(Equal(0))
    41  			})
    42  		})
    43  	})
    44  
    45  	Describe("Printing message to stdout with Say", func() {
    46  		It("prints strings", func() {
    47  			io_helpers.SimulateStdin("", func(reader io.Reader) {
    48  				output := io_helpers.CaptureOutput(func() {
    49  					ui := NewUI(reader, NewTeePrinter())
    50  					ui.Say("Hello")
    51  				})
    52  
    53  				Expect("Hello").To(Equal(strings.Join(output, "")))
    54  			})
    55  		})
    56  
    57  		It("prints formatted strings", func() {
    58  			io_helpers.SimulateStdin("", func(reader io.Reader) {
    59  				output := io_helpers.CaptureOutput(func() {
    60  					ui := NewUI(reader, NewTeePrinter())
    61  					ui.Say("Hello %s", "World!")
    62  				})
    63  
    64  				Expect("Hello World!").To(Equal(strings.Join(output, "")))
    65  			})
    66  		})
    67  
    68  		It("does not format strings when provided no args", func() {
    69  			output := io_helpers.CaptureOutput(func() {
    70  				ui := NewUI(os.Stdin, NewTeePrinter())
    71  				ui.Say("Hello %s World!") // whoops
    72  			})
    73  
    74  			Expect(strings.Join(output, "")).To(Equal("Hello %s World!"))
    75  		})
    76  	})
    77  
    78  	Describe("Asking user for input", func() {
    79  		It("allows string with whitespaces", func() {
    80  			io_helpers.CaptureOutput(func() {
    81  				io_helpers.SimulateStdin("foo bar\n", func(reader io.Reader) {
    82  					ui := NewUI(reader, NewTeePrinter())
    83  					Expect(ui.Ask("?")).To(Equal("foo bar"))
    84  				})
    85  			})
    86  		})
    87  
    88  		It("returns empty string if an error occured while reading string", func() {
    89  			io_helpers.CaptureOutput(func() {
    90  				io_helpers.SimulateStdin("string without expected delimiter", func(reader io.Reader) {
    91  					ui := NewUI(reader, NewTeePrinter())
    92  					Expect(ui.Ask("?")).To(Equal(""))
    93  				})
    94  			})
    95  		})
    96  
    97  		It("always outputs the prompt, even when output is disabled", func() {
    98  			output := io_helpers.CaptureOutput(func() {
    99  				io_helpers.SimulateStdin("things are great\n", func(reader io.Reader) {
   100  					printer := NewTeePrinter()
   101  					printer.DisableTerminalOutput(true)
   102  					ui := NewUI(reader, printer)
   103  					ui.Ask("You like things?")
   104  				})
   105  			})
   106  			Expect(strings.Join(output, "")).To(ContainSubstring("You like things?"))
   107  		})
   108  	})
   109  
   110  	Describe("Confirming user input", func() {
   111  		It("treats 'y' as an affirmative confirmation", func() {
   112  			io_helpers.SimulateStdin("y\n", func(reader io.Reader) {
   113  				out := io_helpers.CaptureOutput(func() {
   114  					ui := NewUI(reader, NewTeePrinter())
   115  					Expect(ui.Confirm("Hello %s", "World?")).To(BeTrue())
   116  				})
   117  
   118  				Expect(out).To(ContainSubstrings([]string{"Hello World?"}))
   119  			})
   120  		})
   121  
   122  		It("treats 'yes' as an affirmative confirmation when default language is not en_US", func() {
   123  			oldLang := os.Getenv("LC_ALL")
   124  			defer os.Setenv("LC_ALL", oldLang)
   125  
   126  			oldT := i18n.T
   127  			defer func() {
   128  				i18n.T = oldT
   129  			}()
   130  
   131  			os.Setenv("LC_ALL", "fr_FR")
   132  
   133  			config := configuration.NewRepositoryWithDefaults()
   134  			i18n.T = i18n.Init(config, &detection.JibberJabberDetector{})
   135  
   136  			io_helpers.SimulateStdin("yes\n", func(reader io.Reader) {
   137  				out := io_helpers.CaptureOutput(func() {
   138  					ui := NewUI(reader, NewTeePrinter())
   139  					Expect(ui.Confirm("Hello %s", "World?")).To(BeTrue())
   140  				})
   141  				Expect(out).To(ContainSubstrings([]string{"Hello World?"}))
   142  			})
   143  		})
   144  
   145  		It("treats 'yes' as an affirmative confirmation", func() {
   146  			io_helpers.SimulateStdin("yes\n", func(reader io.Reader) {
   147  				out := io_helpers.CaptureOutput(func() {
   148  					ui := NewUI(reader, NewTeePrinter())
   149  					Expect(ui.Confirm("Hello %s", "World?")).To(BeTrue())
   150  				})
   151  
   152  				Expect(out).To(ContainSubstrings([]string{"Hello World?"}))
   153  			})
   154  		})
   155  
   156  		It("treats other input as a negative confirmation", func() {
   157  			io_helpers.SimulateStdin("wat\n", func(reader io.Reader) {
   158  				out := io_helpers.CaptureOutput(func() {
   159  					ui := NewUI(reader, NewTeePrinter())
   160  					Expect(ui.Confirm("Hello %s", "World?")).To(BeFalse())
   161  				})
   162  
   163  				Expect(out).To(ContainSubstrings([]string{"Hello World?"}))
   164  			})
   165  		})
   166  	})
   167  
   168  	Describe("Confirming deletion", func() {
   169  		It("formats a nice output string with exactly one prompt", func() {
   170  			io_helpers.SimulateStdin("y\n", func(reader io.Reader) {
   171  				out := io_helpers.CaptureOutput(func() {
   172  					ui := NewUI(reader, NewTeePrinter())
   173  					Expect(ui.ConfirmDelete("fizzbuzz", "bizzbump")).To(BeTrue())
   174  				})
   175  
   176  				Expect(out).To(ContainSubstrings([]string{
   177  					"Really delete the fizzbuzz",
   178  					"bizzbump",
   179  					"?> ",
   180  				}))
   181  			})
   182  		})
   183  
   184  		It("treats 'yes' as an affirmative confirmation", func() {
   185  			io_helpers.SimulateStdin("yes\n", func(reader io.Reader) {
   186  				out := io_helpers.CaptureOutput(func() {
   187  					ui := NewUI(reader, NewTeePrinter())
   188  					Expect(ui.ConfirmDelete("modelType", "modelName")).To(BeTrue())
   189  				})
   190  
   191  				Expect(out).To(ContainSubstrings([]string{"modelType modelName"}))
   192  			})
   193  		})
   194  
   195  		It("treats other input as a negative confirmation and warns the user", func() {
   196  			io_helpers.SimulateStdin("wat\n", func(reader io.Reader) {
   197  				out := io_helpers.CaptureOutput(func() {
   198  					ui := NewUI(reader, NewTeePrinter())
   199  					Expect(ui.ConfirmDelete("modelType", "modelName")).To(BeFalse())
   200  				})
   201  
   202  				Expect(out).To(ContainSubstrings([]string{"Delete cancelled"}))
   203  			})
   204  		})
   205  	})
   206  
   207  	Describe("Confirming deletion with associations", func() {
   208  		It("warns the user that associated objects will also be deleted", func() {
   209  			io_helpers.SimulateStdin("wat\n", func(reader io.Reader) {
   210  				out := io_helpers.CaptureOutput(func() {
   211  					ui := NewUI(reader, NewTeePrinter())
   212  					Expect(ui.ConfirmDeleteWithAssociations("modelType", "modelName")).To(BeFalse())
   213  				})
   214  
   215  				Expect(out).To(ContainSubstrings([]string{"Delete cancelled"}))
   216  			})
   217  		})
   218  	})
   219  
   220  	Context("when user is not logged in", func() {
   221  		var config core_config.Reader
   222  
   223  		BeforeEach(func() {
   224  			config = testconfig.NewRepository()
   225  		})
   226  
   227  		It("prompts the user to login", func() {
   228  			output := io_helpers.CaptureOutput(func() {
   229  				ui := NewUI(os.Stdin, NewTeePrinter())
   230  				ui.ShowConfiguration(config)
   231  			})
   232  
   233  			Expect(output).ToNot(ContainSubstrings([]string{"API endpoint:"}))
   234  			Expect(output).To(ContainSubstrings([]string{"Not logged in", "Use", "log in"}))
   235  		})
   236  	})
   237  
   238  	Context("when an api endpoint is set and the user logged in", func() {
   239  		var config core_config.ReadWriter
   240  
   241  		BeforeEach(func() {
   242  			accessToken := core_config.TokenInfo{
   243  				UserGuid: "my-user-guid",
   244  				Username: "my-user",
   245  				Email:    "my-user-email",
   246  			}
   247  			config = testconfig.NewRepositoryWithAccessToken(accessToken)
   248  			config.SetApiEndpoint("https://test.example.org")
   249  			config.SetApiVersion("☃☃☃")
   250  		})
   251  
   252  		Describe("tells the user what is set in the config", func() {
   253  			var output []string
   254  
   255  			JustBeforeEach(func() {
   256  				output = io_helpers.CaptureOutput(func() {
   257  					ui := NewUI(os.Stdin, NewTeePrinter())
   258  					ui.ShowConfiguration(config)
   259  				})
   260  			})
   261  
   262  			It("tells the user which api endpoint is set", func() {
   263  				Expect(output).To(ContainSubstrings([]string{"API endpoint:", "https://test.example.org"}))
   264  			})
   265  
   266  			It("tells the user the api version", func() {
   267  				Expect(output).To(ContainSubstrings([]string{"API version:", "☃☃☃"}))
   268  			})
   269  
   270  			It("tells the user which user is logged in", func() {
   271  				Expect(output).To(ContainSubstrings([]string{"User:", "my-user-email"}))
   272  			})
   273  
   274  			Context("when an org is targeted", func() {
   275  				BeforeEach(func() {
   276  					config.SetOrganizationFields(models.OrganizationFields{
   277  						Name: "org-name",
   278  						Guid: "org-guid",
   279  					})
   280  				})
   281  
   282  				It("tells the user which org is targeted", func() {
   283  					Expect(output).To(ContainSubstrings([]string{"Org:", "org-name"}))
   284  				})
   285  			})
   286  
   287  			Context("when a space is targeted", func() {
   288  				BeforeEach(func() {
   289  					config.SetSpaceFields(models.SpaceFields{
   290  						Name: "my-space",
   291  						Guid: "space-guid",
   292  					})
   293  				})
   294  
   295  				It("tells the user which space is targeted", func() {
   296  					Expect(output).To(ContainSubstrings([]string{"Space:", "my-space"}))
   297  				})
   298  			})
   299  		})
   300  
   301  		It("prompts the user to target an org and space when no org or space is targeted", func() {
   302  			output := io_helpers.CaptureOutput(func() {
   303  				ui := NewUI(os.Stdin, NewTeePrinter())
   304  				ui.ShowConfiguration(config)
   305  			})
   306  
   307  			Expect(output).To(ContainSubstrings([]string{"No", "org", "space", "targeted", "-o ORG", "-s SPACE"}))
   308  		})
   309  
   310  		It("prompts the user to target an org when no org is targeted", func() {
   311  			sf := models.SpaceFields{}
   312  			sf.Guid = "guid"
   313  			sf.Name = "name"
   314  
   315  			output := io_helpers.CaptureOutput(func() {
   316  				ui := NewUI(os.Stdin, NewTeePrinter())
   317  				ui.ShowConfiguration(config)
   318  			})
   319  
   320  			Expect(output).To(ContainSubstrings([]string{"No", "org", "targeted", "-o ORG"}))
   321  		})
   322  
   323  		It("prompts the user to target a space when no space is targeted", func() {
   324  			of := models.OrganizationFields{}
   325  			of.Guid = "of-guid"
   326  			of.Name = "of-name"
   327  
   328  			output := io_helpers.CaptureOutput(func() {
   329  				ui := NewUI(os.Stdin, NewTeePrinter())
   330  				ui.ShowConfiguration(config)
   331  			})
   332  
   333  			Expect(output).To(ContainSubstrings([]string{"No", "space", "targeted", "-s SPACE"}))
   334  		})
   335  	})
   336  
   337  	Describe("failing", func() {
   338  		It("panics with a specific string", func() {
   339  			io_helpers.CaptureOutput(func() {
   340  				testassert.AssertPanic(QuietPanic, func() {
   341  					NewUI(os.Stdin, NewTeePrinter()).Failed("uh oh")
   342  				})
   343  			})
   344  		})
   345  
   346  		It("does not use 'T' func to translate when it is not initialized", func() {
   347  			t := i18n.T
   348  			i18n.T = nil
   349  
   350  			io_helpers.CaptureOutput(func() {
   351  				testassert.AssertPanic(QuietPanic, func() {
   352  					NewUI(os.Stdin, NewTeePrinter()).Failed("uh oh")
   353  				})
   354  			})
   355  
   356  			i18n.T = t
   357  		})
   358  	})
   359  
   360  	Describe("NotifyUpdateIfNeeded", func() {
   361  
   362  		var (
   363  			output []string
   364  			config core_config.ReadWriter
   365  		)
   366  
   367  		BeforeEach(func() {
   368  			config = testconfig.NewRepository()
   369  		})
   370  
   371  		It("Prints a notification to user if current version < min cli version", func() {
   372  			config.SetMinCliVersion("6.0.0")
   373  			config.SetMinRecommendedCliVersion("6.5.0")
   374  			config.SetApiVersion("2.15.1")
   375  			cf.Version = "5.0.0"
   376  			output = io_helpers.CaptureOutput(func() {
   377  				ui := NewUI(os.Stdin, NewTeePrinter())
   378  				ui.NotifyUpdateIfNeeded(config)
   379  			})
   380  
   381  			Ω(output).To(ContainSubstrings([]string{"Cloud Foundry API version",
   382  				"requires CLI version 6.0.0",
   383  				"You are currently on version 5.0.0",
   384  				"To upgrade your CLI, please visit: https://github.com/cloudfoundry/cli#downloads",
   385  			}))
   386  		})
   387  
   388  		It("Doesn't print a notification to user if current version >= min cli version", func() {
   389  			config.SetMinCliVersion("6.0.0")
   390  			config.SetMinRecommendedCliVersion("6.5.0")
   391  			config.SetApiVersion("2.15.1")
   392  			cf.Version = "6.0.0"
   393  			output = io_helpers.CaptureOutput(func() {
   394  				ui := NewUI(os.Stdin, NewTeePrinter())
   395  				ui.NotifyUpdateIfNeeded(config)
   396  			})
   397  
   398  			Ω(output[0]).To(Equal(""))
   399  		})
   400  	})
   401  })