github.com/lukasheimann/cloudfoundrycli@v7.1.0+incompatible/integration/shared/plugin/install_plugin_from_repo_command_test.go (about)

     1  package plugin
     2  
     3  import (
     4  	"net/http"
     5  	"runtime"
     6  
     7  	"code.cloudfoundry.org/cli/integration/helpers"
     8  	"code.cloudfoundry.org/cli/util/generic"
     9  	. "github.com/onsi/ginkgo"
    10  	. "github.com/onsi/gomega"
    11  	. "github.com/onsi/gomega/gbytes"
    12  	. "github.com/onsi/gomega/gexec"
    13  	. "github.com/onsi/gomega/ghttp"
    14  )
    15  
    16  var _ = Describe("install-plugin (from repo) command", func() {
    17  	Describe("installing a plugin from a specific repo", func() {
    18  		When("the repo and the plugin name are swapped", func() {
    19  			var repoServer *Server
    20  
    21  			BeforeEach(func() {
    22  				repoServer = helpers.NewPluginRepositoryServer(helpers.PluginRepository{})
    23  				Eventually(helpers.CF("add-plugin-repo", "kaka", repoServer.URL(), "-k")).Should(Exit(0))
    24  			})
    25  
    26  			AfterEach(func() {
    27  				repoServer.Close()
    28  			})
    29  
    30  			It("it parses the arguments correctly", func() {
    31  				session := helpers.CF("install-plugin", "-f", "some-plugin", "-r", "kaka", "-k")
    32  
    33  				Eventually(session.Err).Should(Say(`Plugin some-plugin not found in repository kaka\.`))
    34  				Eventually(session).Should(Exit(1))
    35  			})
    36  		})
    37  
    38  		When("the repo is not registered", func() {
    39  			It("fails with an error message", func() {
    40  				session := helpers.CF("install-plugin", "-f", "-r", "repo-that-does-not-exist", "some-plugin")
    41  
    42  				Eventually(session.Err).Should(Say(`Plugin repository repo-that-does-not-exist not found\.`))
    43  				Eventually(session.Err).Should(Say(`Use 'cf list-plugin-repos' to list registered repos\.`))
    44  				Eventually(session).Should(Exit(1))
    45  			})
    46  		})
    47  
    48  		When("fetching a list of plugins from a repo returns a 4xx/5xx status or a SSL error", func() {
    49  			var repoServer *Server
    50  
    51  			BeforeEach(func() {
    52  				repoServer = NewTLSServer()
    53  
    54  				repoServer.AppendHandlers(
    55  					CombineHandlers(
    56  						VerifyRequest(http.MethodGet, "/list"),
    57  						RespondWith(http.StatusOK, `{"plugins":[]}`),
    58  					),
    59  					CombineHandlers(
    60  						VerifyRequest(http.MethodGet, "/list"),
    61  						RespondWith(http.StatusTeapot, nil),
    62  					),
    63  				)
    64  
    65  				Eventually(helpers.CF("add-plugin-repo", "kaka", repoServer.URL(), "-k")).Should(Exit(0))
    66  			})
    67  
    68  			AfterEach(func() {
    69  				repoServer.Close()
    70  			})
    71  
    72  			It("fails with an error message", func() {
    73  				session := helpers.CF("install-plugin", "-f", "-r", "kaka", "some-plugin", "-k")
    74  
    75  				Eventually(session.Err).Should(Say("Download attempt failed; server returned 418 I'm a teapot"))
    76  				Eventually(session.Err).Should(Say(`Unable to install; plugin is not available from the given URL\.`))
    77  				Eventually(session).Should(Exit(1))
    78  			})
    79  		})
    80  
    81  		When("the repo returns invalid json", func() {
    82  			var repoServer *Server
    83  
    84  			BeforeEach(func() {
    85  				repoServer = NewTLSServer()
    86  
    87  				repoServer.AppendHandlers(
    88  					CombineHandlers(
    89  						VerifyRequest(http.MethodGet, "/list"),
    90  						RespondWith(http.StatusOK, `{"plugins":[]}`),
    91  					),
    92  					CombineHandlers(
    93  						VerifyRequest(http.MethodGet, "/list"),
    94  						RespondWith(http.StatusOK, `{"foo":}`),
    95  					),
    96  				)
    97  
    98  				Eventually(helpers.CF("add-plugin-repo", "kaka", repoServer.URL(), "-k")).Should(Exit(0))
    99  			})
   100  
   101  			AfterEach(func() {
   102  				repoServer.Close()
   103  			})
   104  
   105  			It("fails with an error message", func() {
   106  				session := helpers.CF("install-plugin", "-f", "-r", "kaka", "some-plugin", "-k")
   107  
   108  				Eventually(session.Err).Should(Say("Invalid JSON content from server: invalid character '}' looking for beginning of value"))
   109  				Eventually(session).Should(Exit(1))
   110  			})
   111  		})
   112  
   113  		When("the repo does not contain the specified plugin", func() {
   114  			var repoServer *Server
   115  
   116  			BeforeEach(func() {
   117  				repoServer = helpers.NewPluginRepositoryServer(helpers.PluginRepository{})
   118  				Eventually(helpers.CF("add-plugin-repo", "kaka", repoServer.URL(), "-k")).Should(Exit(0))
   119  			})
   120  
   121  			AfterEach(func() {
   122  				repoServer.Close()
   123  			})
   124  
   125  			It("fails with an error message", func() {
   126  				session := helpers.CF("install-plugin", "-f", "-r", "kaka", "plugin-that-does-not-exist", "-k")
   127  
   128  				Eventually(session).Should(Say("FAILED"))
   129  				Eventually(session.Err).Should(Say(`Plugin plugin-that-does-not-exist not found in repository kaka\.`))
   130  				Eventually(session.Err).Should(Say(`Use 'cf repo-plugins -r kaka' to list plugins available in the repo\.`))
   131  
   132  				Eventually(session).Should(Exit(1))
   133  			})
   134  		})
   135  
   136  		When("the repo contains the specified plugin", func() {
   137  			var repoServer *helpers.PluginRepositoryServerWithPlugin
   138  
   139  			When("no compatible binary is found in the repo", func() {
   140  				BeforeEach(func() {
   141  					repoServer = helpers.NewPluginRepositoryServerWithPlugin("configurable_plugin", "some-plugin", "1.0.0", "not-me-platform", true)
   142  					Eventually(helpers.CF("add-plugin-repo", "kaka", repoServer.URL())).Should(Exit(0))
   143  				})
   144  
   145  				AfterEach(func() {
   146  					repoServer.Cleanup()
   147  				})
   148  
   149  				It("returns plugin not found", func() {
   150  					session := helpers.CF("install-plugin", "-f", "-r", "kaka", "some-plugin", "-k")
   151  					Eventually(session).Should(Say("FAILED"))
   152  					Eventually(session.Err).Should(Say(`Plugin requested has no binary available for your platform\.`))
   153  
   154  					Eventually(session).Should(Exit(1))
   155  				})
   156  			})
   157  
   158  			When("-f is specified", func() {
   159  				When("the plugin is not already installed", func() {
   160  					When("the plugin checksum is valid", func() {
   161  						BeforeEach(func() {
   162  							repoServer = helpers.NewPluginRepositoryServerWithPlugin("configurable_plugin", "some-plugin", "1.0.0", generic.GeneratePlatform(runtime.GOOS, runtime.GOARCH), true)
   163  							Eventually(helpers.CF("add-plugin-repo", "kaka", repoServer.URL())).Should(Exit(0))
   164  						})
   165  
   166  						AfterEach(func() {
   167  							repoServer.Cleanup()
   168  						})
   169  
   170  						It("installs the plugin case-insensitively", func() {
   171  							session := helpers.CF("install-plugin", "-f", "-r", "kAkA", "some-plugin", "-k")
   172  							Eventually(session).Should(Say(`Searching kaka for plugin some-plugin\.\.\.`))
   173  							Eventually(session).Should(Say(`Plugin some-plugin 1\.0\.0 found in: kaka\n`))
   174  							Eventually(session).Should(Say(`Attention: Plugins are binaries written by potentially untrusted authors\.`))
   175  							Eventually(session).Should(Say(`Install and use plugins at your own risk\.`))
   176  							Eventually(session).Should(Say(`Starting download of plugin binary from repository kaka\.\.\.`))
   177  							Eventually(session).Should(Say(`\d.* .*B / ?`))
   178  							Eventually(session).Should(Say(`Installing plugin some-plugin\.\.\.`))
   179  							Eventually(session).Should(Say("OK"))
   180  							Eventually(session).Should(Say(`Plugin some-plugin 1\.0\.0 successfully installed\.`))
   181  
   182  							Eventually(session).Should(Exit(0))
   183  						})
   184  					})
   185  
   186  					When("the plugin checksum is invalid", func() {
   187  						BeforeEach(func() {
   188  							repoServer = helpers.NewPluginRepositoryServerWithPlugin("configurable_plugin", "some-plugin", "1.0.0", generic.GeneratePlatform(runtime.GOOS, runtime.GOARCH), false)
   189  							Eventually(helpers.CF("add-plugin-repo", "kaka", repoServer.URL())).Should(Exit(0))
   190  
   191  						})
   192  
   193  						AfterEach(func() {
   194  							repoServer.Cleanup()
   195  						})
   196  
   197  						It("fails with an error message", func() {
   198  							session := helpers.CF("install-plugin", "-f", "-r", "kaka", "some-plugin", "-k")
   199  							Eventually(session).Should(Say("FAILED"))
   200  							Eventually(session.Err).Should(Say(`Downloaded plugin binary's checksum does not match repo metadata\.`))
   201  							Eventually(session.Err).Should(Say(`Please try again or contact the plugin author\.`))
   202  							Eventually(session).Should(Exit(1))
   203  						})
   204  					})
   205  				})
   206  
   207  				When("the plugin is already installed", func() {
   208  					BeforeEach(func() {
   209  						pluginPath := helpers.BuildConfigurablePlugin("configurable_plugin", "some-plugin", "1.0.0",
   210  							[]helpers.PluginCommand{
   211  								{Name: "some-command", Help: "some-command-help"},
   212  							},
   213  						)
   214  						Eventually(helpers.CF("install-plugin", pluginPath, "-f", "-k")).Should(Exit(0))
   215  					})
   216  
   217  					When("the plugin checksum is valid", func() {
   218  						BeforeEach(func() {
   219  							repoServer = helpers.NewPluginRepositoryServerWithPlugin("configurable_plugin", "some-plugin", "2.0.0", generic.GeneratePlatform(runtime.GOOS, runtime.GOARCH), true)
   220  							Eventually(helpers.CF("add-plugin-repo", "kaka", repoServer.URL())).Should(Exit(0))
   221  						})
   222  
   223  						AfterEach(func() {
   224  							repoServer.Cleanup()
   225  						})
   226  
   227  						It("reinstalls the plugin", func() {
   228  							session := helpers.CF("install-plugin", "-f", "-r", "kaka", "some-plugin", "-k")
   229  
   230  							Eventually(session).Should(Say(`Searching kaka for plugin some-plugin\.\.\.`))
   231  							Eventually(session).Should(Say(`Plugin some-plugin 2\.0\.0 found in: kaka\n`))
   232  							Eventually(session).Should(Say(`Plugin some-plugin 1\.0\.0 is already installed\.`))
   233  							Eventually(session).Should(Say(`Attention: Plugins are binaries written by potentially untrusted authors\.`))
   234  							Eventually(session).Should(Say(`Install and use plugins at your own risk\.`))
   235  							Eventually(session).Should(Say(`Starting download of plugin binary from repository kaka\.\.\.`))
   236  							Eventually(session).Should(Say(`\d.* .*B / ?`))
   237  							Eventually(session).Should(Say(`Uninstalling existing plugin\.\.\.`))
   238  							Eventually(session).Should(Say("OK"))
   239  							Eventually(session).Should(Say(`Plugin some-plugin successfully uninstalled\.`))
   240  							Eventually(session).Should(Say(`Installing plugin some-plugin\.\.\.`))
   241  							Eventually(session).Should(Say("OK"))
   242  							Eventually(session).Should(Say(`Plugin some-plugin 2\.0\.0 successfully installed\.`))
   243  
   244  							Eventually(session).Should(Exit(0))
   245  						})
   246  					})
   247  
   248  					When("the plugin checksum is invalid", func() {
   249  						BeforeEach(func() {
   250  							repoServer = helpers.NewPluginRepositoryServerWithPlugin("configurable_plugin", "some-plugin", "2.0.0", generic.GeneratePlatform(runtime.GOOS, runtime.GOARCH), false)
   251  							Eventually(helpers.CF("add-plugin-repo", "kaka", repoServer.URL())).Should(Exit(0))
   252  						})
   253  
   254  						AfterEach(func() {
   255  							repoServer.Cleanup()
   256  						})
   257  
   258  						It("fails with an error message", func() {
   259  							session := helpers.CF("install-plugin", "-f", "-r", "kaka", "some-plugin", "-k")
   260  
   261  							Eventually(session).Should(Say(`Searching kaka for plugin some-plugin\.\.\.`))
   262  							Eventually(session).Should(Say(`Plugin some-plugin 2\.0\.0 found in: kaka\n`))
   263  							Eventually(session).Should(Say(`Plugin some-plugin 1\.0\.0 is already installed\.`))
   264  							Eventually(session).Should(Say(`Attention: Plugins are binaries written by potentially untrusted authors\.`))
   265  							Eventually(session).Should(Say(`Install and use plugins at your own risk\.`))
   266  							Eventually(session).Should(Say(`Starting download of plugin binary from repository kaka\.\.\.`))
   267  							Eventually(session).Should(Say(`\d.* .*B / ?`))
   268  
   269  							Eventually(session).Should(Say("FAILED"))
   270  							Eventually(session.Err).Should(Say(`Downloaded plugin binary's checksum does not match repo metadata\.`))
   271  							Eventually(session.Err).Should(Say(`Please try again or contact the plugin author\.`))
   272  
   273  							Eventually(session).Should(Exit(1))
   274  						})
   275  					})
   276  				})
   277  			})
   278  
   279  			When("-f is not specified", func() {
   280  				var buffer *Buffer
   281  
   282  				BeforeEach(func() {
   283  					buffer = NewBuffer()
   284  				})
   285  
   286  				When("the plugin is not already installed", func() {
   287  					BeforeEach(func() {
   288  						repoServer = helpers.NewPluginRepositoryServerWithPlugin("configurable_plugin", "some-plugin", "1.2.3", generic.GeneratePlatform(runtime.GOOS, runtime.GOARCH), true)
   289  						Eventually(helpers.CF("add-plugin-repo", "kaka", repoServer.URL())).Should(Exit(0))
   290  					})
   291  
   292  					AfterEach(func() {
   293  						repoServer.Cleanup()
   294  					})
   295  
   296  					When("the user says yes", func() {
   297  						BeforeEach(func() {
   298  							_, err := buffer.Write([]byte("y\n"))
   299  							Expect(err).ToNot(HaveOccurred())
   300  						})
   301  
   302  						It("installs the plugin", func() {
   303  							session := helpers.CFWithStdin(buffer, "install-plugin", "-r", "kaka", "some-plugin", "-k")
   304  							Eventually(session).Should(Say(`Searching kaka for plugin some-plugin\.\.\.`))
   305  							Eventually(session).Should(Say(`Plugin some-plugin 1\.2\.3 found in: kaka\n`))
   306  							Eventually(session).Should(Say(`Attention: Plugins are binaries written by potentially untrusted authors\.`))
   307  							Eventually(session).Should(Say(`Install and use plugins at your own risk\.`))
   308  							Eventually(session).Should(Say(`Do you want to install the plugin some-plugin\? \[yN\]: y`))
   309  							Eventually(session).Should(Say(`Starting download of plugin binary from repository kaka\.\.\.`))
   310  							Eventually(session).Should(Say(`\d.* .*B / ?`))
   311  							Eventually(session).Should(Say(`Installing plugin some-plugin\.\.\.`))
   312  							Eventually(session).Should(Say("OK"))
   313  							Eventually(session).Should(Say(`Plugin some-plugin 1\.2\.3 successfully installed\.`))
   314  
   315  							Eventually(session).Should(Exit(0))
   316  						})
   317  					})
   318  
   319  					When("the user says no", func() {
   320  						BeforeEach(func() {
   321  							_, err := buffer.Write([]byte("n\n"))
   322  							Expect(err).ToNot(HaveOccurred())
   323  						})
   324  
   325  						It("does not install the plugin", func() {
   326  							session := helpers.CFWithStdin(buffer, "install-plugin", "-r", "kaka", "some-plugin", "-k")
   327  							Eventually(session).Should(Say(`Searching kaka for plugin some-plugin\.\.\.`))
   328  							Eventually(session).Should(Say(`Plugin some-plugin 1\.2\.3 found in: kaka\n`))
   329  							Eventually(session).Should(Say(`Attention: Plugins are binaries written by potentially untrusted authors\.`))
   330  							Eventually(session).Should(Say(`Install and use plugins at your own risk\.`))
   331  							Eventually(session).Should(Say(`Do you want to install the plugin some-plugin\? \[yN\]: n`))
   332  
   333  							Eventually(session).Should(Say("Plugin installation cancelled"))
   334  
   335  							Eventually(session).Should(Exit(0))
   336  						})
   337  					})
   338  				})
   339  
   340  				When("the plugin is already installed", func() {
   341  					BeforeEach(func() {
   342  						pluginPath := helpers.BuildConfigurablePlugin("configurable_plugin", "some-plugin", "1.2.2",
   343  							[]helpers.PluginCommand{
   344  								{Name: "some-command", Help: "some-command-help"},
   345  							},
   346  						)
   347  						Eventually(helpers.CF("install-plugin", pluginPath, "-f", "-k")).Should(Exit(0))
   348  					})
   349  
   350  					When("the user chooses yes", func() {
   351  						BeforeEach(func() {
   352  							_, err := buffer.Write([]byte("y\n"))
   353  							Expect(err).ToNot(HaveOccurred())
   354  						})
   355  
   356  						When("the plugin checksum is valid", func() {
   357  							BeforeEach(func() {
   358  								repoServer = helpers.NewPluginRepositoryServerWithPlugin("configurable_plugin", "some-plugin", "1.2.3", generic.GeneratePlatform(runtime.GOOS, runtime.GOARCH), true)
   359  								Eventually(helpers.CF("add-plugin-repo", "kaka", repoServer.URL())).Should(Exit(0))
   360  							})
   361  
   362  							AfterEach(func() {
   363  								repoServer.Cleanup()
   364  							})
   365  
   366  							It("installs the plugin", func() {
   367  								session := helpers.CFWithStdin(buffer, "install-plugin", "-r", "kaka", "some-plugin", "-k")
   368  
   369  								Eventually(session).Should(Say(`Searching kaka for plugin some-plugin\.\.\.`))
   370  								Eventually(session).Should(Say(`Plugin some-plugin 1\.2\.3 found in: kaka\n`))
   371  								Eventually(session).Should(Say(`Plugin some-plugin 1\.2\.2 is already installed\.`))
   372  								Eventually(session).Should(Say(`Attention: Plugins are binaries written by potentially untrusted authors\.`))
   373  								Eventually(session).Should(Say(`Install and use plugins at your own risk\.`))
   374  								Eventually(session).Should(Say(`Do you want to uninstall the existing plugin and install some-plugin 1\.2\.3\? \[yN\]: y`))
   375  								Eventually(session).Should(Say(`Starting download of plugin binary from repository kaka\.\.\.`))
   376  								Eventually(session).Should(Say(`\d.* .*B / ?`))
   377  								Eventually(session).Should(Say(`Uninstalling existing plugin\.\.\.`))
   378  								Eventually(session).Should(Say("OK"))
   379  								Eventually(session).Should(Say(`Plugin some-plugin successfully uninstalled\.`))
   380  								Eventually(session).Should(Say(`Installing plugin some-plugin\.\.\.`))
   381  								Eventually(session).Should(Say("OK"))
   382  								Eventually(session).Should(Say(`Plugin some-plugin 1\.2\.3 successfully installed\.`))
   383  
   384  								Eventually(session).Should(Exit(0))
   385  							})
   386  						})
   387  
   388  						When("the plugin checksum is invalid", func() {
   389  							BeforeEach(func() {
   390  								repoServer = helpers.NewPluginRepositoryServerWithPlugin("configurable_plugin", "some-plugin", "1.2.3", generic.GeneratePlatform(runtime.GOOS, runtime.GOARCH), false)
   391  
   392  								Eventually(helpers.CF("add-plugin-repo", "kaka", repoServer.URL())).Should(Exit(0))
   393  							})
   394  
   395  							AfterEach(func() {
   396  								repoServer.Cleanup()
   397  							})
   398  
   399  							It("fails with an error message", func() {
   400  								session := helpers.CFWithStdin(buffer, "install-plugin", "-r", "kaka", "some-plugin", "-k")
   401  								Eventually(session).Should(Say(`Searching kaka for plugin some-plugin\.\.\.`))
   402  								Eventually(session).Should(Say(`Plugin some-plugin 1\.2\.3 found in: kaka\n`))
   403  								Eventually(session).Should(Say(`Plugin some-plugin 1\.2\.2 is already installed\.`))
   404  								Eventually(session).Should(Say(`Attention: Plugins are binaries written by potentially untrusted authors\.`))
   405  								Eventually(session).Should(Say(`Install and use plugins at your own risk\.`))
   406  								Eventually(session).Should(Say(`Do you want to uninstall the existing plugin and install some-plugin 1\.2\.3\? \[yN\]: y`))
   407  								Eventually(session).Should(Say(`Starting download of plugin binary from repository kaka\.\.\.`))
   408  								Eventually(session).Should(Say(`\d.* .*B / ?`))
   409  								Eventually(session).Should(Say("FAILED"))
   410  								Eventually(session.Err).Should(Say(`Downloaded plugin binary's checksum does not match repo metadata\.`))
   411  								Eventually(session.Err).Should(Say(`Please try again or contact the plugin author\.`))
   412  
   413  								Eventually(session).Should(Exit(1))
   414  							})
   415  						})
   416  					})
   417  
   418  					When("the user chooses no", func() {
   419  						BeforeEach(func() {
   420  							repoServer = helpers.NewPluginRepositoryServerWithPlugin("configurable_plugin", "some-plugin", "1.2.3", generic.GeneratePlatform(runtime.GOOS, runtime.GOARCH), false)
   421  							Eventually(helpers.CF("add-plugin-repo", "kaka", repoServer.URL())).Should(Exit(0))
   422  
   423  							_, err := buffer.Write([]byte("n\n"))
   424  							Expect(err).ToNot(HaveOccurred())
   425  						})
   426  
   427  						AfterEach(func() {
   428  							repoServer.Cleanup()
   429  						})
   430  
   431  						It("does not install the plugin", func() {
   432  							session := helpers.CFWithStdin(buffer, "install-plugin", "-r", "kaka", "some-plugin", "-k")
   433  
   434  							Eventually(session).Should(Say(`Searching kaka for plugin some-plugin\.\.\.`))
   435  							Eventually(session).Should(Say(`Plugin some-plugin 1\.2\.3 found in: kaka\n`))
   436  							Eventually(session).Should(Say(`Plugin some-plugin 1\.2\.2 is already installed\.`))
   437  							Eventually(session).Should(Say(`Attention: Plugins are binaries written by potentially untrusted authors\.`))
   438  							Eventually(session).Should(Say(`Install and use plugins at your own risk\.`))
   439  							Eventually(session).Should(Say(`Do you want to uninstall the existing plugin and install some-plugin 1\.2\.3\? \[yN\]: n`))
   440  							Eventually(session).Should(Say("Plugin installation cancelled"))
   441  
   442  							Eventually(session).Should(Exit(0))
   443  						})
   444  					})
   445  				})
   446  			})
   447  		})
   448  	})
   449  
   450  	Describe("installing a plugin from any repo", func() {
   451  		When("there are no repositories registered", func() {
   452  			It("fails and displays the plugin not found message", func() {
   453  				session := helpers.CF("install-plugin", "some-plugin")
   454  
   455  				Eventually(session).Should(Say("FAILED"))
   456  				Eventually(session.Err).Should(Say(`Plugin some-plugin not found on disk or in any registered repo\.`))
   457  				Eventually(session.Err).Should(Say(`Use 'cf repo-plugins' to list plugins available in the repos\.`))
   458  
   459  				Eventually(session).Should(Exit(1))
   460  			})
   461  		})
   462  
   463  		When("there are repositories registered", func() {
   464  			When("fetching a list of plugins from a repo returns a 4xx/5xx status or a SSL error", func() {
   465  				var repoServer *Server
   466  
   467  				BeforeEach(func() {
   468  					repoServer = NewTLSServer()
   469  
   470  					repoServer.AppendHandlers(
   471  						CombineHandlers(
   472  							VerifyRequest(http.MethodGet, "/list"),
   473  							RespondWith(http.StatusOK, `{"plugins":[]}`),
   474  						),
   475  						CombineHandlers(
   476  							VerifyRequest(http.MethodGet, "/list"),
   477  							RespondWith(http.StatusTeapot, nil),
   478  						),
   479  					)
   480  
   481  					Eventually(helpers.CF("add-plugin-repo", "kaka", repoServer.URL(), "-k")).Should(Exit(0))
   482  				})
   483  
   484  				AfterEach(func() {
   485  					repoServer.Close()
   486  				})
   487  
   488  				It("fails with an error message", func() {
   489  					session := helpers.CF("install-plugin", "-f", "some-plugin", "-k")
   490  
   491  					Eventually(session.Err).Should(Say("Plugin list download failed; repository kaka returned 418 I'm a teapot"))
   492  					Consistently(session.Err).ShouldNot(Say(`Unable to install; plugin is not available from the given URL\.`))
   493  					Eventually(session).Should(Exit(1))
   494  				})
   495  			})
   496  
   497  			When("the plugin isn't found in any of the repositories", func() {
   498  				var repoServer1 *Server
   499  				var repoServer2 *Server
   500  
   501  				BeforeEach(func() {
   502  					repoServer1 = helpers.NewPluginRepositoryServer(helpers.PluginRepository{})
   503  					repoServer2 = helpers.NewPluginRepositoryServer(helpers.PluginRepository{})
   504  					Eventually(helpers.CF("add-plugin-repo", "kaka1", repoServer1.URL(), "-k")).Should(Exit(0))
   505  					Eventually(helpers.CF("add-plugin-repo", "kaka2", repoServer2.URL(), "-k")).Should(Exit(0))
   506  				})
   507  
   508  				AfterEach(func() {
   509  					repoServer1.Close()
   510  					repoServer2.Close()
   511  				})
   512  
   513  				It("fails and displays the plugin not found message", func() {
   514  					session := helpers.CF("install-plugin", "some-plugin", "-k")
   515  
   516  					Eventually(session).Should(Say(`Searching kaka1, kaka2 for plugin some-plugin\.\.\.`))
   517  					Eventually(session).Should(Say("FAILED"))
   518  					Eventually(session.Err).Should(Say(`Plugin some-plugin not found on disk or in any registered repo\.`))
   519  					Eventually(session.Err).Should(Say(`Use 'cf repo-plugins' to list plugins available in the repos\.`))
   520  
   521  					Eventually(session).Should(Exit(1))
   522  				})
   523  			})
   524  
   525  			When("-f is specified", func() {
   526  				When("identical versions of the plugin are found in the repositories", func() {
   527  					var repoServer1 *helpers.PluginRepositoryServerWithPlugin
   528  					var repoServer2 *helpers.PluginRepositoryServerWithPlugin
   529  
   530  					BeforeEach(func() {
   531  						repoServer1 = helpers.NewPluginRepositoryServerWithPlugin("configurable_plugin", "some-plugin", "1.2.3", generic.GeneratePlatform(runtime.GOOS, runtime.GOARCH), true)
   532  						Eventually(helpers.CF("add-plugin-repo", "kaka1", repoServer1.URL())).Should(Exit(0))
   533  
   534  						repoServer2 = helpers.NewPluginRepositoryServerWithPlugin("configurable_plugin", "some-plugin", "1.2.3", generic.GeneratePlatform(runtime.GOOS, runtime.GOARCH), true)
   535  						Eventually(helpers.CF("add-plugin-repo", "kaka2", repoServer2.URL())).Should(Exit(0))
   536  					})
   537  
   538  					AfterEach(func() {
   539  						repoServer1.Cleanup()
   540  						repoServer2.Cleanup()
   541  					})
   542  
   543  					When("the plugin is not already installed", func() {
   544  						When("the checksum is valid", func() {
   545  							It("installs the plugin", func() {
   546  								session := helpers.CF("install-plugin", "some-plugin", "-f", "-k")
   547  
   548  								Eventually(session).Should(Say(`Searching kaka1, kaka2 for plugin some-plugin\.\.\.`))
   549  								Eventually(session).Should(Say(`Plugin some-plugin 1\.2\.3 found in: kaka1, kaka2`))
   550  								Eventually(session).Should(Say(`Attention: Plugins are binaries written by potentially untrusted authors\.`))
   551  								Eventually(session).Should(Say(`Install and use plugins at your own risk\.`))
   552  								Eventually(session).Should(Say(`Starting download of plugin binary from repository kaka1\.\.\.`))
   553  								Eventually(session).Should(Say(`\d.* .*B / ?`))
   554  								Eventually(session).Should(Say(`Installing plugin some-plugin\.\.\.`))
   555  								Eventually(session).Should(Say("OK"))
   556  								Eventually(session).Should(Say(`Plugin some-plugin 1\.2\.3 successfully installed\.`))
   557  
   558  								Eventually(session).Should(Exit(0))
   559  							})
   560  						})
   561  
   562  						When("the plugin checksum is invalid", func() {
   563  							var repoServer3 *helpers.PluginRepositoryServerWithPlugin
   564  							var repoServer4 *helpers.PluginRepositoryServerWithPlugin
   565  
   566  							BeforeEach(func() {
   567  								repoServer3 = helpers.NewPluginRepositoryServerWithPlugin("configurable_plugin", "some-plugin-with-bad-checksum", "2.2.3", generic.GeneratePlatform(runtime.GOOS, runtime.GOARCH), false)
   568  								Eventually(helpers.CF("add-plugin-repo", "kaka3", repoServer3.URL())).Should(Exit(0))
   569  
   570  								repoServer4 = helpers.NewPluginRepositoryServerWithPlugin("configurable_plugin", "some-plugin-with-bad-checksum", "2.2.3", generic.GeneratePlatform(runtime.GOOS, runtime.GOARCH), true)
   571  								Eventually(helpers.CF("add-plugin-repo", "kaka4", repoServer4.URL())).Should(Exit(0))
   572  							})
   573  
   574  							AfterEach(func() {
   575  								repoServer3.Cleanup()
   576  								repoServer4.Cleanup()
   577  							})
   578  
   579  							It("fails with the invalid checksum message", func() {
   580  								session := helpers.CF("install-plugin", "some-plugin-with-bad-checksum", "-f", "-k")
   581  
   582  								Eventually(session).Should(Say(`Searching kaka1, kaka2, kaka3, kaka4 for plugin some-plugin-with-bad-checksum\.\.\.`))
   583  								Eventually(session).Should(Say(`Plugin some-plugin-with-bad-checksum 2\.2\.3 found in: kaka3, kaka4`))
   584  								Eventually(session).Should(Say(`Attention: Plugins are binaries written by potentially untrusted authors\.`))
   585  								Eventually(session).Should(Say(`Install and use plugins at your own risk\.`))
   586  								Eventually(session).Should(Say(`Starting download of plugin binary from repository kaka3\.\.\.`))
   587  								Eventually(session).Should(Say(`\d.* .*B / ?`))
   588  								Eventually(session).Should(Say("FAILED"))
   589  								Eventually(session.Err).Should(Say(`Downloaded plugin binary's checksum does not match repo metadata\.`))
   590  								Eventually(session.Err).Should(Say(`Please try again or contact the plugin author\.`))
   591  
   592  								Eventually(session).Should(Exit(1))
   593  							})
   594  						})
   595  					})
   596  
   597  					When("the plugin is already installed", func() {
   598  						When("the checksum is valid", func() {
   599  							BeforeEach(func() {
   600  								pluginPath := helpers.BuildConfigurablePlugin("configurable_plugin", "some-plugin", "1.0.0",
   601  									[]helpers.PluginCommand{
   602  										{Name: "some-command", Help: "some-command-help"},
   603  									},
   604  								)
   605  								Eventually(helpers.CF("install-plugin", pluginPath, "-f", "-k")).Should(Exit(0))
   606  							})
   607  
   608  							It("reinstalls the plugin", func() {
   609  								session := helpers.CF("install-plugin", "-f", "some-plugin", "-k")
   610  
   611  								Eventually(session).Should(Say(`Searching kaka1, kaka2 for plugin some-plugin\.\.\.`))
   612  								Eventually(session).Should(Say(`Plugin some-plugin 1\.2\.3 found in: kaka1, kaka2`))
   613  								Eventually(session).Should(Say(`Plugin some-plugin 1\.0\.0 is already installed\.`))
   614  								Eventually(session).Should(Say(`Attention: Plugins are binaries written by potentially untrusted authors\.`))
   615  
   616  								Eventually(session).Should(Exit(0))
   617  							})
   618  						})
   619  					})
   620  				})
   621  
   622  				When("the binary version for the current GOOS/GOARCH is exists in only one repo", func() {
   623  					var repoServer1 *helpers.PluginRepositoryServerWithPlugin
   624  					var repoServer2 *helpers.PluginRepositoryServerWithPlugin
   625  
   626  					BeforeEach(func() {
   627  						repoServer1 = helpers.NewPluginRepositoryServerWithPlugin("configurable_plugin", "some-plugin", "1.2.3", "solaris", false)
   628  						Eventually(helpers.CF("add-plugin-repo", "kaka1", repoServer1.URL())).Should(Exit(0))
   629  
   630  						repoServer2 = helpers.NewPluginRepositoryServerWithPlugin("configurable_plugin", "some-plugin", "1.2.3", generic.GeneratePlatform(runtime.GOOS, runtime.GOARCH), true)
   631  						Eventually(helpers.CF("add-plugin-repo", "kaka2", repoServer2.URL())).Should(Exit(0))
   632  					})
   633  
   634  					AfterEach(func() {
   635  						repoServer1.Cleanup()
   636  						repoServer2.Cleanup()
   637  					})
   638  
   639  					It("installs the plugin from the correct repo", func() {
   640  						session := helpers.CF("install-plugin", "-f", "some-plugin", "-k")
   641  
   642  						Eventually(session).Should(Say(`Searching kaka1, kaka2 for plugin some-plugin\.\.\.`))
   643  						Eventually(session).Should(Say(`Plugin some-plugin 1\.2\.3 found in: kaka2`))
   644  						Eventually(session).Should(Say(`Attention: Plugins are binaries written by potentially untrusted authors\.`))
   645  						Eventually(session).Should(Say(`Install and use plugins at your own risk\.`))
   646  						Eventually(session).Should(Say(`Starting download of plugin binary from repository kaka2\.\.\.`))
   647  
   648  						Eventually(session).Should(Exit(0))
   649  					})
   650  				})
   651  
   652  				When("different versions of the plugin are found in the repositories", func() {
   653  					When("the checksum is valid", func() {
   654  						var repoServer1 *helpers.PluginRepositoryServerWithPlugin
   655  						var repoServer2 *helpers.PluginRepositoryServerWithPlugin
   656  
   657  						BeforeEach(func() {
   658  							repoServer1 = helpers.NewPluginRepositoryServerWithPlugin("configurable_plugin", "some-plugin", "1.2.3", generic.GeneratePlatform(runtime.GOOS, runtime.GOARCH), true)
   659  							Eventually(helpers.CF("add-plugin-repo", "kaka1", repoServer1.URL())).Should(Exit(0))
   660  
   661  							repoServer2 = helpers.NewPluginRepositoryServerWithPlugin("configurable_plugin", "some-plugin", "1.2.4", generic.GeneratePlatform(runtime.GOOS, runtime.GOARCH), true)
   662  							Eventually(helpers.CF("add-plugin-repo", "kaka2", repoServer2.URL())).Should(Exit(0))
   663  						})
   664  
   665  						AfterEach(func() {
   666  							repoServer1.Cleanup()
   667  							repoServer2.Cleanup()
   668  						})
   669  
   670  						It("installs the newest plugin", func() {
   671  							session := helpers.CF("install-plugin", "some-plugin", "-f", "-k")
   672  
   673  							Eventually(session).Should(Say(`Searching kaka1, kaka2 for plugin some-plugin\.\.\.`))
   674  							Eventually(session).Should(Say("Plugin some-plugin 1.2.4 found in: kaka2"))
   675  							Eventually(session).Should(Say(`Attention: Plugins are binaries written by potentially untrusted authors\.`))
   676  							Eventually(session).Should(Say(`Install and use plugins at your own risk\.`))
   677  							Eventually(session).Should(Say(`Starting download of plugin binary from repository kaka2\.\.\.`))
   678  							Eventually(session).Should(Say(`\d.* .*B / ?`))
   679  							Eventually(session).Should(Say(`Installing plugin some-plugin\.\.\.`))
   680  							Eventually(session).Should(Say("OK"))
   681  							Eventually(session).Should(Say(`Plugin some-plugin 1\.2\.4 successfully installed\.`))
   682  
   683  							Eventually(session).Should(Exit(0))
   684  						})
   685  					})
   686  
   687  					When("the checksum for the latest version is invalid", func() {
   688  						var repoServer1 *helpers.PluginRepositoryServerWithPlugin
   689  						var repoServer2 *helpers.PluginRepositoryServerWithPlugin
   690  
   691  						BeforeEach(func() {
   692  							repoServer1 = helpers.NewPluginRepositoryServerWithPlugin("configurable_plugin", "some-plugin", "1.2.3", generic.GeneratePlatform(runtime.GOOS, runtime.GOARCH), true)
   693  							Eventually(helpers.CF("add-plugin-repo", "kaka1", repoServer1.URL())).Should(Exit(0))
   694  
   695  							repoServer2 = helpers.NewPluginRepositoryServerWithPlugin("configurable_plugin", "some-plugin", "1.2.4", generic.GeneratePlatform(runtime.GOOS, runtime.GOARCH), false)
   696  							Eventually(helpers.CF("add-plugin-repo", "kaka2", repoServer2.URL())).Should(Exit(0))
   697  						})
   698  
   699  						AfterEach(func() {
   700  							repoServer1.Cleanup()
   701  							repoServer2.Cleanup()
   702  						})
   703  
   704  						It("prints the invalid checksum error", func() {
   705  							session := helpers.CF("install-plugin", "some-plugin", "-f", "-k")
   706  
   707  							Eventually(session).Should(Say(`Searching kaka1, kaka2 for plugin some-plugin\.\.\.`))
   708  							Eventually(session).Should(Say("Plugin some-plugin 1.2.4 found in: kaka2"))
   709  							Eventually(session).Should(Say(`Attention: Plugins are binaries written by potentially untrusted authors\.`))
   710  							Eventually(session).Should(Say(`Install and use plugins at your own risk\.`))
   711  							Eventually(session).Should(Say(`Starting download of plugin binary from repository kaka2\.\.\.`))
   712  							Eventually(session).Should(Say(`\d.* .*B / ?`))
   713  							Eventually(session).Should(Say("FAILED"))
   714  							Eventually(session.Err).Should(Say(`Downloaded plugin binary's checksum does not match repo metadata\.`))
   715  							Eventually(session.Err).Should(Say(`Please try again or contact the plugin author\.`))
   716  
   717  							Eventually(session).Should(Exit(1))
   718  						})
   719  					})
   720  				})
   721  			})
   722  
   723  			When("-f is not specified", func() {
   724  				var buffer *Buffer
   725  
   726  				BeforeEach(func() {
   727  					buffer = NewBuffer()
   728  				})
   729  
   730  				When("identical versions of the plugin are found in the repositories", func() {
   731  					var repoServer1 *helpers.PluginRepositoryServerWithPlugin
   732  					var repoServer2 *helpers.PluginRepositoryServerWithPlugin
   733  
   734  					BeforeEach(func() {
   735  						repoServer1 = helpers.NewPluginRepositoryServerWithPlugin("configurable_plugin", "some-plugin", "1.2.3", generic.GeneratePlatform(runtime.GOOS, runtime.GOARCH), true)
   736  						Eventually(helpers.CF("add-plugin-repo", "kaka1", repoServer1.URL())).Should(Exit(0))
   737  
   738  						repoServer2 = helpers.NewPluginRepositoryServerWithPlugin("configurable_plugin", "some-plugin", "1.2.3", generic.GeneratePlatform(runtime.GOOS, runtime.GOARCH), true)
   739  						Eventually(helpers.CF("add-plugin-repo", "kaka2", repoServer2.URL())).Should(Exit(0))
   740  					})
   741  
   742  					AfterEach(func() {
   743  						repoServer1.Cleanup()
   744  						repoServer2.Cleanup()
   745  					})
   746  
   747  					When("the plugin is not already installed", func() {
   748  						When("the user says yes", func() {
   749  							BeforeEach(func() {
   750  								_, err := buffer.Write([]byte("y\n"))
   751  								Expect(err).ToNot(HaveOccurred())
   752  							})
   753  
   754  							When("the checksum is valid", func() {
   755  								It("installs the plugin", func() {
   756  									session := helpers.CFWithStdin(buffer, "install-plugin", "some-plugin", "-k")
   757  
   758  									Eventually(session).Should(Say(`Searching kaka1, kaka2 for plugin some-plugin\.\.\.`))
   759  									Eventually(session).Should(Say(`Plugin some-plugin 1\.2\.3 found in: kaka1, kaka2`))
   760  									Eventually(session).Should(Say(`Attention: Plugins are binaries written by potentially untrusted authors\.`))
   761  									Eventually(session).Should(Say(`Install and use plugins at your own risk\.`))
   762  									Eventually(session).Should(Say(`Do you want to install the plugin some-plugin\? \[yN\]: y`))
   763  									Eventually(session).Should(Say(`Starting download of plugin binary from repository kaka1\.\.\.`))
   764  									Eventually(session).Should(Say(`\d.* .*B / ?`))
   765  									Eventually(session).Should(Say(`Installing plugin some-plugin\.\.\.`))
   766  									Eventually(session).Should(Say("OK"))
   767  									Eventually(session).Should(Say(`Plugin some-plugin 1\.2\.3 successfully installed\.`))
   768  
   769  									Eventually(session).Should(Exit(0))
   770  								})
   771  							})
   772  
   773  							When("the checksum is invalid", func() {
   774  								var repoServer3 *helpers.PluginRepositoryServerWithPlugin
   775  								var repoServer4 *helpers.PluginRepositoryServerWithPlugin
   776  
   777  								BeforeEach(func() {
   778  									repoServer3 = helpers.NewPluginRepositoryServerWithPlugin("configurable_plugin", "some-plugin-with-bad-checksum", "2.2.3", generic.GeneratePlatform(runtime.GOOS, runtime.GOARCH), false)
   779  									Eventually(helpers.CF("add-plugin-repo", "kaka3", repoServer3.URL())).Should(Exit(0))
   780  
   781  									repoServer4 = helpers.NewPluginRepositoryServerWithPlugin("configurable_plugin", "some-plugin-with-bad-checksum", "2.2.3", generic.GeneratePlatform(runtime.GOOS, runtime.GOARCH), false)
   782  									Eventually(helpers.CF("add-plugin-repo", "kaka4", repoServer4.URL())).Should(Exit(0))
   783  								})
   784  
   785  								AfterEach(func() {
   786  									repoServer3.Cleanup()
   787  									repoServer4.Cleanup()
   788  								})
   789  
   790  								It("fails with the invalid checksum message", func() {
   791  									session := helpers.CFWithStdin(buffer, "install-plugin", "some-plugin-with-bad-checksum", "-k")
   792  
   793  									Eventually(session).Should(Say("FAILED"))
   794  									Eventually(session.Err).Should(Say(`Downloaded plugin binary's checksum does not match repo metadata\.`))
   795  									Eventually(session.Err).Should(Say(`Please try again or contact the plugin author\.`))
   796  
   797  									Eventually(session).Should(Exit(1))
   798  								})
   799  							})
   800  						})
   801  
   802  						When("the user says no", func() {
   803  							BeforeEach(func() {
   804  								_, err := buffer.Write([]byte("n\n"))
   805  								Expect(err).ToNot(HaveOccurred())
   806  							})
   807  
   808  							It("does not install the plugin", func() {
   809  								session := helpers.CFWithStdin(buffer, "install-plugin", "some-plugin", "-k")
   810  
   811  								Eventually(session).Should(Say(`Do you want to install the plugin some-plugin\? \[yN\]: n`))
   812  								Eventually(session).Should(Say("Plugin installation cancelled"))
   813  
   814  								Eventually(session).Should(Exit(0))
   815  							})
   816  						})
   817  					})
   818  
   819  					When("the plugin is already installed", func() {
   820  						BeforeEach(func() {
   821  							pluginPath := helpers.BuildConfigurablePlugin("configurable_plugin", "some-plugin", "1.0.0",
   822  								[]helpers.PluginCommand{
   823  									{Name: "some-command", Help: "some-command-help"},
   824  								},
   825  							)
   826  							Eventually(helpers.CF("install-plugin", pluginPath, "-f", "-k")).Should(Exit(0))
   827  						})
   828  
   829  						When("the user says yes", func() {
   830  							BeforeEach(func() {
   831  								_, err := buffer.Write([]byte("y\n"))
   832  								Expect(err).ToNot(HaveOccurred())
   833  							})
   834  
   835  							When("the checksum is valid", func() {
   836  								It("installs the plugin", func() {
   837  									session := helpers.CFWithStdin(buffer, "install-plugin", "some-plugin", "-k")
   838  
   839  									Eventually(session).Should(Say(`Searching kaka1, kaka2 for plugin some-plugin\.\.\.`))
   840  									Eventually(session).Should(Say(`Plugin some-plugin 1\.2\.3 found in: kaka1, kaka2`))
   841  									Eventually(session).Should(Say(`Plugin some-plugin 1\.0\.0 is already installed.`))
   842  									Eventually(session).Should(Say(`Attention: Plugins are binaries written by potentially untrusted authors\.`))
   843  									Eventually(session).Should(Say(`Install and use plugins at your own risk\.`))
   844  									Eventually(session).Should(Say(`Do you want to uninstall the existing plugin and install some-plugin 1\.2\.3\? \[yN\]: y`))
   845  									Eventually(session).Should(Say(`Starting download of plugin binary from repository kaka1\.\.\.`))
   846  									Eventually(session).Should(Say(`\d.* .*B / ?`))
   847  									Eventually(session).Should(Say(`Uninstalling existing plugin\.\.\.`))
   848  									Eventually(session).Should(Say("OK"))
   849  									Eventually(session).Should(Say(`Plugin some-plugin successfully uninstalled\.`))
   850  									Eventually(session).Should(Say(`Installing plugin some-plugin\.\.\.`))
   851  									Eventually(session).Should(Say("OK"))
   852  									Eventually(session).Should(Say(`Plugin some-plugin 1\.2\.3 successfully installed\.`))
   853  
   854  									Eventually(session).Should(Exit(0))
   855  								})
   856  							})
   857  						})
   858  
   859  						When("the user says no", func() {
   860  							BeforeEach(func() {
   861  								_, err := buffer.Write([]byte("n\n"))
   862  								Expect(err).ToNot(HaveOccurred())
   863  							})
   864  
   865  							It("does not install the plugin", func() {
   866  								session := helpers.CFWithStdin(buffer, "install-plugin", "some-plugin", "-k")
   867  
   868  								Eventually(session).Should(Say(`Searching kaka1, kaka2 for plugin some-plugin\.\.\.`))
   869  								Eventually(session).Should(Say(`Plugin some-plugin 1\.2\.3 found in: kaka1, kaka2`))
   870  								Eventually(session).Should(Say(`Plugin some-plugin 1\.0\.0 is already installed.`))
   871  								Eventually(session).Should(Say(`Attention: Plugins are binaries written by potentially untrusted authors\.`))
   872  								Eventually(session).Should(Say(`Install and use plugins at your own risk\.`))
   873  								Eventually(session).Should(Say(`Do you want to uninstall the existing plugin and install some-plugin 1\.2\.3\? \[yN\]: n`))
   874  								Eventually(session).Should(Say("Plugin installation cancelled"))
   875  
   876  								Eventually(session).Should(Exit(0))
   877  							})
   878  						})
   879  					})
   880  				})
   881  			})
   882  		})
   883  	})
   884  })