github.com/liamawhite/cli-with-i18n@v6.32.1-0.20171122084555-dede0a5c3448+incompatible/integration/plugin/add_plugin_repo_test.go (about)

     1  package plugin
     2  
     3  import (
     4  	"bytes"
     5  	"encoding/json"
     6  	"fmt"
     7  	"log"
     8  	"net/http"
     9  
    10  	"github.com/liamawhite/cli-with-i18n/integration/helpers"
    11  	. "github.com/onsi/ginkgo"
    12  	. "github.com/onsi/gomega"
    13  	. "github.com/onsi/gomega/gbytes"
    14  	. "github.com/onsi/gomega/gexec"
    15  	. "github.com/onsi/gomega/ghttp"
    16  )
    17  
    18  var _ = Describe("add-plugin-repo command", func() {
    19  	Describe("help", func() {
    20  		Context("when --help flag is provided", func() {
    21  			It("displays command usage to output", func() {
    22  				session := helpers.CF("add-plugin-repo", "--help", "-k")
    23  
    24  				Eventually(session.Out).Should(Say("NAME:"))
    25  				Eventually(session.Out).Should(Say("add-plugin-repo - Add a new plugin repository"))
    26  				Eventually(session.Out).Should(Say("USAGE:"))
    27  				Eventually(session.Out).Should(Say("cf add-plugin-repo REPO_NAME URL"))
    28  				Eventually(session.Out).Should(Say("EXAMPLES"))
    29  				Eventually(session.Out).Should(Say("cf add-plugin-repo ExampleRepo https://example\\.com/repo"))
    30  				Eventually(session.Out).Should(Say("SEE ALSO:"))
    31  				Eventually(session.Out).Should(Say("install-plugin, list-plugin-repos"))
    32  				Eventually(session).Should(Exit(0))
    33  			})
    34  		})
    35  	})
    36  
    37  	Context("when the command line arguments are invalid", func() {
    38  		Context("when no arguments are provided", func() {
    39  			It("fails with incorrect usage message and displays help", func() {
    40  				session := helpers.CF("add-plugin-repo", "-k")
    41  
    42  				Eventually(session.Err).Should(Say("Incorrect Usage: the required arguments `REPO_NAME` and `URL` were not provided"))
    43  				Eventually(session.Out).Should(Say("USAGE:"))
    44  				Eventually(session).Should(Exit(1))
    45  			})
    46  		})
    47  
    48  		Context("when only one argument is provided", func() {
    49  			It("fails with incorrect usage message and displays help", func() {
    50  				session := helpers.CF("add-plugin-repo", "repo-name", "-k")
    51  
    52  				Eventually(session.Err).Should(Say("Incorrect Usage: the required argument `URL` was not provided"))
    53  				Eventually(session.Out).Should(Say("USAGE:"))
    54  				Eventually(session).Should(Exit(1))
    55  			})
    56  		})
    57  	})
    58  
    59  	Context("when the user provides a url without a protocol scheme", func() {
    60  		It("defaults to 'https://'", func() {
    61  			session := helpers.CF("add-plugin-repo", "some-repo", "example.com/repo", "-k")
    62  
    63  			Eventually(session.Err).Should(Say("Could not add repository 'some-repo' from https://example\\.com/repo:"))
    64  			Eventually(session).Should(Exit(1))
    65  		})
    66  	})
    67  
    68  	Context("when the provided URL is a valid plugin repository", func() {
    69  		var (
    70  			server     *Server
    71  			serverURL  string
    72  			pluginRepo helpers.PluginRepository
    73  		)
    74  
    75  		BeforeEach(func() {
    76  			pluginRepo = helpers.PluginRepository{
    77  				Plugins: []helpers.Plugin{},
    78  			}
    79  			server = helpers.NewPluginRepositoryTLSServer(pluginRepo)
    80  			serverURL = server.URL()
    81  		})
    82  
    83  		AfterEach(func() {
    84  			server.Close()
    85  		})
    86  
    87  		It("succeeds and exits 0", func() {
    88  			session := helpers.CF("add-plugin-repo", "repo1", serverURL, "-k")
    89  
    90  			Eventually(session.Out).Should(Say("%s added as repo1", serverURL))
    91  			Eventually(session).Should(Exit(0))
    92  		})
    93  
    94  		Context("when the repo URL is already in use", func() {
    95  			BeforeEach(func() {
    96  				Eventually(helpers.CF("add-plugin-repo", "repo1", serverURL, "-k")).Should(Exit(0))
    97  			})
    98  
    99  			It("allows the duplicate repo URL", func() {
   100  				session := helpers.CF("add-plugin-repo", "some-repo", serverURL, "-k")
   101  
   102  				Eventually(session.Out).Should(Say("%s added as some-repo", serverURL))
   103  				Eventually(session).Should(Exit(0))
   104  			})
   105  		})
   106  
   107  		Context("when the repo name is already in use", func() {
   108  			BeforeEach(func() {
   109  				Eventually(helpers.CF("add-plugin-repo", "repo1", serverURL, "-k")).Should(Exit(0))
   110  			})
   111  
   112  			Context("when the repo name is different only in case sensitivity", func() {
   113  				It("succeeds and exists 0", func() {
   114  					session := helpers.CF("add-plugin-repo", "rEPo1", serverURL, "-k")
   115  
   116  					Eventually(session.Out).Should(Say("%s already registered as repo1", serverURL))
   117  					Eventually(session).Should(Exit(0))
   118  				})
   119  			})
   120  
   121  			Context("when the URL is different", func() {
   122  				It("errors and says the repo name is taken", func() {
   123  					session := helpers.CF("add-plugin-repo", "repo1", "some-other-url", "-k")
   124  
   125  					Eventually(session.Err).Should(Say("Plugin repo named 'repo1' already exists, please use another name\\."))
   126  					Eventually(session).Should(Exit(1))
   127  				})
   128  			})
   129  
   130  			Context("when the URL is the same", func() {
   131  				It("succeeds and exits 0", func() {
   132  					session := helpers.CF("add-plugin-repo", "repo1", serverURL, "-k")
   133  
   134  					Eventually(session.Out).Should(Say("%s already registered as repo1", serverURL))
   135  					Eventually(session).Should(Exit(0))
   136  				})
   137  			})
   138  
   139  			Context("when the URL is the same except for a trailing '/'", func() {
   140  				It("succeeds and exits 0", func() {
   141  					session := helpers.CF("add-plugin-repo", "repo1", fmt.Sprintf("%s/", serverURL), "-k")
   142  
   143  					Eventually(session.Out).Should(Say("%s already registered as repo1", serverURL))
   144  					Eventually(session).Should(Exit(0))
   145  				})
   146  			})
   147  		})
   148  
   149  		Context("when the repo URL contains a path", func() {
   150  			BeforeEach(func() {
   151  				jsonBytes, err := json.Marshal(pluginRepo)
   152  				Expect(err).ToNot(HaveOccurred())
   153  
   154  				server.SetHandler(
   155  					0,
   156  					CombineHandlers(
   157  						VerifyRequest(http.MethodGet, "/some-path/list"),
   158  						RespondWith(http.StatusOK, jsonBytes),
   159  					),
   160  				)
   161  			})
   162  
   163  			Context("when the repo URL ends with /list", func() {
   164  				It("succeeds and exits 0", func() {
   165  					session := helpers.CF("add-plugin-repo", "some-repo", fmt.Sprintf("%s/some-path/list", serverURL), "-k")
   166  
   167  					Eventually(session.Out).Should(Say("%s/some-path/list added as some-repo", serverURL))
   168  					Eventually(session).Should(Exit(0))
   169  				})
   170  			})
   171  
   172  			Context("when the repo URL does not end with /list", func() {
   173  				It("succeeds and exits 0", func() {
   174  					session := helpers.CF("add-plugin-repo", "some-repo", fmt.Sprintf("%s/some-path", serverURL), "-k")
   175  
   176  					Eventually(session.Out).Should(Say("%s/some-path added as some-repo", serverURL))
   177  					Eventually(session).Should(Exit(0))
   178  				})
   179  			})
   180  
   181  			Context("when the repo URL ends with trailing /", func() {
   182  				It("succeeds and exits 0", func() {
   183  					session := helpers.CF("add-plugin-repo", "some-repo", fmt.Sprintf("%s/some-path/", serverURL), "-k")
   184  
   185  					Eventually(session.Out).Should(Say("%s/some-path/ added as some-repo", serverURL))
   186  					Eventually(session).Should(Exit(0))
   187  				})
   188  			})
   189  		})
   190  	})
   191  
   192  	Context("when the provided URL is NOT a valid plugin repository", func() {
   193  		var server *Server
   194  
   195  		BeforeEach(func() {
   196  			server = NewTLSServer()
   197  			// Suppresses ginkgo server logs
   198  			server.HTTPTestServer.Config.ErrorLog = log.New(&bytes.Buffer{}, "", 0)
   199  		})
   200  
   201  		AfterEach(func() {
   202  			server.Close()
   203  		})
   204  
   205  		Context("when the protocol is unsupported", func() {
   206  			It("reports an appropriate error", func() {
   207  				session := helpers.CF("add-plugin-repo", "repo1", "ftp://example.com/repo", "-k")
   208  
   209  				Eventually(session.Err).Should(Say("Could not add repository 'repo1' from ftp://example\\.com/repo: Get ftp://example\\.com/repo/list: unsupported protocol scheme \"ftp\""))
   210  				Eventually(session.Out).Should(Say("FAILED"))
   211  				Eventually(session).Should(Exit(1))
   212  			})
   213  		})
   214  
   215  		Context("when the domain cannot be reached", func() {
   216  			It("reports an appropriate error", func() {
   217  				session := helpers.CF("add-plugin-repo", "repo1", "cfpluginrepothatdoesnotexist.cf-app.com", "-k")
   218  
   219  				Eventually(session.Err).Should(Say("Could not add repository 'repo1' from https://cfpluginrepothatdoesnotexist\\.cf-app\\.com: Get https://cfpluginrepothatdoesnotexist\\.cf-app\\.com/list: dial tcp: lookup cfpluginrepothatdoesnotexist\\.cf-app\\.com.*: no such host"))
   220  				Eventually(session.Out).Should(Say("FAILED"))
   221  				Eventually(session).Should(Exit(1))
   222  			})
   223  		})
   224  
   225  		Context("when the path cannot be found", func() {
   226  			BeforeEach(func() {
   227  				server.AppendHandlers(
   228  					RespondWith(http.StatusNotFound, "foobar"),
   229  				)
   230  			})
   231  
   232  			It("returns an appropriate error", func() {
   233  				session := helpers.CF("add-plugin-repo", "repo1", server.URL(), "-k")
   234  
   235  				Eventually(session.Err).Should(Say("Could not add repository 'repo1' from https://127\\.0\\.0\\.1:\\d{1,5}"))
   236  				Eventually(session.Err).Should(Say("HTTP Response: 404"))
   237  				Eventually(session.Err).Should(Say("HTTP Response Body: foobar"))
   238  				Eventually(session.Out).Should(Say("FAILED"))
   239  				Eventually(session).Should(Exit(1))
   240  			})
   241  		})
   242  
   243  		Context("when the response is not parseable", func() {
   244  			BeforeEach(func() {
   245  				server.AppendHandlers(RespondWith(http.StatusOK, `{"plugins":[}`))
   246  			})
   247  
   248  			It("returns an appropriate error", func() {
   249  				session := helpers.CF("add-plugin-repo", "repo1", server.URL(), "-k")
   250  
   251  				Eventually(session.Err).Should(Say("Could not add repository 'repo1' from https://127\\.0\\.0\\.1:\\d{1,5}: invalid character '}' looking for beginning of value"))
   252  				Eventually(session.Out).Should(Say("FAILED"))
   253  				Eventually(session).Should(Exit(1))
   254  			})
   255  		})
   256  	})
   257  })