github.com/franc20/ayesa_sap@v7.0.0-beta.28.0.20200124003224-302d4d52fa6c+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/ccerror"
     8  	. "code.cloudfoundry.org/cli/api/cloudcontroller/ccv2"
     9  	"code.cloudfoundry.org/cli/api/cloudcontroller/ccv2/constant"
    10  	"code.cloudfoundry.org/cli/types"
    11  	. "github.com/onsi/ginkgo"
    12  	. "github.com/onsi/gomega"
    13  	. "github.com/onsi/gomega/ghttp"
    14  )
    15  
    16  var _ = Describe("Application", func() {
    17  	var client *Client
    18  
    19  	BeforeEach(func() {
    20  		client = NewTestClient()
    21  	})
    22  
    23  	Describe("CreateApplication", func() {
    24  		When("the update is successful", func() {
    25  			When("setting the minimum", func() { // are we **only** encoding the things we want
    26  				BeforeEach(func() {
    27  					response := `
    28  						{
    29  							"metadata": {
    30  								"guid": "some-app-guid"
    31  							},
    32  							"entity": {
    33  								"name": "some-app-name",
    34  								"space_guid": "some-space-guid"
    35  							}
    36  						}`
    37  					requestBody := map[string]string{
    38  						"name":       "some-app-name",
    39  						"space_guid": "some-space-guid",
    40  					}
    41  					server.AppendHandlers(
    42  						CombineHandlers(
    43  							VerifyRequest(http.MethodPost, "/v2/apps"),
    44  							VerifyJSONRepresenting(requestBody),
    45  							RespondWith(http.StatusCreated, response, http.Header{"X-Cf-Warnings": {"this is a warning"}}),
    46  						),
    47  					)
    48  				})
    49  
    50  				It("returns the created object and warnings", func() {
    51  					app, warnings, err := client.CreateApplication(Application{
    52  						Name:      "some-app-name",
    53  						SpaceGUID: "some-space-guid",
    54  					})
    55  					Expect(err).NotTo(HaveOccurred())
    56  
    57  					Expect(app).To(Equal(Application{
    58  						GUID:      "some-app-guid",
    59  						SpaceGUID: "some-space-guid",
    60  						Name:      "some-app-name",
    61  					}))
    62  					Expect(warnings).To(ConsistOf(Warnings{"this is a warning"}))
    63  				})
    64  			})
    65  		})
    66  
    67  		When("the create returns an error", func() {
    68  			BeforeEach(func() {
    69  				response := `
    70  					{
    71  						"description": "Request invalid due to parse error: Field: name, Error: Missing field name, Field: space_guid, Error: Missing field space_guid",
    72  						"error_code": "CF-MessageParseError",
    73  						"code": 1001
    74  					}
    75  			`
    76  				server.AppendHandlers(
    77  					CombineHandlers(
    78  						VerifyRequest(http.MethodPost, "/v2/apps"),
    79  						RespondWith(http.StatusBadRequest, response, http.Header{"X-Cf-Warnings": {"this is a warning"}}),
    80  					),
    81  				)
    82  			})
    83  
    84  			It("returns the error and warnings", func() {
    85  				_, warnings, err := client.CreateApplication(Application{})
    86  				Expect(err).To(MatchError(ccerror.BadRequestError{Message: "Request invalid due to parse error: Field: name, Error: Missing field name, Field: space_guid, Error: Missing field space_guid"}))
    87  				Expect(warnings).To(ConsistOf(Warnings{"this is a warning"}))
    88  			})
    89  		})
    90  	})
    91  
    92  	Describe("GetApplication", func() {
    93  		BeforeEach(func() {
    94  			response := `{
    95  						"metadata": {
    96  							"guid": "app-guid-1",
    97  							"updated_at": null
    98  						},
    99  						"entity": {
   100  							"buildpack": "ruby 1.6.29",
   101  							"command": "some-command",
   102  							"detected_start_command": "echo 'I am a banana'",
   103  							"disk_quota": 586,
   104  							"detected_buildpack": null,
   105  							"docker_credentials": {
   106  								"username": "docker-username",
   107  								"password": "docker-password"
   108  							},
   109  							"docker_image": "some-docker-path",
   110  							"environment_json": {
   111  								"key1": "val1",
   112  								"key2": 83493475092347,
   113  								"key3": true,
   114  								"key4": 75821.521
   115  							},
   116  							"health_check_timeout": 120,
   117  							"health_check_type": "port",
   118  							"health_check_http_endpoint": "/",
   119  							"instances": 13,
   120  							"memory": 1024,
   121  							"name": "app-name-1",
   122  							"package_state": "FAILED",
   123  							"package_updated_at": "2015-03-10T23:11:54Z",
   124  							"stack_guid": "some-stack-guid",
   125  							"staging_failed_description": "some-staging-failed-description",
   126  							"staging_failed_reason": "some-reason",
   127  							"state": "STOPPED"
   128  						}
   129  			}`
   130  			server.AppendHandlers(
   131  				CombineHandlers(
   132  					VerifyRequest(http.MethodGet, "/v2/apps/app-guid-1"),
   133  					RespondWith(http.StatusOK, response, http.Header{"X-Cf-Warnings": {"this is a warning"}}),
   134  				),
   135  			)
   136  		})
   137  
   138  		When("apps exist", func() {
   139  			It("returns the app", func() {
   140  				app, warnings, err := client.GetApplication("app-guid-1")
   141  				Expect(err).NotTo(HaveOccurred())
   142  
   143  				updatedAt, err := time.Parse(time.RFC3339, "2015-03-10T23:11:54Z")
   144  				Expect(err).NotTo(HaveOccurred())
   145  
   146  				Expect(app).To(Equal(Application{
   147  					Buildpack:            types.FilteredString{IsSet: true, Value: "ruby 1.6.29"},
   148  					Command:              types.FilteredString{IsSet: true, Value: "some-command"},
   149  					DetectedBuildpack:    types.FilteredString{},
   150  					DetectedStartCommand: types.FilteredString{IsSet: true, Value: "echo 'I am a banana'"},
   151  					DiskQuota:            types.NullByteSizeInMb{IsSet: true, Value: 586},
   152  					DockerCredentials: DockerCredentials{
   153  						Username: "docker-username",
   154  						Password: "docker-password",
   155  					},
   156  					DockerImage: "some-docker-path",
   157  					EnvironmentVariables: map[string]string{
   158  						"key1": "val1",
   159  						"key2": "83493475092347",
   160  						"key3": "true",
   161  						"key4": "75821.521",
   162  					},
   163  					GUID:                     "app-guid-1",
   164  					HealthCheckTimeout:       120,
   165  					HealthCheckType:          "port",
   166  					HealthCheckHTTPEndpoint:  "/",
   167  					Instances:                types.NullInt{Value: 13, IsSet: true},
   168  					Memory:                   types.NullByteSizeInMb{IsSet: true, Value: 1024},
   169  					Name:                     "app-name-1",
   170  					PackageState:             constant.ApplicationPackageFailed,
   171  					PackageUpdatedAt:         updatedAt,
   172  					StackGUID:                "some-stack-guid",
   173  					StagingFailedDescription: "some-staging-failed-description",
   174  					StagingFailedReason:      "some-reason",
   175  					State:                    constant.ApplicationStopped,
   176  				}))
   177  				Expect(warnings).To(ConsistOf(Warnings{"this is a warning"}))
   178  			})
   179  		})
   180  	})
   181  
   182  	Describe("GetApplications", func() {
   183  		BeforeEach(func() {
   184  			response1 := `{
   185  				"next_url": "/v2/apps?q=space_guid:some-space-guid&page=2",
   186  				"resources": [
   187  					{
   188  						"metadata": {
   189  							"guid": "app-guid-1",
   190  							"updated_at": null
   191  						},
   192  						"entity": {
   193  							"buildpack": "ruby 1.6.29",
   194  							"detected_start_command": "echo 'I am a banana'",
   195  							"disk_quota": 586,
   196  							"detected_buildpack": null,
   197  							"health_check_type": "port",
   198  							"health_check_http_endpoint": "/",
   199  							"instances": 13,
   200  							"memory": 1024,
   201  							"name": "app-name-1",
   202  							"package_state": "FAILED",
   203  							"package_updated_at": "2015-03-10T23:11:54Z",
   204  							"space_guid": "some-space-guid",
   205  							"stack_guid": "some-stack-guid",
   206  							"staging_failed_reason": "some-reason",
   207  							"state": "STOPPED"
   208  						}
   209  					},
   210  					{
   211  						"metadata": {
   212  							"guid": "app-guid-2",
   213  							"updated_at": null
   214  						},
   215  						"entity": {
   216  							"name": "app-name-2",
   217  							"detected_buildpack": "ruby 1.6.29",
   218  							"package_updated_at": null
   219  						}
   220  					}
   221  				]
   222  			}`
   223  			response2 := `{
   224  				"next_url": null,
   225  				"resources": [
   226  					{
   227  						"metadata": {
   228  							"guid": "app-guid-3",
   229  							"updated_at": null
   230  						},
   231  						"entity": {
   232  							"name": "app-name-3"
   233  						}
   234  					},
   235  					{
   236  						"metadata": {
   237  							"guid": "app-guid-4",
   238  							"updated_at": null
   239  						},
   240  						"entity": {
   241  							"name": "app-name-4"
   242  						}
   243  					}
   244  				]
   245  			}`
   246  			server.AppendHandlers(
   247  				CombineHandlers(
   248  					VerifyRequest(http.MethodGet, "/v2/apps", "q=space_guid:some-space-guid"),
   249  					RespondWith(http.StatusOK, response1, http.Header{"X-Cf-Warnings": {"this is a warning"}}),
   250  				),
   251  			)
   252  			server.AppendHandlers(
   253  				CombineHandlers(
   254  					VerifyRequest(http.MethodGet, "/v2/apps", "q=space_guid:some-space-guid&page=2"),
   255  					RespondWith(http.StatusOK, response2, http.Header{"X-Cf-Warnings": {"this is another warning"}}),
   256  				),
   257  			)
   258  		})
   259  
   260  		When("apps exist", func() {
   261  			It("returns all the queried apps", func() {
   262  				apps, warnings, err := client.GetApplications(Filter{
   263  					Type:     constant.SpaceGUIDFilter,
   264  					Operator: constant.EqualOperator,
   265  					Values:   []string{"some-space-guid"},
   266  				})
   267  				Expect(err).NotTo(HaveOccurred())
   268  
   269  				updatedAt, err := time.Parse(time.RFC3339, "2015-03-10T23:11:54Z")
   270  				Expect(err).NotTo(HaveOccurred())
   271  
   272  				Expect(apps).To(ConsistOf([]Application{
   273  					{
   274  						Buildpack:               types.FilteredString{IsSet: true, Value: "ruby 1.6.29"},
   275  						DetectedBuildpack:       types.FilteredString{},
   276  						DetectedStartCommand:    types.FilteredString{IsSet: true, Value: "echo 'I am a banana'"},
   277  						DiskQuota:               types.NullByteSizeInMb{IsSet: true, Value: 586},
   278  						GUID:                    "app-guid-1",
   279  						HealthCheckType:         "port",
   280  						HealthCheckHTTPEndpoint: "/",
   281  						Instances:               types.NullInt{Value: 13, IsSet: true},
   282  						Memory:                  types.NullByteSizeInMb{IsSet: true, Value: 1024},
   283  						Name:                    "app-name-1",
   284  						PackageState:            constant.ApplicationPackageFailed,
   285  						PackageUpdatedAt:        updatedAt,
   286  						SpaceGUID:               "some-space-guid",
   287  						StackGUID:               "some-stack-guid",
   288  						StagingFailedReason:     "some-reason",
   289  						State:                   constant.ApplicationStopped,
   290  					},
   291  					{
   292  						Name:              "app-name-2",
   293  						GUID:              "app-guid-2",
   294  						DetectedBuildpack: types.FilteredString{IsSet: true, Value: "ruby 1.6.29"},
   295  					},
   296  					{Name: "app-name-3", GUID: "app-guid-3"},
   297  					{Name: "app-name-4", GUID: "app-guid-4"},
   298  				}))
   299  				Expect(warnings).To(ConsistOf(Warnings{"this is a warning", "this is another warning"}))
   300  			})
   301  		})
   302  	})
   303  
   304  	Describe("GetRouteApplications", func() {
   305  		When("the route guid is not found", func() {
   306  			BeforeEach(func() {
   307  				response := `
   308  {
   309    "code": 210002,
   310    "description": "The route could not be found: some-route-guid",
   311    "error_code": "CF-RouteNotFound"
   312  }
   313  			`
   314  				server.AppendHandlers(
   315  					CombineHandlers(
   316  						VerifyRequest(http.MethodGet, "/v2/routes/some-route-guid/apps"),
   317  						RespondWith(http.StatusNotFound, response),
   318  					),
   319  				)
   320  			})
   321  
   322  			It("returns an error", func() {
   323  				_, _, err := client.GetRouteApplications("some-route-guid")
   324  				Expect(err).To(MatchError(ccerror.ResourceNotFoundError{
   325  					Message: "The route could not be found: some-route-guid",
   326  				}))
   327  			})
   328  		})
   329  
   330  		When("there are applications associated with this route", func() {
   331  			BeforeEach(func() {
   332  				response1 := `{
   333  				"next_url": "/v2/routes/some-route-guid/apps?q=space_guid:some-space-guid&page=2",
   334  				"resources": [
   335  					{
   336  						"metadata": {
   337  							"guid": "app-guid-1",
   338  							"updated_at": null
   339  						},
   340  						"entity": {
   341  							"name": "app-name-1"
   342  						}
   343  					},
   344  					{
   345  						"metadata": {
   346  							"guid": "app-guid-2",
   347  							"updated_at": null
   348  						},
   349  						"entity": {
   350  							"name": "app-name-2"
   351  						}
   352  					}
   353  				]
   354  			}`
   355  				response2 := `{
   356  				"next_url": null,
   357  				"resources": [
   358  					{
   359  						"metadata": {
   360  							"guid": "app-guid-3",
   361  							"updated_at": null
   362  						},
   363  						"entity": {
   364  							"name": "app-name-3"
   365  						}
   366  					},
   367  					{
   368  						"metadata": {
   369  							"guid": "app-guid-4",
   370  							"updated_at": null
   371  						},
   372  						"entity": {
   373  							"name": "app-name-4"
   374  						}
   375  					}
   376  				]
   377  			}`
   378  				server.AppendHandlers(
   379  					CombineHandlers(
   380  						VerifyRequest(http.MethodGet, "/v2/routes/some-route-guid/apps", "q=space_guid:some-space-guid"),
   381  						RespondWith(http.StatusOK, response1, http.Header{"X-Cf-Warnings": {"this is a warning"}}),
   382  					),
   383  				)
   384  				server.AppendHandlers(
   385  					CombineHandlers(
   386  						VerifyRequest(http.MethodGet, "/v2/routes/some-route-guid/apps", "q=space_guid:some-space-guid&page=2"),
   387  						RespondWith(http.StatusOK, response2, http.Header{"X-Cf-Warnings": {"this is another warning"}}),
   388  					),
   389  				)
   390  			})
   391  
   392  			It("returns all the applications and all warnings", func() {
   393  				apps, warnings, err := client.GetRouteApplications("some-route-guid", Filter{
   394  					Type:     constant.SpaceGUIDFilter,
   395  					Operator: constant.EqualOperator,
   396  					Values:   []string{"some-space-guid"},
   397  				})
   398  				Expect(err).NotTo(HaveOccurred())
   399  				Expect(apps).To(ConsistOf([]Application{
   400  					{Name: "app-name-1", GUID: "app-guid-1"},
   401  					{Name: "app-name-2", GUID: "app-guid-2"},
   402  					{Name: "app-name-3", GUID: "app-guid-3"},
   403  					{Name: "app-name-4", GUID: "app-guid-4"},
   404  				}))
   405  				Expect(warnings).To(ConsistOf(Warnings{"this is a warning", "this is another warning"}))
   406  			})
   407  		})
   408  
   409  		When("there are no applications associated with this route", func() {
   410  			BeforeEach(func() {
   411  				response := `{
   412  				"next_url": "",
   413  				"resources": []
   414  			}`
   415  				server.AppendHandlers(
   416  					CombineHandlers(
   417  						VerifyRequest(http.MethodGet, "/v2/routes/some-route-guid/apps"),
   418  						RespondWith(http.StatusOK, response),
   419  					),
   420  				)
   421  			})
   422  
   423  			It("returns an empty list of applications", func() {
   424  				apps, _, err := client.GetRouteApplications("some-route-guid")
   425  				Expect(err).NotTo(HaveOccurred())
   426  				Expect(apps).To(BeEmpty())
   427  			})
   428  		})
   429  	})
   430  
   431  	Describe("RestageApplication", func() {
   432  		When("the restage is successful", func() {
   433  			BeforeEach(func() {
   434  				response := `{
   435  					"metadata": {
   436  						"guid": "some-app-guid",
   437  						"url": "/v2/apps/some-app-guid"
   438  					},
   439  					"entity": {
   440  						"buildpack": "ruby 1.6.29",
   441  						"detected_start_command": "echo 'I am a banana'",
   442  						"disk_quota": 586,
   443  						"detected_buildpack": null,
   444  						"docker_image": "some-docker-path",
   445  						"health_check_type": "some-health-check-type",
   446  						"health_check_http_endpoint": "/anything",
   447  						"instances": 13,
   448  						"memory": 1024,
   449  						"name": "app-name-1",
   450  						"package_updated_at": "2015-03-10T23:11:54Z",
   451  						"stack_guid": "some-stack-guid",
   452  						"state": "STARTED"
   453  					}
   454  				}`
   455  
   456  				server.AppendHandlers(
   457  					CombineHandlers(
   458  						VerifyRequest(http.MethodPost, "/v2/apps/some-app-guid/restage"),
   459  						RespondWith(http.StatusCreated, response, http.Header{"X-Cf-Warnings": {"this is a warning"}}),
   460  					),
   461  				)
   462  			})
   463  
   464  			It("returns the updated object and warnings and sends all updated field", func() {
   465  				app, warnings, err := client.RestageApplication(Application{
   466  					DockerImage:             "some-docker-path",
   467  					GUID:                    "some-app-guid",
   468  					HealthCheckType:         "some-health-check-type",
   469  					HealthCheckHTTPEndpoint: "/anything",
   470  					State:                   constant.ApplicationStarted,
   471  				})
   472  				Expect(err).NotTo(HaveOccurred())
   473  
   474  				updatedAt, err := time.Parse(time.RFC3339, "2015-03-10T23:11:54Z")
   475  				Expect(err).NotTo(HaveOccurred())
   476  
   477  				Expect(app).To(Equal(Application{
   478  					Buildpack:               types.FilteredString{IsSet: true, Value: "ruby 1.6.29"},
   479  					DetectedBuildpack:       types.FilteredString{},
   480  					DetectedStartCommand:    types.FilteredString{IsSet: true, Value: "echo 'I am a banana'"},
   481  					DiskQuota:               types.NullByteSizeInMb{IsSet: true, Value: 586},
   482  					DockerImage:             "some-docker-path",
   483  					GUID:                    "some-app-guid",
   484  					HealthCheckType:         "some-health-check-type",
   485  					HealthCheckHTTPEndpoint: "/anything",
   486  					Instances:               types.NullInt{Value: 13, IsSet: true},
   487  					Memory:                  types.NullByteSizeInMb{IsSet: true, Value: 1024},
   488  					Name:                    "app-name-1",
   489  					PackageUpdatedAt:        updatedAt,
   490  					StackGUID:               "some-stack-guid",
   491  					State:                   constant.ApplicationStarted,
   492  				}))
   493  				Expect(warnings).To(ConsistOf(Warnings{"this is a warning"}))
   494  			})
   495  		})
   496  
   497  		When("the restage returns an error", func() {
   498  			BeforeEach(func() {
   499  				response := `
   500  {
   501    "code": 210002,
   502    "description": "The app could not be found: some-app-guid",
   503    "error_code": "CF-AppNotFound"
   504  }
   505  			`
   506  				server.AppendHandlers(
   507  					CombineHandlers(
   508  						VerifyRequest(http.MethodPost, "/v2/apps/some-app-guid/restage"),
   509  						RespondWith(http.StatusNotFound, response, http.Header{"X-Cf-Warnings": {"this is a warning"}}),
   510  					),
   511  				)
   512  			})
   513  
   514  			It("returns the error and warnings", func() {
   515  				_, warnings, err := client.RestageApplication(Application{
   516  					GUID:            "some-app-guid",
   517  					HealthCheckType: "some-health-check-type",
   518  				})
   519  				Expect(err).To(MatchError(ccerror.ResourceNotFoundError{Message: "The app could not be found: some-app-guid"}))
   520  				Expect(warnings).To(ConsistOf(Warnings{"this is a warning"}))
   521  			})
   522  		})
   523  	})
   524  
   525  	Describe("UpdateApplication", func() {
   526  		When("the update is successful", func() {
   527  			When("updating all fields", func() { //are we encoding everything correctly?
   528  				BeforeEach(func() {
   529  					response1 := `{
   530  				"metadata": {
   531  					"guid": "some-app-guid",
   532  					"updated_at": null
   533  				},
   534  				"entity": {
   535  					"detected_start_command": "echo 'I am a banana'",
   536  					"disk_quota": 586,
   537  					"detected_buildpack": null,
   538  					"docker_credentials": {
   539  						"username": "docker-username",
   540  						"password": "docker-password"
   541  					},
   542  					"docker_image": "some-docker-path",
   543  					"environment_json": {
   544  						"key1": "val1",
   545  						"key2": 83493475092347,
   546  						"key3": true,
   547  						"key4": 75821.521
   548  					},
   549  					"health_check_timeout": 120,
   550  					"health_check_type": "some-health-check-type",
   551  					"health_check_http_endpoint": "/anything",
   552  					"instances": 0,
   553  					"memory": 1024,
   554  					"name": "app-name-1",
   555  					"package_updated_at": "2015-03-10T23:11:54Z",
   556  					"stack_guid": "some-stack-guid",
   557  					"state": "STARTED"
   558  				}
   559  			}`
   560  					expectedBody := map[string]interface{}{
   561  						"buildpack":  "",
   562  						"command":    "",
   563  						"disk_quota": 0,
   564  						"docker_credentials": map[string]string{
   565  							"username": "docker-username",
   566  							"password": "docker-password",
   567  						},
   568  						"docker_image": "some-docker-path",
   569  						"environment_json": map[string]string{
   570  							"key1": "val1",
   571  							"key2": "83493475092347",
   572  							"key3": "true",
   573  							"key4": "75821.521",
   574  						},
   575  						"health_check_http_endpoint": "/anything",
   576  						"health_check_type":          "some-health-check-type",
   577  						"instances":                  0,
   578  						"memory":                     0,
   579  						"stack_guid":                 "some-stack-guid",
   580  						"state":                      "STARTED",
   581  					}
   582  
   583  					server.AppendHandlers(
   584  						CombineHandlers(
   585  							VerifyRequest(http.MethodPut, "/v2/apps/some-app-guid"),
   586  							VerifyJSONRepresenting(expectedBody),
   587  							RespondWith(http.StatusCreated, response1, http.Header{"X-Cf-Warnings": {"this is a warning"}}),
   588  						),
   589  					)
   590  				})
   591  
   592  				It("returns the updated object and warnings and sends all updated field", func() {
   593  					app, warnings, err := client.UpdateApplication(Application{
   594  						Buildpack: types.FilteredString{IsSet: true, Value: ""},
   595  						Command:   types.FilteredString{IsSet: true, Value: ""},
   596  						DiskQuota: types.NullByteSizeInMb{IsSet: true},
   597  						DockerCredentials: DockerCredentials{
   598  							Username: "docker-username",
   599  							Password: "docker-password",
   600  						},
   601  						DockerImage: "some-docker-path",
   602  						EnvironmentVariables: map[string]string{
   603  							"key1": "val1",
   604  							"key2": "83493475092347",
   605  							"key3": "true",
   606  							"key4": "75821.521",
   607  						},
   608  						GUID:                    "some-app-guid",
   609  						HealthCheckHTTPEndpoint: "/anything",
   610  						HealthCheckType:         "some-health-check-type",
   611  						Instances:               types.NullInt{Value: 0, IsSet: true},
   612  						Memory:                  types.NullByteSizeInMb{IsSet: true},
   613  						StackGUID:               "some-stack-guid",
   614  						State:                   constant.ApplicationStarted,
   615  					})
   616  					Expect(err).NotTo(HaveOccurred())
   617  
   618  					updatedAt, err := time.Parse(time.RFC3339, "2015-03-10T23:11:54Z")
   619  					Expect(err).NotTo(HaveOccurred())
   620  
   621  					Expect(app).To(Equal(Application{
   622  						DetectedBuildpack:    types.FilteredString{},
   623  						DetectedStartCommand: types.FilteredString{IsSet: true, Value: "echo 'I am a banana'"},
   624  						DiskQuota:            types.NullByteSizeInMb{IsSet: true, Value: 586},
   625  						DockerCredentials: DockerCredentials{
   626  							Username: "docker-username",
   627  							Password: "docker-password",
   628  						},
   629  						DockerImage: "some-docker-path",
   630  						EnvironmentVariables: map[string]string{
   631  							"key1": "val1",
   632  							"key2": "83493475092347",
   633  							"key3": "true",
   634  							"key4": "75821.521",
   635  						},
   636  						GUID:                    "some-app-guid",
   637  						HealthCheckHTTPEndpoint: "/anything",
   638  						HealthCheckTimeout:      120,
   639  						HealthCheckType:         "some-health-check-type",
   640  						Instances:               types.NullInt{Value: 0, IsSet: true},
   641  						Memory:                  types.NullByteSizeInMb{IsSet: true, Value: 1024},
   642  						Name:                    "app-name-1",
   643  						PackageUpdatedAt:        updatedAt,
   644  						StackGUID:               "some-stack-guid",
   645  						State:                   constant.ApplicationStarted,
   646  					}))
   647  					Expect(warnings).To(ConsistOf(Warnings{"this is a warning"}))
   648  				})
   649  			})
   650  
   651  			When("only updating one field", func() { // are we **only** encoding the things we want
   652  				BeforeEach(func() {
   653  					response1 := `{
   654  				"metadata": {
   655  					"guid": "some-app-guid",
   656  					"updated_at": null
   657  				},
   658  				"entity": {
   659  					"buildpack": "ruby 1.6.29",
   660  					"detected_start_command": "echo 'I am a banana'",
   661  					"disk_quota": 586,
   662  					"detected_buildpack": null,
   663  					"health_check_type": "some-health-check-type",
   664  					"health_check_http_endpoint": "/",
   665  					"instances": 7,
   666  					"memory": 1024,
   667  					"name": "app-name-1",
   668  					"package_updated_at": "2015-03-10T23:11:54Z",
   669  					"stack_guid": "some-stack-guid",
   670  					"state": "STOPPED"
   671  				}
   672  			}`
   673  					server.AppendHandlers(
   674  						CombineHandlers(
   675  							VerifyRequest(http.MethodPut, "/v2/apps/some-app-guid"),
   676  							VerifyBody([]byte(`{"instances":7}`)),
   677  							RespondWith(http.StatusCreated, response1, http.Header{"X-Cf-Warnings": {"this is a warning"}}),
   678  						),
   679  					)
   680  				})
   681  
   682  				It("returns the updated object and warnings and sends only updated field", func() {
   683  					app, warnings, err := client.UpdateApplication(Application{
   684  						GUID:      "some-app-guid",
   685  						Instances: types.NullInt{IsSet: true, Value: 7},
   686  					})
   687  					Expect(err).NotTo(HaveOccurred())
   688  
   689  					updatedAt, err := time.Parse(time.RFC3339, "2015-03-10T23:11:54Z")
   690  					Expect(err).NotTo(HaveOccurred())
   691  
   692  					Expect(app).To(Equal(Application{
   693  						Buildpack:               types.FilteredString{IsSet: true, Value: "ruby 1.6.29"},
   694  						DetectedBuildpack:       types.FilteredString{},
   695  						DetectedStartCommand:    types.FilteredString{IsSet: true, Value: "echo 'I am a banana'"},
   696  						DiskQuota:               types.NullByteSizeInMb{IsSet: true, Value: 586},
   697  						GUID:                    "some-app-guid",
   698  						HealthCheckType:         "some-health-check-type",
   699  						HealthCheckHTTPEndpoint: "/",
   700  						Instances:               types.NullInt{Value: 7, IsSet: true},
   701  						Memory:                  types.NullByteSizeInMb{IsSet: true, Value: 1024},
   702  						Name:                    "app-name-1",
   703  						PackageUpdatedAt:        updatedAt,
   704  						StackGUID:               "some-stack-guid",
   705  						State:                   constant.ApplicationStopped,
   706  					}))
   707  					Expect(warnings).To(ConsistOf(Warnings{"this is a warning"}))
   708  				})
   709  			})
   710  		})
   711  
   712  		When("the update returns an error", func() {
   713  			BeforeEach(func() {
   714  				response := `
   715  {
   716    "code": 210002,
   717    "description": "The app could not be found: some-app-guid",
   718    "error_code": "CF-AppNotFound"
   719  }
   720  			`
   721  				server.AppendHandlers(
   722  					CombineHandlers(
   723  						VerifyRequest(http.MethodPut, "/v2/apps/some-app-guid"),
   724  						// VerifyBody([]byte(`{"health_check_type":"some-health-check-type"}`)),
   725  						RespondWith(http.StatusNotFound, response, http.Header{"X-Cf-Warnings": {"this is a warning"}}),
   726  					),
   727  				)
   728  			})
   729  
   730  			It("returns the error and warnings", func() {
   731  				_, warnings, err := client.UpdateApplication(Application{
   732  					GUID:            "some-app-guid",
   733  					HealthCheckType: "some-health-check-type",
   734  				})
   735  				Expect(err).To(MatchError(ccerror.ResourceNotFoundError{Message: "The app could not be found: some-app-guid"}))
   736  				Expect(warnings).To(ConsistOf(Warnings{"this is a warning"}))
   737  			})
   738  		})
   739  	})
   740  })