github.com/dcarley/cf-cli@v6.24.1-0.20170220111324-4225ff346898+incompatible/api/cloudcontroller/ccv2/application_test.go (about)

     1  package ccv2_test
     2  
     3  import (
     4  	"net/http"
     5  	"time"
     6  
     7  	"code.cloudfoundry.org/cli/api/cloudcontroller"
     8  	. "code.cloudfoundry.org/cli/api/cloudcontroller/ccv2"
     9  	. "github.com/onsi/ginkgo"
    10  	. "github.com/onsi/gomega"
    11  	. "github.com/onsi/gomega/ghttp"
    12  )
    13  
    14  var _ = Describe("Application", func() {
    15  	var client *Client
    16  
    17  	BeforeEach(func() {
    18  		client = NewTestClient()
    19  	})
    20  
    21  	Describe("GetApplication", func() {
    22  		BeforeEach(func() {
    23  			response := `{
    24  						"metadata": {
    25  							"guid": "app-guid-1",
    26  							"updated_at": null
    27  						},
    28  						"entity": {
    29  							"buildpack": "ruby 1.6.29",
    30  							"detected_start_command": "echo 'I am a banana'",
    31  							"disk_quota": 586,
    32  							"detected_buildpack": null,
    33  							"health_check_type": "port",
    34  							"health_check_http_endpoint": "/",
    35  							"instances": 13,
    36  							"memory": 1024,
    37  							"name": "app-name-1",
    38  							"package_state": "FAILED",
    39  							"package_updated_at": "2015-03-10T23:11:54Z",
    40  							"stack_guid": "some-stack-guid",
    41  							"staging_failed_reason": "some-reason",
    42  							"state": "STOPPED"
    43  						}
    44  			}`
    45  			server.AppendHandlers(
    46  				CombineHandlers(
    47  					VerifyRequest(http.MethodGet, "/v2/apps/app-guid-1"),
    48  					RespondWith(http.StatusOK, response, http.Header{"X-Cf-Warnings": {"this is a warning"}}),
    49  				),
    50  			)
    51  		})
    52  
    53  		Context("when apps exist", func() {
    54  			It("returns the app", func() {
    55  				app, warnings, err := client.GetApplication("app-guid-1")
    56  				Expect(err).NotTo(HaveOccurred())
    57  
    58  				updatedAt, err := time.Parse(time.RFC3339, "2015-03-10T23:11:54Z")
    59  				Expect(err).NotTo(HaveOccurred())
    60  
    61  				Expect(app).To(Equal(Application{
    62  					Buildpack:               "ruby 1.6.29",
    63  					DetectedBuildpack:       "",
    64  					DetectedStartCommand:    "echo 'I am a banana'",
    65  					DiskQuota:               586,
    66  					GUID:                    "app-guid-1",
    67  					HealthCheckType:         "port",
    68  					HealthCheckHTTPEndpoint: "/",
    69  					Instances:               13,
    70  					Memory:                  1024,
    71  					Name:                    "app-name-1",
    72  					PackageState:            ApplicationPackageFailed,
    73  					PackageUpdatedAt:        updatedAt,
    74  					StackGUID:               "some-stack-guid",
    75  					StagingFailedReason:     "some-reason",
    76  					State:                   ApplicationStopped,
    77  				}))
    78  				Expect(warnings).To(ConsistOf(Warnings{"this is a warning"}))
    79  			})
    80  		})
    81  	})
    82  
    83  	Describe("GetApplications", func() {
    84  		BeforeEach(func() {
    85  			response1 := `{
    86  				"next_url": "/v2/apps?q=space_guid:some-space-guid&page=2",
    87  				"resources": [
    88  					{
    89  						"metadata": {
    90  							"guid": "app-guid-1",
    91  							"updated_at": null
    92  						},
    93  						"entity": {
    94  							"buildpack": "ruby 1.6.29",
    95  							"detected_start_command": "echo 'I am a banana'",
    96  							"disk_quota": 586,
    97  							"detected_buildpack": null,
    98  							"health_check_type": "port",
    99  							"health_check_http_endpoint": "/",
   100  							"instances": 13,
   101  							"memory": 1024,
   102  							"name": "app-name-1",
   103  							"package_state": "FAILED",
   104  							"package_updated_at": "2015-03-10T23:11:54Z",
   105  							"stack_guid": "some-stack-guid",
   106  							"staging_failed_reason": "some-reason",
   107  							"state": "STOPPED"
   108  						}
   109  					},
   110  					{
   111  						"metadata": {
   112  							"guid": "app-guid-2",
   113  							"updated_at": null
   114  						},
   115  						"entity": {
   116  							"name": "app-name-2",
   117  							"detected_buildpack": "ruby 1.6.29",
   118  							"package_updated_at": null
   119  						}
   120  					}
   121  				]
   122  			}`
   123  			response2 := `{
   124  				"next_url": null,
   125  				"resources": [
   126  					{
   127  						"metadata": {
   128  							"guid": "app-guid-3",
   129  							"updated_at": null
   130  						},
   131  						"entity": {
   132  							"name": "app-name-3"
   133  						}
   134  					},
   135  					{
   136  						"metadata": {
   137  							"guid": "app-guid-4",
   138  							"updated_at": null
   139  						},
   140  						"entity": {
   141  							"name": "app-name-4"
   142  						}
   143  					}
   144  				]
   145  			}`
   146  			server.AppendHandlers(
   147  				CombineHandlers(
   148  					VerifyRequest(http.MethodGet, "/v2/apps", "q=space_guid:some-space-guid"),
   149  					RespondWith(http.StatusOK, response1, http.Header{"X-Cf-Warnings": {"this is a warning"}}),
   150  				),
   151  			)
   152  			server.AppendHandlers(
   153  				CombineHandlers(
   154  					VerifyRequest(http.MethodGet, "/v2/apps", "q=space_guid:some-space-guid&page=2"),
   155  					RespondWith(http.StatusOK, response2, http.Header{"X-Cf-Warnings": {"this is another warning"}}),
   156  				),
   157  			)
   158  		})
   159  
   160  		Context("when apps exist", func() {
   161  			It("returns all the queried apps", func() {
   162  				apps, warnings, err := client.GetApplications([]Query{{
   163  					Filter:   SpaceGUIDFilter,
   164  					Operator: EqualOperator,
   165  					Value:    "some-space-guid",
   166  				}})
   167  				Expect(err).NotTo(HaveOccurred())
   168  
   169  				updatedAt, err := time.Parse(time.RFC3339, "2015-03-10T23:11:54Z")
   170  				Expect(err).NotTo(HaveOccurred())
   171  
   172  				Expect(apps).To(ConsistOf([]Application{
   173  					{
   174  						Buildpack:               "ruby 1.6.29",
   175  						DetectedBuildpack:       "",
   176  						DetectedStartCommand:    "echo 'I am a banana'",
   177  						DiskQuota:               586,
   178  						GUID:                    "app-guid-1",
   179  						HealthCheckType:         "port",
   180  						HealthCheckHTTPEndpoint: "/",
   181  						Instances:               13,
   182  						Memory:                  1024,
   183  						Name:                    "app-name-1",
   184  						PackageState:            ApplicationPackageFailed,
   185  						PackageUpdatedAt:        updatedAt,
   186  						StackGUID:               "some-stack-guid",
   187  						StagingFailedReason:     "some-reason",
   188  						State:                   ApplicationStopped,
   189  					},
   190  					{Name: "app-name-2", GUID: "app-guid-2", DetectedBuildpack: "ruby 1.6.29"},
   191  					{Name: "app-name-3", GUID: "app-guid-3"},
   192  					{Name: "app-name-4", GUID: "app-guid-4"},
   193  				}))
   194  				Expect(warnings).To(ConsistOf(Warnings{"this is a warning", "this is another warning"}))
   195  			})
   196  		})
   197  	})
   198  
   199  	Describe("UpdateApplication", func() {
   200  		Context("when the update is successful", func() {
   201  			Context("when updating all fields", func() { //are we encoding everything correctly?
   202  				BeforeEach(func() {
   203  					response1 := `{
   204  				"metadata": {
   205  					"guid": "some-app-guid",
   206  					"updated_at": null
   207  				},
   208  				"entity": {
   209  					"buildpack": "ruby 1.6.29",
   210  					"detected_start_command": "echo 'I am a banana'",
   211  					"disk_quota": 586,
   212  					"detected_buildpack": null,
   213  					"health_check_type": "some-health-check-type",
   214  					"health_check_http_endpoint": "/anything",
   215  					"instances": 13,
   216  					"memory": 1024,
   217  					"name": "app-name-1",
   218  					"package_updated_at": "2015-03-10T23:11:54Z",
   219  					"stack_guid": "some-stack-guid",
   220  					"state": "STARTED"
   221  				}
   222  			}`
   223  					expectedBody := map[string]string{
   224  						"health_check_http_endpoint": "/anything",
   225  						"health_check_type":          "some-health-check-type",
   226  						"state":                      "STARTED",
   227  					}
   228  
   229  					server.AppendHandlers(
   230  						CombineHandlers(
   231  							VerifyRequest(http.MethodPut, "/v2/apps/some-app-guid"),
   232  							VerifyJSONRepresenting(expectedBody),
   233  							RespondWith(http.StatusCreated, response1, http.Header{"X-Cf-Warnings": {"this is a warning"}}),
   234  						),
   235  					)
   236  				})
   237  
   238  				It("returns the updated object and warnings and sends all updated field", func() {
   239  					app, warnings, err := client.UpdateApplication(Application{
   240  						GUID:                    "some-app-guid",
   241  						HealthCheckType:         "some-health-check-type",
   242  						HealthCheckHTTPEndpoint: "/anything",
   243  						State: ApplicationStarted,
   244  					})
   245  					Expect(err).NotTo(HaveOccurred())
   246  
   247  					updatedAt, err := time.Parse(time.RFC3339, "2015-03-10T23:11:54Z")
   248  					Expect(err).NotTo(HaveOccurred())
   249  
   250  					Expect(app).To(Equal(Application{
   251  						Buildpack:               "ruby 1.6.29",
   252  						DetectedBuildpack:       "",
   253  						DetectedStartCommand:    "echo 'I am a banana'",
   254  						DiskQuota:               586,
   255  						GUID:                    "some-app-guid",
   256  						HealthCheckType:         "some-health-check-type",
   257  						HealthCheckHTTPEndpoint: "/anything",
   258  						Instances:               13,
   259  						Memory:                  1024,
   260  						Name:                    "app-name-1",
   261  						PackageUpdatedAt:        updatedAt,
   262  						StackGUID:               "some-stack-guid",
   263  						State:                   ApplicationStarted,
   264  					}))
   265  					Expect(warnings).To(ConsistOf(Warnings{"this is a warning"}))
   266  				})
   267  			})
   268  
   269  			Context("when only updating one field", func() { // are we **only** encoding the things we want
   270  				BeforeEach(func() {
   271  					response1 := `{
   272  				"metadata": {
   273  					"guid": "some-app-guid",
   274  					"updated_at": null
   275  				},
   276  				"entity": {
   277  					"buildpack": "ruby 1.6.29",
   278  					"detected_start_command": "echo 'I am a banana'",
   279  					"disk_quota": 586,
   280  					"detected_buildpack": null,
   281  					"health_check_type": "some-health-check-type",
   282  					"health_check_http_endpoint": "/",
   283  					"instances": 13,
   284  					"memory": 1024,
   285  					"name": "app-name-1",
   286  					"package_updated_at": "2015-03-10T23:11:54Z",
   287  					"stack_guid": "some-stack-guid",
   288  					"state": "STOPPED"
   289  				}
   290  			}`
   291  					server.AppendHandlers(
   292  						CombineHandlers(
   293  							VerifyRequest(http.MethodPut, "/v2/apps/some-app-guid"),
   294  							VerifyBody([]byte(`{"health_check_type":"some-health-check-type"}`)),
   295  							RespondWith(http.StatusCreated, response1, http.Header{"X-Cf-Warnings": {"this is a warning"}}),
   296  						),
   297  					)
   298  				})
   299  
   300  				It("returns the updated object and warnings and sends only updated field", func() {
   301  					app, warnings, err := client.UpdateApplication(Application{
   302  						GUID:            "some-app-guid",
   303  						HealthCheckType: "some-health-check-type",
   304  					})
   305  					Expect(err).NotTo(HaveOccurred())
   306  
   307  					updatedAt, err := time.Parse(time.RFC3339, "2015-03-10T23:11:54Z")
   308  					Expect(err).NotTo(HaveOccurred())
   309  
   310  					Expect(app).To(Equal(Application{
   311  						Buildpack:               "ruby 1.6.29",
   312  						DetectedBuildpack:       "",
   313  						DetectedStartCommand:    "echo 'I am a banana'",
   314  						DiskQuota:               586,
   315  						GUID:                    "some-app-guid",
   316  						HealthCheckType:         "some-health-check-type",
   317  						HealthCheckHTTPEndpoint: "/",
   318  						Instances:               13,
   319  						Memory:                  1024,
   320  						Name:                    "app-name-1",
   321  						PackageUpdatedAt:        updatedAt,
   322  						StackGUID:               "some-stack-guid",
   323  						State:                   ApplicationStopped,
   324  					}))
   325  					Expect(warnings).To(ConsistOf(Warnings{"this is a warning"}))
   326  				})
   327  			})
   328  		})
   329  
   330  		Context("when the update returns an error", func() {
   331  			BeforeEach(func() {
   332  				response := `
   333  {
   334    "code": 210002,
   335    "description": "The app could not be found: some-app-guid",
   336    "error_code": "CF-AppNotFound"
   337  }
   338  			`
   339  				server.AppendHandlers(
   340  					CombineHandlers(
   341  						VerifyRequest(http.MethodPut, "/v2/apps/some-app-guid"),
   342  						// VerifyBody([]byte(`{"health_check_type":"some-health-check-type"}`)),
   343  						RespondWith(http.StatusNotFound, response, http.Header{"X-Cf-Warnings": {"this is a warning"}}),
   344  					),
   345  				)
   346  			})
   347  
   348  			It("returns the error and warnings", func() {
   349  				_, warnings, err := client.UpdateApplication(Application{
   350  					GUID:            "some-app-guid",
   351  					HealthCheckType: "some-health-check-type",
   352  				})
   353  				Expect(err).To(MatchError(cloudcontroller.ResourceNotFoundError{Message: "The app could not be found: some-app-guid"}))
   354  				Expect(warnings).To(ConsistOf(Warnings{"this is a warning"}))
   355  			})
   356  		})
   357  	})
   358  
   359  	Describe("GetRouteApplications", func() {
   360  		Context("when the route guid is not found", func() {
   361  			BeforeEach(func() {
   362  				response := `
   363  {
   364    "code": 210002,
   365    "description": "The route could not be found: some-route-guid",
   366    "error_code": "CF-RouteNotFound"
   367  }
   368  			`
   369  				server.AppendHandlers(
   370  					CombineHandlers(
   371  						VerifyRequest(http.MethodGet, "/v2/routes/some-route-guid/apps"),
   372  						RespondWith(http.StatusNotFound, response),
   373  					),
   374  				)
   375  			})
   376  
   377  			It("returns an error", func() {
   378  				_, _, err := client.GetRouteApplications("some-route-guid", nil)
   379  				Expect(err).To(MatchError(cloudcontroller.ResourceNotFoundError{
   380  					Message: "The route could not be found: some-route-guid",
   381  				}))
   382  			})
   383  		})
   384  
   385  		Context("when there are applications associated with this route", func() {
   386  			BeforeEach(func() {
   387  				response1 := `{
   388  				"next_url": "/v2/routes/some-route-guid/apps?q=space_guid:some-space-guid&page=2",
   389  				"resources": [
   390  					{
   391  						"metadata": {
   392  							"guid": "app-guid-1",
   393  							"updated_at": null
   394  						},
   395  						"entity": {
   396  							"name": "app-name-1"
   397  						}
   398  					},
   399  					{
   400  						"metadata": {
   401  							"guid": "app-guid-2",
   402  							"updated_at": null
   403  						},
   404  						"entity": {
   405  							"name": "app-name-2"
   406  						}
   407  					}
   408  				]
   409  			}`
   410  				response2 := `{
   411  				"next_url": null,
   412  				"resources": [
   413  					{
   414  						"metadata": {
   415  							"guid": "app-guid-3",
   416  							"updated_at": null
   417  						},
   418  						"entity": {
   419  							"name": "app-name-3"
   420  						}
   421  					},
   422  					{
   423  						"metadata": {
   424  							"guid": "app-guid-4",
   425  							"updated_at": null
   426  						},
   427  						"entity": {
   428  							"name": "app-name-4"
   429  						}
   430  					}
   431  				]
   432  			}`
   433  				server.AppendHandlers(
   434  					CombineHandlers(
   435  						VerifyRequest(http.MethodGet, "/v2/routes/some-route-guid/apps", "q=space_guid:some-space-guid"),
   436  						RespondWith(http.StatusOK, response1, http.Header{"X-Cf-Warnings": {"this is a warning"}}),
   437  					),
   438  				)
   439  				server.AppendHandlers(
   440  					CombineHandlers(
   441  						VerifyRequest(http.MethodGet, "/v2/routes/some-route-guid/apps", "q=space_guid:some-space-guid&page=2"),
   442  						RespondWith(http.StatusOK, response2, http.Header{"X-Cf-Warnings": {"this is another warning"}}),
   443  					),
   444  				)
   445  			})
   446  
   447  			It("returns all the applications and all warnings", func() {
   448  				apps, warnings, err := client.GetRouteApplications("some-route-guid", []Query{{
   449  					Filter:   SpaceGUIDFilter,
   450  					Operator: EqualOperator,
   451  					Value:    "some-space-guid",
   452  				}})
   453  				Expect(err).NotTo(HaveOccurred())
   454  				Expect(apps).To(ConsistOf([]Application{
   455  					{Name: "app-name-1", GUID: "app-guid-1"},
   456  					{Name: "app-name-2", GUID: "app-guid-2"},
   457  					{Name: "app-name-3", GUID: "app-guid-3"},
   458  					{Name: "app-name-4", GUID: "app-guid-4"},
   459  				}))
   460  				Expect(warnings).To(ConsistOf(Warnings{"this is a warning", "this is another warning"}))
   461  			})
   462  		})
   463  
   464  		Context("when there are no applications associated with this route", func() {
   465  			BeforeEach(func() {
   466  				response := `{
   467  				"next_url": "",
   468  				"resources": []
   469  			}`
   470  				server.AppendHandlers(
   471  					CombineHandlers(
   472  						VerifyRequest(http.MethodGet, "/v2/routes/some-route-guid/apps"),
   473  						RespondWith(http.StatusOK, response),
   474  					),
   475  				)
   476  			})
   477  
   478  			It("returns an empty list of applications", func() {
   479  				apps, _, err := client.GetRouteApplications("some-route-guid", nil)
   480  				Expect(err).NotTo(HaveOccurred())
   481  				Expect(apps).To(BeEmpty())
   482  			})
   483  		})
   484  	})
   485  })