github.com/jasonkeene/cli@v6.14.1-0.20160816203908-ca5715166dfb+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  	. "github.com/cloudfoundry/cli/cf/api"
     9  	"github.com/cloudfoundry/cli/cf/api/apifakes"
    10  	"github.com/cloudfoundry/cli/cf/configuration/coreconfig"
    11  	"github.com/cloudfoundry/cli/cf/errors"
    12  	"github.com/cloudfoundry/cli/cf/models"
    13  	"github.com/cloudfoundry/cli/cf/net"
    14  	"github.com/cloudfoundry/cli/cf/terminal/terminalfakes"
    15  	"github.com/cloudfoundry/cli/cf/trace/tracefakes"
    16  	testconfig "github.com/cloudfoundry/cli/testhelpers/configuration"
    17  	. "github.com/cloudfoundry/cli/testhelpers/matchers"
    18  	testnet "github.com/cloudfoundry/cli/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  })