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  }