github.com/asifdxtreme/cli@v6.1.3-0.20150123051144-9ead8700b4ae+incompatible/cf/api/spaces/spaces_test.go (about) 1 package spaces_test 2 3 import ( 4 "fmt" 5 "net/http" 6 "net/http/httptest" 7 "time" 8 9 testapi "github.com/cloudfoundry/cli/cf/api/fakes" 10 "github.com/cloudfoundry/cli/cf/errors" 11 "github.com/cloudfoundry/cli/cf/models" 12 "github.com/cloudfoundry/cli/cf/net" 13 testconfig "github.com/cloudfoundry/cli/testhelpers/configuration" 14 testnet "github.com/cloudfoundry/cli/testhelpers/net" 15 testterm "github.com/cloudfoundry/cli/testhelpers/terminal" 16 17 . "github.com/cloudfoundry/cli/cf/api/spaces" 18 . "github.com/cloudfoundry/cli/testhelpers/matchers" 19 . "github.com/onsi/ginkgo" 20 . "github.com/onsi/gomega" 21 ) 22 23 var _ = Describe("Space Repository", func() { 24 It("lists all the spaces", func() { 25 firstPageSpacesRequest := testapi.NewCloudControllerTestRequest(testnet.TestRequest{ 26 Method: "GET", 27 Path: "/v2/organizations/my-org-guid/spaces?inline-relations-depth=1", 28 Response: testnet.TestResponse{ 29 Status: http.StatusOK, 30 Body: ` 31 { 32 "next_url": "/v2/organizations/my-org-guid/spaces?inline-relations-depth=1&page=2", 33 "resources": [ 34 { 35 "metadata": { 36 "guid": "acceptance-space-guid" 37 }, 38 "entity": { 39 "name": "acceptance", 40 "security_groups": [ 41 { 42 "metadata": { 43 "guid": "4302b3b4-4afc-4f12-ae6d-ed1bb815551f" 44 }, 45 "entity": { 46 "name": "imma-security-group" 47 } 48 } 49 ] 50 } 51 } 52 ] 53 }`}}) 54 55 secondPageSpacesRequest := testapi.NewCloudControllerTestRequest(testnet.TestRequest{ 56 Method: "GET", 57 Path: "/v2/organizations/my-org-guid/spaces?inline-relations-depth=1&page=2", 58 Response: testnet.TestResponse{ 59 Status: http.StatusOK, 60 Body: ` 61 { 62 "resources": [ 63 { 64 "metadata": { 65 "guid": "staging-space-guid" 66 }, 67 "entity": { 68 "name": "staging", 69 "security_groups": [] 70 } 71 } 72 ] 73 }`}}) 74 75 ts, handler, repo := createSpacesRepo(firstPageSpacesRequest, secondPageSpacesRequest) 76 defer ts.Close() 77 78 spaces := []models.Space{} 79 apiErr := repo.ListSpaces(func(space models.Space) bool { 80 spaces = append(spaces, space) 81 return true 82 }) 83 84 Expect(len(spaces)).To(Equal(2)) 85 Expect(spaces[0].Guid).To(Equal("acceptance-space-guid")) 86 Expect(spaces[0].SecurityGroups[0].Name).To(Equal("imma-security-group")) 87 Expect(spaces[1].Guid).To(Equal("staging-space-guid")) 88 Expect(apiErr).NotTo(HaveOccurred()) 89 Expect(handler).To(HaveAllRequestsCalled()) 90 }) 91 92 Describe("finding spaces by name", func() { 93 It("returns the space", func() { 94 testSpacesFindByNameWithOrg("my-org-guid", 95 func(repo SpaceRepository, spaceName string) (models.Space, error) { 96 return repo.FindByName(spaceName) 97 }, 98 ) 99 }) 100 101 It("can find spaces in a particular org", func() { 102 testSpacesFindByNameWithOrg("another-org-guid", 103 func(repo SpaceRepository, spaceName string) (models.Space, error) { 104 return repo.FindByNameInOrg(spaceName, "another-org-guid") 105 }, 106 ) 107 }) 108 109 It("returns a 'not found' response when the space doesn't exist", func() { 110 testSpacesDidNotFindByNameWithOrg("my-org-guid", 111 func(repo SpaceRepository, spaceName string) (models.Space, error) { 112 return repo.FindByName(spaceName) 113 }, 114 ) 115 }) 116 117 It("returns a 'not found' response when the space doesn't exist in the given org", func() { 118 testSpacesDidNotFindByNameWithOrg("another-org-guid", 119 func(repo SpaceRepository, spaceName string) (models.Space, error) { 120 return repo.FindByNameInOrg(spaceName, "another-org-guid") 121 }, 122 ) 123 }) 124 }) 125 126 It("creates spaces without a space-quota", func() { 127 request := testapi.NewCloudControllerTestRequest(testnet.TestRequest{ 128 Method: "POST", 129 Path: "/v2/spaces", 130 Matcher: testnet.RequestBodyMatcher(`{"name":"space-name","organization_guid":"my-org-guid"}`), 131 Response: testnet.TestResponse{Status: http.StatusCreated, Body: ` 132 { 133 "metadata": { 134 "guid": "space-guid" 135 }, 136 "entity": { 137 "name": "space-name" 138 } 139 }`}, 140 }) 141 142 ts, handler, repo := createSpacesRepo(request) 143 defer ts.Close() 144 145 space, apiErr := repo.Create("space-name", "my-org-guid", "") 146 Expect(handler).To(HaveAllRequestsCalled()) 147 Expect(apiErr).NotTo(HaveOccurred()) 148 Expect(space.Guid).To(Equal("space-guid")) 149 Expect(space.SpaceQuotaGuid).To(Equal("")) 150 }) 151 152 It("creates spaces with a space-quota", func() { 153 request := testapi.NewCloudControllerTestRequest(testnet.TestRequest{ 154 Method: "POST", 155 Path: "/v2/spaces", 156 Matcher: testnet.RequestBodyMatcher(`{"name":"space-name","organization_guid":"my-org-guid","space_quota_definition_guid":"space-quota-guid"}`), 157 Response: testnet.TestResponse{Status: http.StatusCreated, Body: ` 158 { 159 "metadata": { 160 "guid": "space-guid" 161 }, 162 "entity": { 163 "name": "space-name", 164 "space_quota_definition_guid":"space-quota-guid" 165 } 166 }`}, 167 }) 168 169 ts, handler, repo := createSpacesRepo(request) 170 defer ts.Close() 171 172 space, apiErr := repo.Create("space-name", "my-org-guid", "space-quota-guid") 173 Expect(handler).To(HaveAllRequestsCalled()) 174 Expect(apiErr).NotTo(HaveOccurred()) 175 Expect(space.Guid).To(Equal("space-guid")) 176 Expect(space.SpaceQuotaGuid).To(Equal("space-quota-guid")) 177 }) 178 179 It("renames spaces", func() { 180 request := testapi.NewCloudControllerTestRequest(testnet.TestRequest{ 181 Method: "PUT", 182 Path: "/v2/spaces/my-space-guid", 183 Matcher: testnet.RequestBodyMatcher(`{"name":"new-space-name"}`), 184 Response: testnet.TestResponse{Status: http.StatusCreated}, 185 }) 186 187 ts, handler, repo := createSpacesRepo(request) 188 defer ts.Close() 189 190 apiErr := repo.Rename("my-space-guid", "new-space-name") 191 Expect(handler).To(HaveAllRequestsCalled()) 192 Expect(apiErr).NotTo(HaveOccurred()) 193 }) 194 195 It("deletes spaces", func() { 196 request := testapi.NewCloudControllerTestRequest(testnet.TestRequest{ 197 Method: "DELETE", 198 Path: "/v2/spaces/my-space-guid?recursive=true", 199 Response: testnet.TestResponse{Status: http.StatusOK}, 200 }) 201 202 ts, handler, repo := createSpacesRepo(request) 203 defer ts.Close() 204 205 apiErr := repo.Delete("my-space-guid") 206 Expect(handler).To(HaveAllRequestsCalled()) 207 Expect(apiErr).NotTo(HaveOccurred()) 208 }) 209 }) 210 211 func testSpacesFindByNameWithOrg(orgGuid string, findByName func(SpaceRepository, string) (models.Space, error)) { 212 findSpaceByNameResponse := testnet.TestResponse{ 213 Status: http.StatusOK, 214 Body: ` 215 { 216 "resources": [ 217 { 218 "metadata": { 219 "guid": "space1-guid" 220 }, 221 "entity": { 222 "name": "Space1", 223 "organization_guid": "org1-guid", 224 "organization": { 225 "metadata": { 226 "guid": "org1-guid" 227 }, 228 "entity": { 229 "name": "Org1" 230 } 231 }, 232 "apps": [ 233 { 234 "metadata": { 235 "guid": "app1-guid" 236 }, 237 "entity": { 238 "name": "app1" 239 } 240 }, 241 { 242 "metadata": { 243 "guid": "app2-guid" 244 }, 245 "entity": { 246 "name": "app2" 247 } 248 } 249 ], 250 "domains": [ 251 { 252 "metadata": { 253 "guid": "domain1-guid" 254 }, 255 "entity": { 256 "name": "domain1" 257 } 258 } 259 ], 260 "service_instances": [ 261 { 262 "metadata": { 263 "guid": "service1-guid" 264 }, 265 "entity": { 266 "name": "service1" 267 } 268 } 269 ] 270 } 271 } 272 ] 273 }`} 274 request := testapi.NewCloudControllerTestRequest(testnet.TestRequest{ 275 Method: "GET", 276 Path: fmt.Sprintf("/v2/organizations/%s/spaces?q=name%%3Aspace1&inline-relations-depth=1", orgGuid), 277 Response: findSpaceByNameResponse, 278 }) 279 280 ts, handler, repo := createSpacesRepo(request) 281 defer ts.Close() 282 283 space, apiErr := findByName(repo, "Space1") 284 Expect(handler).To(HaveAllRequestsCalled()) 285 Expect(apiErr).NotTo(HaveOccurred()) 286 Expect(space.Name).To(Equal("Space1")) 287 Expect(space.Guid).To(Equal("space1-guid")) 288 289 Expect(space.Organization.Guid).To(Equal("org1-guid")) 290 291 Expect(len(space.Applications)).To(Equal(2)) 292 Expect(space.Applications[0].Guid).To(Equal("app1-guid")) 293 Expect(space.Applications[1].Guid).To(Equal("app2-guid")) 294 295 Expect(len(space.Domains)).To(Equal(1)) 296 Expect(space.Domains[0].Guid).To(Equal("domain1-guid")) 297 298 Expect(len(space.ServiceInstances)).To(Equal(1)) 299 Expect(space.ServiceInstances[0].Guid).To(Equal("service1-guid")) 300 301 Expect(apiErr).NotTo(HaveOccurred()) 302 return 303 } 304 305 func testSpacesDidNotFindByNameWithOrg(orgGuid string, findByName func(SpaceRepository, string) (models.Space, error)) { 306 request := testapi.NewCloudControllerTestRequest(testnet.TestRequest{ 307 Method: "GET", 308 Path: fmt.Sprintf("/v2/organizations/%s/spaces?q=name%%3Aspace1&inline-relations-depth=1", orgGuid), 309 Response: testnet.TestResponse{ 310 Status: http.StatusOK, 311 Body: ` { "resources": [ ] }`, 312 }, 313 }) 314 315 ts, handler, repo := createSpacesRepo(request) 316 defer ts.Close() 317 318 _, apiErr := findByName(repo, "Space1") 319 Expect(handler).To(HaveAllRequestsCalled()) 320 321 Expect(apiErr.(*errors.ModelNotFoundError)).NotTo(BeNil()) 322 } 323 324 func createSpacesRepo(reqs ...testnet.TestRequest) (ts *httptest.Server, handler *testnet.TestHandler, repo SpaceRepository) { 325 ts, handler = testnet.NewServer(reqs) 326 configRepo := testconfig.NewRepositoryWithDefaults() 327 configRepo.SetApiEndpoint(ts.URL) 328 gateway := net.NewCloudControllerGateway(configRepo, time.Now, &testterm.FakeUI{}) 329 repo = NewCloudControllerSpaceRepository(configRepo, gateway) 330 return 331 }