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