github.com/loggregator/cli@v6.33.1-0.20180224010324-82334f081791+incompatible/cf/api/securitygroups/security_groups_test.go (about) 1 package securitygroups_test 2 3 import ( 4 "net/http" 5 "net/http/httptest" 6 "time" 7 8 "code.cloudfoundry.org/cli/cf/api/apifakes" 9 "code.cloudfoundry.org/cli/cf/configuration/coreconfig" 10 "code.cloudfoundry.org/cli/cf/errors" 11 "code.cloudfoundry.org/cli/cf/models" 12 "code.cloudfoundry.org/cli/cf/net" 13 "code.cloudfoundry.org/cli/cf/terminal/terminalfakes" 14 testconfig "code.cloudfoundry.org/cli/util/testhelpers/configuration" 15 testnet "code.cloudfoundry.org/cli/util/testhelpers/net" 16 17 . "code.cloudfoundry.org/cli/cf/api/securitygroups" 18 "code.cloudfoundry.org/cli/cf/trace/tracefakes" 19 . "code.cloudfoundry.org/cli/util/testhelpers/matchers" 20 . "github.com/onsi/ginkgo" 21 . "github.com/onsi/gomega" 22 ) 23 24 var _ = Describe("app security group api", func() { 25 var ( 26 testServer *httptest.Server 27 testHandler *testnet.TestHandler 28 configRepo coreconfig.ReadWriter 29 repo SecurityGroupRepo 30 ) 31 32 BeforeEach(func() { 33 configRepo = testconfig.NewRepositoryWithDefaults() 34 gateway := net.NewCloudControllerGateway(configRepo, time.Now, new(terminalfakes.FakeUI), new(tracefakes.FakePrinter), "") 35 repo = NewSecurityGroupRepo(configRepo, gateway) 36 }) 37 38 AfterEach(func() { 39 testServer.Close() 40 }) 41 42 setupTestServer := func(reqs ...testnet.TestRequest) { 43 testServer, testHandler = testnet.NewServer(reqs) 44 configRepo.SetAPIEndpoint(testServer.URL) 45 } 46 47 Describe(".Create", func() { 48 It("can create an app security group, given some attributes", func() { 49 req := apifakes.NewCloudControllerTestRequest(testnet.TestRequest{ 50 Method: "POST", 51 Path: "/v2/security_groups", 52 // FIXME: this matcher depend on the order of the key/value pairs in the map 53 Matcher: testnet.RequestBodyMatcher(`{ 54 "name": "mygroup", 55 "rules": [{"my-house": "my-rules"}] 56 }`), 57 Response: testnet.TestResponse{Status: http.StatusCreated}, 58 }) 59 setupTestServer(req) 60 61 err := repo.Create( 62 "mygroup", 63 []map[string]interface{}{{"my-house": "my-rules"}}, 64 ) 65 66 Expect(err).NotTo(HaveOccurred()) 67 Expect(testHandler).To(HaveAllRequestsCalled()) 68 }) 69 }) 70 71 Describe(".Read", func() { 72 It("returns the app security group with the given name", func() { 73 74 req1 := testnet.TestRequest{ 75 Method: "GET", 76 Path: "/v2/security_groups?q=name:the-name", 77 Response: testnet.TestResponse{ 78 Status: http.StatusOK, 79 Body: ` 80 { 81 "resources": [ 82 { 83 "metadata": { 84 "guid": "the-group-guid" 85 }, 86 "entity": { 87 "name": "the-name", 88 "rules": [{"key": "value"}], 89 "spaces_url": "/v2/security_groups/guid-id/spaces" 90 } 91 } 92 ] 93 } 94 `, 95 }, 96 } 97 98 req2 := testnet.TestRequest{ 99 Method: "GET", 100 Path: "/v2/security_groups/guid-id/spaces?inline-relations-depth=1", 101 Response: testnet.TestResponse{ 102 Status: http.StatusOK, 103 Body: ` 104 { 105 "resources": [ 106 { 107 "metadata":{ 108 "guid": "my-space-guid" 109 }, 110 "entity": { 111 "name": "my-space", 112 "organization": { 113 "metadata": { 114 "guid": "my-org-guid" 115 }, 116 "entity": { 117 "name": "my-org" 118 } 119 } 120 } 121 }, 122 { 123 "metadata":{ 124 "guid": "my-space-guid2" 125 }, 126 "entity": { 127 "name": "my-space2", 128 "organization": { 129 "metadata": { 130 "guid": "my-org-guid2" 131 }, 132 "entity": { 133 "name": "my-org2" 134 } 135 } 136 } 137 } 138 ] 139 } 140 `, 141 }, 142 } 143 144 setupTestServer(apifakes.NewCloudControllerTestRequest(req1), apifakes.NewCloudControllerTestRequest(req2)) 145 146 group, err := repo.Read("the-name") 147 148 Expect(err).ToNot(HaveOccurred()) 149 Expect(testHandler).To(HaveAllRequestsCalled()) 150 Expect(group).To(Equal(models.SecurityGroup{ 151 SecurityGroupFields: models.SecurityGroupFields{ 152 Name: "the-name", 153 GUID: "the-group-guid", 154 SpaceURL: "/v2/security_groups/guid-id/spaces", 155 Rules: []map[string]interface{}{{"key": "value"}}, 156 }, 157 Spaces: []models.Space{ 158 { 159 SpaceFields: models.SpaceFields{GUID: "my-space-guid", Name: "my-space"}, 160 Organization: models.OrganizationFields{GUID: "my-org-guid", Name: "my-org", QuotaDefinition: models.QuotaFields{AppInstanceLimit: -1}}, 161 }, 162 { 163 SpaceFields: models.SpaceFields{GUID: "my-space-guid2", Name: "my-space2"}, 164 Organization: models.OrganizationFields{GUID: "my-org-guid2", Name: "my-org2", QuotaDefinition: models.QuotaFields{AppInstanceLimit: -1}}, 165 }, 166 }, 167 })) 168 }) 169 170 It("returns a ModelNotFound error if the security group cannot be found", func() { 171 setupTestServer(apifakes.NewCloudControllerTestRequest(testnet.TestRequest{ 172 Method: "GET", 173 Path: "/v2/security_groups?q=name:the-name", 174 Response: testnet.TestResponse{ 175 Status: http.StatusOK, 176 Body: `{"resources": []}`, 177 }, 178 })) 179 180 _, err := repo.Read("the-name") 181 182 Expect(err).To(HaveOccurred()) 183 Expect(err).To(BeAssignableToTypeOf(errors.NewModelNotFoundError("model-type", "description"))) 184 }) 185 }) 186 187 Describe(".Delete", func() { 188 It("deletes the security group", func() { 189 securityGroupGUID := "the-security-group-guid" 190 setupTestServer(apifakes.NewCloudControllerTestRequest(testnet.TestRequest{ 191 Method: "DELETE", 192 Path: "/v2/security_groups/" + securityGroupGUID, 193 Response: testnet.TestResponse{ 194 Status: http.StatusNoContent, 195 }, 196 })) 197 198 err := repo.Delete(securityGroupGUID) 199 200 Expect(err).ToNot(HaveOccurred()) 201 }) 202 }) 203 204 Describe(".FindAll", func() { 205 It("returns all the security groups", func() { 206 setupTestServer( 207 apifakes.NewCloudControllerTestRequest(testnet.TestRequest{ 208 Method: "GET", 209 Path: "/v2/security_groups", 210 Response: testnet.TestResponse{ 211 Status: http.StatusOK, 212 Body: firstListItem(), 213 }, 214 }), 215 apifakes.NewCloudControllerTestRequest(testnet.TestRequest{ 216 Method: "GET", 217 Path: "/v2/security_groups?page=2", 218 Response: testnet.TestResponse{ 219 Status: http.StatusOK, 220 Body: secondListItem(), 221 }, 222 }), 223 apifakes.NewCloudControllerTestRequest(testnet.TestRequest{ 224 Method: "GET", 225 Path: "/v2/security_groups/cd186158-b356-474d-9861-724f34f48502/spaces?inline-relations-depth=1", 226 Response: testnet.TestResponse{ 227 Status: http.StatusOK, 228 Body: spacesItems(), 229 }, 230 }), 231 apifakes.NewCloudControllerTestRequest(testnet.TestRequest{ 232 Method: "GET", 233 Path: "/v2/security_groups/d3374b62-7eac-4823-afbd-460d2bf44c67/spaces?inline-relations-depth=1", 234 Response: testnet.TestResponse{ 235 Status: http.StatusOK, 236 Body: spacesItems(), 237 }, 238 }), 239 ) 240 241 groups, err := repo.FindAll() 242 243 Expect(err).ToNot(HaveOccurred()) 244 Expect(testHandler).To(HaveAllRequestsCalled()) 245 Expect(groups[0]).To(Equal(models.SecurityGroup{ 246 SecurityGroupFields: models.SecurityGroupFields{ 247 Name: "name-71", 248 GUID: "cd186158-b356-474d-9861-724f34f48502", 249 Rules: []map[string]interface{}{{"protocol": "udp"}}, 250 SpaceURL: "/v2/security_groups/cd186158-b356-474d-9861-724f34f48502/spaces", 251 }, 252 Spaces: []models.Space{ 253 { 254 SpaceFields: models.SpaceFields{GUID: "my-space-guid", Name: "my-space"}, 255 Organization: models.OrganizationFields{GUID: "my-org-guid", Name: "my-org", QuotaDefinition: models.QuotaFields{AppInstanceLimit: -1}}, 256 }, 257 }, 258 })) 259 Expect(groups[1]).To(Equal(models.SecurityGroup{ 260 SecurityGroupFields: models.SecurityGroupFields{ 261 Name: "name-72", 262 GUID: "d3374b62-7eac-4823-afbd-460d2bf44c67", 263 Rules: []map[string]interface{}{{"destination": "198.41.191.47/1"}}, 264 SpaceURL: "/v2/security_groups/d3374b62-7eac-4823-afbd-460d2bf44c67/spaces", 265 }, 266 Spaces: []models.Space{ 267 { 268 SpaceFields: models.SpaceFields{GUID: "my-space-guid", Name: "my-space"}, 269 Organization: models.OrganizationFields{GUID: "my-org-guid", Name: "my-org", QuotaDefinition: models.QuotaFields{AppInstanceLimit: -1}}, 270 }, 271 }, 272 })) 273 }) 274 }) 275 }) 276 277 func firstListItem() string { 278 return `{ 279 "next_url": "/v2/security_groups?inline-relations-depth=2&page=2", 280 "resources": [ 281 { 282 "metadata": { 283 "guid": "cd186158-b356-474d-9861-724f34f48502", 284 "url": "/v2/security_groups/cd186158-b356-474d-9861-724f34f48502", 285 "created_at": "2014-06-23T22:55:30+00:00", 286 "updated_at": null 287 }, 288 "entity": { 289 "name": "name-71", 290 "rules": [ 291 { 292 "protocol": "udp" 293 } 294 ], 295 "spaces_url": "/v2/security_groups/cd186158-b356-474d-9861-724f34f48502/spaces" 296 } 297 } 298 ] 299 }` 300 } 301 302 func secondListItem() string { 303 return `{ 304 "next_url": null, 305 "resources": [ 306 { 307 "metadata": { 308 "guid": "d3374b62-7eac-4823-afbd-460d2bf44c67", 309 "url": "/v2/security_groups/d3374b62-7eac-4823-afbd-460d2bf44c67", 310 "created_at": "2014-06-23T22:55:30+00:00", 311 "updated_at": null 312 }, 313 "entity": { 314 "name": "name-72", 315 "rules": [ 316 { 317 "destination": "198.41.191.47/1" 318 } 319 ], 320 "spaces": [ 321 { 322 "metadata":{ 323 "guid": "my-space-guid" 324 }, 325 "entity": { 326 "name": "my-space", 327 "organization": { 328 "metadata": { 329 "guid": "my-org-guid" 330 }, 331 "entity": { 332 "name": "my-org" 333 } 334 } 335 } 336 } 337 ], 338 "spaces_url": "/v2/security_groups/d3374b62-7eac-4823-afbd-460d2bf44c67/spaces" 339 } 340 } 341 ] 342 }` 343 } 344 345 func spacesItems() string { 346 return `{ 347 "resources": [ 348 { 349 "metadata":{ 350 "guid": "my-space-guid" 351 }, 352 "entity": { 353 "name": "my-space", 354 "organization": { 355 "metadata": { 356 "guid": "my-org-guid" 357 }, 358 "entity": { 359 "name": "my-org" 360 } 361 } 362 } 363 } 364 ] 365 }` 366 }