github.com/loggregator/cli@v6.33.1-0.20180224010324-82334f081791+incompatible/cf/api/buildpacks_test.go (about) 1 package api_test 2 3 import ( 4 "net/http" 5 "net/http/httptest" 6 "time" 7 8 . "code.cloudfoundry.org/cli/cf/api" 9 "code.cloudfoundry.org/cli/cf/api/apifakes" 10 "code.cloudfoundry.org/cli/cf/configuration/coreconfig" 11 "code.cloudfoundry.org/cli/cf/errors" 12 "code.cloudfoundry.org/cli/cf/models" 13 "code.cloudfoundry.org/cli/cf/net" 14 "code.cloudfoundry.org/cli/cf/terminal/terminalfakes" 15 "code.cloudfoundry.org/cli/cf/trace/tracefakes" 16 testconfig "code.cloudfoundry.org/cli/util/testhelpers/configuration" 17 . "code.cloudfoundry.org/cli/util/testhelpers/matchers" 18 testnet "code.cloudfoundry.org/cli/util/testhelpers/net" 19 . "github.com/onsi/ginkgo" 20 . "github.com/onsi/gomega" 21 ) 22 23 var _ = Describe("Buildpacks repo", func() { 24 var ( 25 ts *httptest.Server 26 handler *testnet.TestHandler 27 config coreconfig.ReadWriter 28 repo BuildpackRepository 29 ) 30 31 BeforeEach(func() { 32 config = testconfig.NewRepositoryWithDefaults() 33 gateway := net.NewCloudControllerGateway(config, time.Now, new(terminalfakes.FakeUI), new(tracefakes.FakePrinter), "") 34 repo = NewCloudControllerBuildpackRepository(config, gateway) 35 }) 36 37 AfterEach(func() { 38 ts.Close() 39 }) 40 41 var setupTestServer = func(requests ...testnet.TestRequest) { 42 ts, handler = testnet.NewServer(requests) 43 config.SetAPIEndpoint(ts.URL) 44 } 45 46 It("lists buildpacks", func() { 47 setupTestServer( 48 apifakes.NewCloudControllerTestRequest(testnet.TestRequest{ 49 Method: "GET", 50 Path: "/v2/buildpacks", 51 Response: testnet.TestResponse{ 52 Status: http.StatusOK, 53 Body: `{ 54 "next_url": "/v2/buildpacks?page=2", 55 "resources": [ 56 { 57 "metadata": { 58 "guid": "buildpack1-guid" 59 }, 60 "entity": { 61 "name": "Buildpack1", 62 "position" : 1, 63 "filename" : "firstbp.zip" 64 } 65 } 66 ] 67 }`}}), 68 apifakes.NewCloudControllerTestRequest(testnet.TestRequest{ 69 Method: "GET", 70 Path: "/v2/buildpacks?page=2", 71 Response: testnet.TestResponse{ 72 Status: http.StatusOK, 73 Body: `{ 74 "resources": [ 75 { 76 "metadata": { 77 "guid": "buildpack2-guid" 78 }, 79 "entity": { 80 "name": "Buildpack2", 81 "position" : 2 82 } 83 } 84 ] 85 }`}, 86 })) 87 88 buildpacks := []models.Buildpack{} 89 err := repo.ListBuildpacks(func(b models.Buildpack) bool { 90 buildpacks = append(buildpacks, b) 91 return true 92 }) 93 94 one := 1 95 two := 2 96 Expect(buildpacks).To(ConsistOf([]models.Buildpack{ 97 { 98 GUID: "buildpack1-guid", 99 Name: "Buildpack1", 100 Position: &one, 101 Filename: "firstbp.zip", 102 }, 103 { 104 GUID: "buildpack2-guid", 105 Name: "Buildpack2", 106 Position: &two, 107 }, 108 })) 109 Expect(handler).To(HaveAllRequestsCalled()) 110 Expect(err).NotTo(HaveOccurred()) 111 }) 112 113 Describe("finding buildpacks by name", func() { 114 It("returns the buildpack with that name", func() { 115 setupTestServer(apifakes.NewCloudControllerTestRequest(testnet.TestRequest{ 116 Method: "GET", 117 Path: "/v2/buildpacks?q=name%3ABuildpack1", 118 Response: testnet.TestResponse{ 119 Status: http.StatusOK, 120 Body: `{"resources": [ 121 { 122 "metadata": { 123 "guid": "buildpack1-guid" 124 }, 125 "entity": { 126 "name": "Buildpack1", 127 "position": 10 128 } 129 } 130 ] 131 }`}})) 132 133 buildpack, apiErr := repo.FindByName("Buildpack1") 134 135 Expect(handler).To(HaveAllRequestsCalled()) 136 Expect(apiErr).NotTo(HaveOccurred()) 137 138 Expect(buildpack.Name).To(Equal("Buildpack1")) 139 Expect(buildpack.GUID).To(Equal("buildpack1-guid")) 140 Expect(*buildpack.Position).To(Equal(10)) 141 }) 142 143 It("returns a ModelNotFoundError when the buildpack is not found", func() { 144 setupTestServer(apifakes.NewCloudControllerTestRequest(testnet.TestRequest{ 145 Method: "GET", 146 Path: "/v2/buildpacks?q=name%3ABuildpack1", 147 Response: testnet.TestResponse{ 148 Status: http.StatusOK, 149 Body: `{"resources": []}`, 150 }, 151 })) 152 153 _, apiErr := repo.FindByName("Buildpack1") 154 Expect(handler).To(HaveAllRequestsCalled()) 155 Expect(apiErr.(*errors.ModelNotFoundError)).NotTo(BeNil()) 156 }) 157 }) 158 159 Describe("creating buildpacks", func() { 160 It("returns an error when the buildpack has an invalid name", func() { 161 setupTestServer(testnet.TestRequest{ 162 Method: "POST", 163 Path: "/v2/buildpacks", 164 Response: testnet.TestResponse{ 165 Status: http.StatusBadRequest, 166 Body: `{ 167 "code":290003, 168 "description":"Buildpack is invalid: [\"name name can only contain alphanumeric characters\"]", 169 "error_code":"CF-BuildpackInvalid" 170 }`, 171 }}) 172 173 one := 1 174 createdBuildpack, apiErr := repo.Create("name with space", &one, nil, nil) 175 Expect(apiErr).To(HaveOccurred()) 176 Expect(createdBuildpack).To(Equal(models.Buildpack{})) 177 Expect(apiErr.(errors.HTTPError).ErrorCode()).To(Equal("290003")) 178 Expect(apiErr.Error()).To(ContainSubstring("Buildpack is invalid")) 179 }) 180 181 It("sets the position flag when creating a buildpack", func() { 182 setupTestServer(apifakes.NewCloudControllerTestRequest(testnet.TestRequest{ 183 Method: "POST", 184 Path: "/v2/buildpacks", 185 Matcher: testnet.RequestBodyMatcher(`{"name":"my-cool-buildpack","position":999}`), 186 Response: testnet.TestResponse{ 187 Status: http.StatusCreated, 188 Body: `{ 189 "metadata": { 190 "guid": "my-cool-buildpack-guid" 191 }, 192 "entity": { 193 "name": "my-cool-buildpack", 194 "position":999 195 } 196 }`}, 197 })) 198 199 position := 999 200 created, apiErr := repo.Create("my-cool-buildpack", &position, nil, nil) 201 202 Expect(handler).To(HaveAllRequestsCalled()) 203 Expect(apiErr).NotTo(HaveOccurred()) 204 205 Expect(created.GUID).NotTo(BeNil()) 206 Expect("my-cool-buildpack").To(Equal(created.Name)) 207 Expect(999).To(Equal(*created.Position)) 208 }) 209 210 It("sets the enabled flag when creating a buildpack", func() { 211 setupTestServer(apifakes.NewCloudControllerTestRequest(testnet.TestRequest{ 212 Method: "POST", 213 Path: "/v2/buildpacks", 214 Matcher: testnet.RequestBodyMatcher(`{"name":"my-cool-buildpack","position":999, "enabled":true}`), 215 Response: testnet.TestResponse{ 216 Status: http.StatusCreated, 217 Body: `{ 218 "metadata": { 219 "guid": "my-cool-buildpack-guid" 220 }, 221 "entity": { 222 "name": "my-cool-buildpack", 223 "position":999, 224 "enabled":true 225 } 226 }`}, 227 })) 228 229 position := 999 230 enabled := true 231 created, apiErr := repo.Create("my-cool-buildpack", &position, &enabled, nil) 232 233 Expect(handler).To(HaveAllRequestsCalled()) 234 Expect(apiErr).NotTo(HaveOccurred()) 235 236 Expect(created.GUID).NotTo(BeNil()) 237 Expect(created.Name).To(Equal("my-cool-buildpack")) 238 Expect(999).To(Equal(*created.Position)) 239 }) 240 }) 241 242 It("deletes buildpacks", func() { 243 setupTestServer(apifakes.NewCloudControllerTestRequest(testnet.TestRequest{ 244 Method: "DELETE", 245 Path: "/v2/buildpacks/my-cool-buildpack-guid", 246 Response: testnet.TestResponse{ 247 Status: http.StatusNoContent, 248 }})) 249 250 err := repo.Delete("my-cool-buildpack-guid") 251 252 Expect(handler).To(HaveAllRequestsCalled()) 253 Expect(err).NotTo(HaveOccurred()) 254 }) 255 256 Describe("updating buildpacks", func() { 257 It("updates a buildpack's name, position and enabled flag", func() { 258 setupTestServer(apifakes.NewCloudControllerTestRequest(testnet.TestRequest{ 259 Method: "PUT", 260 Path: "/v2/buildpacks/my-cool-buildpack-guid", 261 Matcher: testnet.RequestBodyMatcher(`{"name":"my-cool-buildpack","position":555,"enabled":false}`), 262 Response: testnet.TestResponse{ 263 Status: http.StatusCreated, 264 Body: `{ 265 "metadata": { 266 "guid": "my-cool-buildpack-guid" 267 }, 268 "entity": { 269 "name": "my-cool-buildpack", 270 "position":555, 271 "enabled":false 272 } 273 }`}, 274 })) 275 276 position := 555 277 enabled := false 278 buildpack := models.Buildpack{ 279 Name: "my-cool-buildpack", 280 GUID: "my-cool-buildpack-guid", 281 Position: &position, 282 Enabled: &enabled, 283 } 284 285 updated, err := repo.Update(buildpack) 286 287 Expect(handler).To(HaveAllRequestsCalled()) 288 Expect(err).NotTo(HaveOccurred()) 289 Expect(updated).To(Equal(buildpack)) 290 }) 291 292 It("sets the locked attribute on the buildpack", func() { 293 setupTestServer(apifakes.NewCloudControllerTestRequest(testnet.TestRequest{ 294 Method: "PUT", 295 Path: "/v2/buildpacks/my-cool-buildpack-guid", 296 Matcher: testnet.RequestBodyMatcher(`{"name":"my-cool-buildpack","locked":true}`), 297 Response: testnet.TestResponse{ 298 Status: http.StatusCreated, 299 Body: `{ 300 301 "metadata": { 302 "guid": "my-cool-buildpack-guid" 303 }, 304 "entity": { 305 "name": "my-cool-buildpack", 306 "position":123, 307 "locked": true 308 } 309 }`}, 310 })) 311 312 locked := true 313 314 buildpack := models.Buildpack{ 315 Name: "my-cool-buildpack", 316 GUID: "my-cool-buildpack-guid", 317 Locked: &locked, 318 } 319 320 updated, err := repo.Update(buildpack) 321 322 Expect(handler).To(HaveAllRequestsCalled()) 323 Expect(err).NotTo(HaveOccurred()) 324 325 position := 123 326 Expect(updated).To(Equal(models.Buildpack{ 327 Name: "my-cool-buildpack", 328 GUID: "my-cool-buildpack-guid", 329 Position: &position, 330 Locked: &locked, 331 })) 332 }) 333 }) 334 })