configRepo = testconfig.NewRepositoryWithDefaults() gateway := net.NewCloudControllerGateway(configRepo, time.Now, &testterm.FakeUI{}) repo = NewCloudControllerServiceAuthTokenRepository(configRepo, gateway) }) AfterEach(func() { testServer.Close() }) Describe("Create", func() { It("creates a service auth token", func() { setupTestServer(testapi.NewCloudControllerTestRequest(testnet.TestRequest{ Method: "POST", Path: "/v2/service_auth_tokens", Matcher: testnet.RequestBodyMatcher(`{"label":"a label","provider":"a provider","token":"a token"}`), Response: testnet.TestResponse{Status: http.StatusCreated}, })) err := repo.Create(models.ServiceAuthTokenFields{ Label: "a label", Provider: "a provider", Token: "a token", }) Expect(testHandler).To(HaveAllRequestsCalled()) Expect(err).NotTo(HaveOccurred()) }) }) Describe("FindAll", func() {
_, apiErr := repo.FindByName("zone1", "") _, ok := apiErr.(*errors.ModelNotFoundError) Expect(ok).To(BeFalse()) Expect(handler).To(HaveAllRequestsCalled()) }) }) Describe("creating zones", func() { It("creates the zone with the given guid", func() { req := testapi.NewCloudControllerTestRequest(testnet.TestRequest{ Method: "POST", Path: "/v2/zones", Matcher: testnet.RequestBodyMatcher(`{ "name":"my-cool-zone", "priority":60, "description": "my-cool-description", "is_public":false, "organization_guid":"my-cool-zone-guid"}`), Response: testnet.TestResponse{Status: http.StatusCreated}, }) testserver, handler, repo := createZoneRepo(req) defer testserver.Close() params := defaultZoneParams() apiErr := repo.Create(params) Expect(handler).To(HaveAllRequestsCalled()) Expect(apiErr).NotTo(HaveOccurred()) }) It("returns an api error when the zone already exists", func() {
}`, }}) one := 1 createdBuildpack, apiErr := repo.Create("name with space", &one, nil, nil) Expect(apiErr).To(HaveOccurred()) Expect(createdBuildpack).To(Equal(models.Buildpack{})) Expect(apiErr.(errors.HttpError).ErrorCode()).To(Equal("290003")) Expect(apiErr.Error()).To(ContainSubstring("Buildpack is invalid")) }) It("sets the position flag when creating a buildpack", func() { setupTestServer(testapi.NewCloudControllerTestRequest(testnet.TestRequest{ Method: "POST", Path: "/v2/buildpacks", Matcher: testnet.RequestBodyMatcher(`{"name":"my-cool-buildpack","position":999}`), Response: testnet.TestResponse{ Status: http.StatusCreated, Body: `{ "metadata": { "guid": "my-cool-buildpack-guid" }, "entity": { "name": "my-cool-buildpack", "position":999 } }`}, })) position := 999 created, apiErr := repo.Create("my-cool-buildpack", &position, nil, nil)
Expect(handler).To(HaveAllRequestsCalled()) Expect(apiErr).NotTo(HaveOccurred()) app := models.Application{} app.Name = "my-cool-app" app.Guid = "my-cool-app-guid" Expect(createdApp).To(Equal(app)) }) It("makes the right request with empty zone", func() { createApplicationRequest_withEmptyZone := createApplicationRequest createApplicationRequest_withEmptyZone.Matcher = testnet.RequestBodyMatcher(`{ "name":"my-cool-app", "instances":3, "buildpack":"buildpack-url", "memory":2048, "disk_quota": 512, "space_guid":"some-space-guid", "stack_guid":"some-stack-guid", "command":"some-command" }`) ts, handler, repo := createAppRepo([]testnet.TestRequest{createApplicationRequest_withEmptyZone}) defer ts.Close() params := defaultAppParams() myZoneName := "" params.ZoneName = &myZoneName createdApp, apiErr := repo.Create(params) Expect(handler).To(HaveAllRequestsCalled()) Expect(apiErr).NotTo(HaveOccurred())
Expect(ok).To(BeFalse()) Expect(handler).To(HaveAllRequestsCalled()) }) }) Describe(".Create", func() { It("creates the org and sends only the org name if the quota flag is not provided", func() { org := models.Organization{ OrganizationFields: models.OrganizationFields{ Name: "my-org", }} req := testapi.NewCloudControllerTestRequest(testnet.TestRequest{ Method: "POST", Path: "/v2/organizations", Matcher: testnet.RequestBodyMatcher(`{"name":"my-org"}`), Response: testnet.TestResponse{Status: http.StatusCreated}, }) testserver, handler, repo := createOrganizationRepo(req) defer testserver.Close() apiErr := repo.Create(org) Expect(handler).To(HaveAllRequestsCalled()) Expect(apiErr).NotTo(HaveOccurred()) }) It("creates the org with the provided quota", func() { org := models.Organization{ OrganizationFields: models.OrganizationFields{ Name: "my-org",
_, apiErr := repo.FindByGuid("bogus-guid") Expect(handler).To(HaveAllRequestsCalled()) Expect(apiErr).To(HaveOccurred()) Expect(apiErr.Error()).To(Equal("Server error, status code: 404, error code: 270042, message: Service Broker bogus-guid not found")) }) }) Describe("Create", func() { It("creates the service broker with the given name, URL, username and password", func() { expectedReqBody := `{"name":"foobroker","broker_url":"http://example.com","auth_username":"******","auth_password":"******"}` req := testapi.NewCloudControllerTestRequest(testnet.TestRequest{ Method: "POST", Path: "/v2/service_brokers", Matcher: testnet.RequestBodyMatcher(expectedReqBody), Response: testnet.TestResponse{Status: http.StatusCreated}, }) ts, handler, repo := createServiceBrokerRepo(req) defer ts.Close() apiErr := repo.Create("foobroker", "http://example.com", "foouser", "password") Expect(handler).To(HaveAllRequestsCalled()) Expect(apiErr).NotTo(HaveOccurred()) }) }) Describe("Update", func() { It("updates the service broker with the given guid", func() {
Expect(quotas[0].Name).To(Equal("my-remote-quota")) Expect(quotas[0].MemoryLimit).To(Equal(int64(1024))) Expect(quotas[0].RoutesLimit).To(Equal(123)) Expect(quotas[0].ServicesLimit).To(Equal(321)) Expect(quotas[1].Guid).To(Equal("my-quota-guid2")) Expect(quotas[2].Guid).To(Equal("my-quota-guid3")) }) }) Describe("AssignQuotaToOrg", func() { It("sets the quota for an organization", func() { req := testapi.NewCloudControllerTestRequest(testnet.TestRequest{ Method: "PUT", Path: "/v2/organizations/my-org-guid", Matcher: testnet.RequestBodyMatcher(`{"quota_definition_guid":"my-quota-guid"}`), Response: testnet.TestResponse{Status: http.StatusCreated}, }) setupTestServer(req) err := repo.AssignQuotaToOrg("my-org-guid", "my-quota-guid") Expect(testHandler).To(HaveAllRequestsCalled()) Expect(err).NotTo(HaveOccurred()) }) }) Describe("Create", func() { It("creates a new quota with the given name", func() { req := testapi.NewCloudControllerTestRequest(testnet.TestRequest{ Method: "POST",
testconfig "github.com/nttlabs/cli/testhelpers/configuration" testnet "github.com/nttlabs/cli/testhelpers/net" testterm "github.com/nttlabs/cli/testhelpers/terminal" . "github.com/nttlabs/cli/cf/api/password" . "github.com/nttlabs/cli/testhelpers/matchers" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" ) var _ = Describe("CloudControllerPasswordRepository", func() { It("updates your password", func() { req := testapi.NewCloudControllerTestRequest(testnet.TestRequest{ Method: "PUT", Path: "/Users/my-user-guid/password", Matcher: testnet.RequestBodyMatcher(`{"password":"******","oldPassword":"******"}`), Response: testnet.TestResponse{Status: http.StatusOK}, }) passwordUpdateServer, handler, repo := createPasswordRepo(req) defer passwordUpdateServer.Close() apiErr := repo.UpdatePassword("old-password", "new-password") Expect(handler).To(HaveAllRequestsCalled()) Expect(apiErr).NotTo(HaveOccurred()) }) }) func createPasswordRepo(req testnet.TestRequest) (passwordServer *httptest.Server, handler *testnet.TestHandler, repo PasswordRepository) { passwordServer, handler = testnet.NewServer([]testnet.TestRequest{req})
err := repo.UnassignQuotaFromSpace("my-space-guid", "my-quota-guid") Expect(err).NotTo(HaveOccurred()) Expect(testHandler).To(HaveAllRequestsCalled()) }) }) Describe("Create", func() { It("creates a new quota with the given name", func() { req := testapi.NewCloudControllerTestRequest(testnet.TestRequest{ Method: "POST", Path: "/v2/space_quota_definitions", Matcher: testnet.RequestBodyMatcher(`{ "name": "not-so-strict", "non_basic_services_allowed": false, "total_services": 1, "total_routes": 12, "memory_limit": 123, "organization_guid": "my-org-guid" }`), Response: testnet.TestResponse{Status: http.StatusCreated}, }) setupTestServer(req) quota := models.SpaceQuota{ Name: "not-so-strict", ServicesLimit: 1, RoutesLimit: 12, MemoryLimit: 123, OrgGuid: "my-org-guid", } err := repo.Create(quota)
var listStagingRequest = testapi.NewCloudControllerTestRequest(testnet.TestRequest{ Method: "GET", Path: "/v2/config/environment_variable_groups/staging", Response: testnet.TestResponse{ Status: http.StatusOK, Body: `{ "abc": 123, "do-re-mi": "fa-sol-la-ti" }`, }, }) var setStagingRequest = testapi.NewCloudControllerTestRequest(testnet.TestRequest{ Method: "PUT", Path: "/v2/config/environment_variable_groups/staging", Matcher: testnet.RequestBodyMatcher(`{ "abc": "one-two-three", "def": 456 }`), }) var setRunningRequest = testapi.NewCloudControllerTestRequest(testnet.TestRequest{ Method: "PUT", Path: "/v2/config/environment_variable_groups/running", Matcher: testnet.RequestBodyMatcher(`{ "abc": "one-two-three", "def": 456 }`), })
}) It("returns a 'not found' response when the space doesn't exist in the given org", func() { testSpacesDidNotFindByNameWithOrg("another-org-guid", func(repo SpaceRepository, spaceName string) (models.Space, error) { return repo.FindByNameInOrg(spaceName, "another-org-guid") }, ) }) }) It("creates spaces", func() { request := testapi.NewCloudControllerTestRequest(testnet.TestRequest{ Method: "POST", Path: "/v2/spaces", Matcher: testnet.RequestBodyMatcher(`{"name":"space-name","organization_guid":"my-org-guid"}`), Response: testnet.TestResponse{Status: http.StatusCreated, Body: ` { "metadata": { "guid": "space-guid" }, "entity": { "name": "space-name" } }`}, }) ts, handler, repo := createSpacesRepo(request) defer ts.Close() space, apiErr := repo.Create("space-name", "my-org-guid")
AfterEach(func() { testServer.Close() }) setupTestServer := func(reqs ...testnet.TestRequest) { testServer, testHandler = testnet.NewServer(reqs) configRepo.SetApiEndpoint(testServer.URL) } Describe(".Create", func() { BeforeEach(func() { setupTestServer(testapi.NewCloudControllerTestRequest(testnet.TestRequest{ Method: "POST", Path: "/v2/service_plan_visibilities", Matcher: testnet.RequestBodyMatcher(`{"service_plan_guid":"service_plan_guid", "organization_guid":"org_guid"}`), Response: testnet.TestResponse{Status: http.StatusCreated}, })) }) It("creates a service plan visibility", func() { err := repo.Create("service_plan_guid", "org_guid") Expect(testHandler).To(HaveAllRequestsCalled()) Expect(err).NotTo(HaveOccurred()) }) }) Describe(".List", func() { BeforeEach(func() { setupTestServer(firstPlanVisibilityRequest, secondPlanVisibilityRequest)
It("returns the header content type", func() { Expect(headers).To(ContainSubstring("Content-Type")) Expect(headers).To(ContainSubstring("text/plain")) }) It("returns the body as a JSON-encoded string", func() { testassert.JSONStringEquals(body, expectedJSONResponse) }) }) Describe("POST requests", func() { BeforeEach(func() { req := testapi.NewCloudControllerTestRequest(testnet.TestRequest{ Method: "POST", Path: "/v2/endpoint", Matcher: testnet.RequestBodyMatcher(`{"key":"val"}`), Response: testnet.TestResponse{ Status: http.StatusOK, Body: expectedJSONResponse}, }) ts, handler := testnet.NewServer([]testnet.TestRequest{req}) defer ts.Close() deps := newCurlDependencies() deps.config.SetApiEndpoint(ts.URL) repo := NewCloudControllerCurlRepository(deps.config, deps.gateway) headers, body, apiErr = repo.Request("POST", "/v2/endpoint", "", `{"key":"val"}`) Expect(handler).To(HaveAllRequestsCalled()) })
} var matchResourceRequest = testnet.TestRequest{ Method: "PUT", Path: "/v2/resource_match", Matcher: testnet.RequestBodyMatcher(testnet.RemoveWhiteSpaceFromBody(`[ { "fn": "app.rb", "sha1": "2474735f5163ba7612ef641f438f4b5bee00127b", "size": 51 }, { "fn": "config.ru", "sha1": "f097424ce1fa66c6cb9f5e8a18c317376ec12e05", "size": 70 }, { "fn": "Gemfile", "sha1": "d9c3a51de5c89c11331d3b90b972789f1a14699a", "size": 59 }, { "fn": "Gemfile.lock", "sha1": "345f999aef9070fb9a608e65cf221b7038156b6d", "size": 229 } ]`)), Response: testnet.TestResponse{ Status: http.StatusOK, Body: matchedResources, }, }
Expect(servicePlansFields[0].Active).To(BeTrue()) Expect(servicePlansFields[1].Name).To(Equal("The small second")) Expect(servicePlansFields[1].Guid).To(Equal("the-small-second")) Expect(servicePlansFields[1].Free).To(BeTrue()) Expect(servicePlansFields[1].Public).To(BeFalse()) Expect(servicePlansFields[1].Active).To(BeFalse()) }) }) }) Describe(".Update", func() { BeforeEach(func() { setupTestServer(testapi.NewCloudControllerTestRequest(testnet.TestRequest{ Method: "PUT", Path: "/v2/service_plans/my-service-plan-guid", Matcher: testnet.RequestBodyMatcher(`{"name":"my-service-plan", "free":true, "description":"descriptive text", "public":true, "service_guid":"service-guid"}`), Response: testnet.TestResponse{Status: http.StatusCreated}, })) }) It("Updates the service to public", func() { servicePlan := models.ServicePlanFields{ Name: "my-service-plan", Guid: "my-service-plan-guid", Description: "descriptive text", Free: true, Public: false, } err := repo.Update(servicePlan, "service-guid", true) Expect(testHandler).To(HaveAllRequestsCalled())
Expect(err).NotTo(HaveOccurred()) Expect(testHandler).To(HaveAllRequestsCalled()) Expect(len(services)).To(Equal(2)) Expect(services[0].Guid).To(Equal("my-service-guid")) Expect(services[1].Guid).To(Equal("my-service-guid2")) }) }) Describe("creating a service instance", func() { It("makes the right request", func() { setupTestServer(testapi.NewCloudControllerTestRequest(testnet.TestRequest{ Method: "POST", Path: "/v2/service_instances", Matcher: testnet.RequestBodyMatcher(`{"name":"instance-name","service_plan_guid":"plan-guid","space_guid":"my-space-guid","async":true}`), Response: testnet.TestResponse{Status: http.StatusCreated}, })) err := repo.CreateServiceInstance("instance-name", "plan-guid") Expect(testHandler).To(HaveAllRequestsCalled()) Expect(err).NotTo(HaveOccurred()) }) Context("when the name is taken but an identical service exists", func() { BeforeEach(func() { setupTestServer( testapi.NewCloudControllerTestRequest(testnet.TestRequest{ Method: "POST", Path: "/v2/service_instances", Matcher: testnet.RequestBodyMatcher(`{"name":"my-service","service_plan_guid":"plan-guid","space_guid":"my-space-guid","async":true}`),
}`}})) _, apiErr := repo.FindByNameInOrg("domain2.cf-app.com", "my-org-guid") Expect(handler).To(HaveAllRequestsCalled()) Expect(apiErr.(*errors.ModelNotFoundError)).NotTo(BeNil()) }) }) Describe("creating domains", func() { Context("when the private domains endpoint is not available", func() { BeforeEach(func() { setupTestServer( testapi.NewCloudControllerTestRequest(testnet.TestRequest{ Method: "POST", Path: "/v2/domains", Matcher: testnet.RequestBodyMatcher(`{"name":"example.com","owning_organization_guid":"org-guid", "wildcard": true}`), Response: testnet.TestResponse{Status: http.StatusCreated, Body: ` { "metadata": { "guid": "abc-123" }, "entity": { "name": "example.com" } }`}, }), ) }) It("uses the general domains endpoint", func() { createdDomain, apiErr := repo.Create("example.com", "org-guid") Expect(handler).To(HaveAllRequestsCalled()) Expect(apiErr).NotTo(HaveOccurred()) Expect(createdDomain.Guid).To(Equal("abc-123"))
})) _, err := repo.FindByUsername("my-user") Expect(uaaHandler).To(HaveAllRequestsCalled()) Expect(err).To(BeAssignableToTypeOf(&errors.ModelNotFoundError{})) }) }) }) Describe("creating users", func() { It("it creates users using the UAA /Users endpoint", func() { setupCCServer( testapi.NewCloudControllerTestRequest(testnet.TestRequest{ Method: "POST", Path: "/v2/users", Matcher: testnet.RequestBodyMatcher(`{"guid":"my-user-guid"}`), Response: testnet.TestResponse{Status: http.StatusCreated}, })) setupUAAServer( testapi.NewCloudControllerTestRequest(testnet.TestRequest{ Method: "POST", Path: "/Users", Matcher: testnet.RequestBodyMatcher(`{ "userName":"******", "emails":[{"value":"my-user"}], "password":"******", "name":{ "givenName":"my-user", "familyName":"my-user"} }`),
gateway := net.NewCloudControllerGateway(configRepo, time.Now, &testterm.FakeUI{}) repo = NewCloudControllerServiceBindingRepository(configRepo, gateway) }) AfterEach(func() { testServer.Close() }) Describe("Create", func() { Context("when the service binding can be created", func() { BeforeEach(func() { setupTestServer(testapi.NewCloudControllerTestRequest(testnet.TestRequest{ Method: "POST", Path: "/v2/service_bindings", Matcher: testnet.RequestBodyMatcher(`{"app_guid":"my-app-guid","service_instance_guid":"my-service-instance-guid","async":true}`), Response: testnet.TestResponse{Status: http.StatusCreated}, })) }) It("creates the service binding", func() { apiErr := repo.Create("my-service-instance-guid", "my-app-guid") Expect(testHandler).To(HaveAllRequestsCalled()) Expect(apiErr).NotTo(HaveOccurred()) }) }) Context("when an error occurs", func() { BeforeEach(func() { setupTestServer(testapi.NewCloudControllerTestRequest(testnet.TestRequest{
_, apiErr := repo.FindByHostAndDomain("my-cool-app", domain) Expect(handler).To(HaveAllRequestsCalled()) Expect(apiErr.(*errors.ModelNotFoundError)).NotTo(BeNil()) }) }) Describe("Create routes", func() { It("creates routes in a given space", func() { ts, handler = testnet.NewServer([]testnet.TestRequest{ testapi.NewCloudControllerTestRequest(testnet.TestRequest{ Method: "POST", Path: "/v2/routes?inline-relations-depth=1", Matcher: testnet.RequestBodyMatcher(`{"host":"my-cool-app","domain_guid":"my-domain-guid","space_guid":"my-space-guid"}`), Response: testnet.TestResponse{Status: http.StatusCreated, Body: ` { "metadata": { "guid": "my-route-guid" }, "entity": { "host": "my-cool-app" } } `}, }), }) configRepo.SetApiEndpoint(ts.URL) createdRoute, apiErr := repo.CreateInSpace("my-cool-app", "my-domain-guid", "my-space-guid") Expect(handler).To(HaveAllRequestsCalled()) Expect(apiErr).NotTo(HaveOccurred()) Expect(createdRoute.Guid).To(Equal("my-route-guid"))
testServer.Close() }) setupTestServer := func(reqs ...testnet.TestRequest) { testServer, testHandler = testnet.NewServer(reqs) configRepo.SetApiEndpoint(testServer.URL) } Describe(".Create", func() { It("can create an app security group, given some attributes", func() { req := testapi.NewCloudControllerTestRequest(testnet.TestRequest{ Method: "POST", Path: "/v2/security_groups", // FIXME: this matcher depend on the order of the key/value pairs in the map Matcher: testnet.RequestBodyMatcher(`{ "name": "mygroup", "rules": [{"my-house": "my-rules"}] }`), Response: testnet.TestResponse{Status: http.StatusCreated}, }) setupTestServer(req) err := repo.Create( "mygroup", []map[string]interface{}{{"my-house": "my-rules"}}, ) Expect(err).NotTo(HaveOccurred()) Expect(testHandler).To(HaveAllRequestsCalled()) }) })
testconfig "github.com/nttlabs/cli/testhelpers/configuration" testnet "github.com/nttlabs/cli/testhelpers/net" testterm "github.com/nttlabs/cli/testhelpers/terminal" . "github.com/nttlabs/cli/cf/api" . "github.com/nttlabs/cli/testhelpers/matchers" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" ) var _ = Describe("UserProvidedServiceRepository", func() { It("creates a user provided service with a name and credentials", func() { req := testapi.NewCloudControllerTestRequest(testnet.TestRequest{ Method: "POST", Path: "/v2/user_provided_service_instances", Matcher: testnet.RequestBodyMatcher(`{"name":"my-custom-service","credentials":{"host":"example.com","password":"******","user":"******"},"space_guid":"my-space-guid","syslog_drain_url":""}`), Response: testnet.TestResponse{Status: http.StatusCreated}, }) ts, handler, repo := createUserProvidedServiceInstanceRepo(req) defer ts.Close() apiErr := repo.Create("my-custom-service", "", map[string]interface{}{ "host": "example.com", "user": "******", "password": "******", }) Expect(handler).To(HaveAllRequestsCalled()) Expect(apiErr).NotTo(HaveOccurred()) })
BeforeEach(func() { configRepo = testconfig.NewRepositoryWithDefaults() gateway := net.NewCloudControllerGateway(configRepo, time.Now, &testterm.FakeUI{}) repo = NewCloudControllerCopyApplicationSourceRepository(configRepo, gateway) }) AfterEach(func() { testServer.Close() }) Describe(".CopyApplication", func() { BeforeEach(func() { setupTestServer(testapi.NewCloudControllerTestRequest(testnet.TestRequest{ Method: "POST", Path: "/v2/apps/target-app-guid/copy_bits", Matcher: testnet.RequestBodyMatcher(`{ "source_app_guid": "source-app-guid" }`), Response: testnet.TestResponse{ Status: http.StatusCreated, }, })) }) It("should return a CopyApplicationModel", func() { err := repo.CopyApplication("source-app-guid", "target-app-guid") Expect(err).ToNot(HaveOccurred()) }) }) })