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

     1  package ccv3_test
     2  
     3  import (
     4  	"net/http"
     5  
     6  	"code.cloudfoundry.org/cli/api/cloudcontroller"
     7  	. "code.cloudfoundry.org/cli/api/cloudcontroller/ccv3"
     8  
     9  	. "github.com/onsi/ginkgo"
    10  	. "github.com/onsi/gomega"
    11  	. "github.com/onsi/gomega/ghttp"
    12  )
    13  
    14  var _ = Describe("Error Wrapper", func() {
    15  	var (
    16  		response           string
    17  		serverResponseCode int
    18  
    19  		client *Client
    20  	)
    21  
    22  	Describe("UnexpectedResponseError", func() {
    23  		Describe("Error", func() {
    24  			It("returns all of the errors joined with newlines", func() {
    25  				err := UnexpectedResponseError{
    26  					ResponseCode: http.StatusTeapot,
    27  					CCErrorResponse: CCErrorResponse{
    28  						Errors: []CCError{
    29  							{
    30  								Code:   282010,
    31  								Detail: "detail 1",
    32  								Title:  "title-1",
    33  							},
    34  							{
    35  								Code:   10242013,
    36  								Detail: "detail 2",
    37  								Title:  "title-2",
    38  							},
    39  						},
    40  					},
    41  					RequestIDs: []string{
    42  						"6e0b4379-f5f7-4b2b-56b0-9ab7e96eed95",
    43  						"6e0b4379-f5f7-4b2b-56b0-9ab7e96eed95::7445d9db-c31e-410d-8dc5-9f79ec3fc26f",
    44  					},
    45  				}
    46  
    47  				Expect(err.Error()).To(Equal(`Unexpected Response
    48  Response Code: 418
    49  Request ID:    6e0b4379-f5f7-4b2b-56b0-9ab7e96eed95
    50  Request ID:    6e0b4379-f5f7-4b2b-56b0-9ab7e96eed95::7445d9db-c31e-410d-8dc5-9f79ec3fc26f
    51  Code: 282010, Title: title-1, Detail: detail 1
    52  Code: 10242013, Title: title-2, Detail: detail 2`))
    53  			})
    54  		})
    55  	})
    56  
    57  	Describe("Make", func() {
    58  		BeforeEach(func() {
    59  			response = `
    60  {
    61    "errors": [
    62      {
    63        "code": 777,
    64        "detail": "SomeCC Error Message",
    65        "title": "CF-SomeError"
    66      }
    67    ]
    68  }`
    69  
    70  			client = NewTestClient()
    71  		})
    72  
    73  		JustBeforeEach(func() {
    74  			server.AppendHandlers(
    75  				CombineHandlers(
    76  					VerifyRequest(http.MethodGet, "/v3/apps"),
    77  					RespondWith(serverResponseCode, response, http.Header{
    78  						"X-Vcap-Request-Id": {
    79  							"6e0b4379-f5f7-4b2b-56b0-9ab7e96eed95",
    80  							"6e0b4379-f5f7-4b2b-56b0-9ab7e96eed95::7445d9db-c31e-410d-8dc5-9f79ec3fc26f",
    81  						},
    82  					},
    83  					),
    84  				),
    85  			)
    86  		})
    87  
    88  		Context("when the error is not from the cloud controller", func() {
    89  			BeforeEach(func() {
    90  				serverResponseCode = http.StatusTeapot
    91  				response = "418 I'm a teapot: Requested route ('some-url.com') does not exist."
    92  			})
    93  
    94  			It("returns a RawHTTPStatusError", func() {
    95  				_, _, err := client.GetApplications(nil)
    96  				Expect(err).To(MatchError(cloudcontroller.RawHTTPStatusError{
    97  					StatusCode:  http.StatusTeapot,
    98  					RawResponse: []byte(response),
    99  					RequestIDs: []string{
   100  						"6e0b4379-f5f7-4b2b-56b0-9ab7e96eed95",
   101  						"6e0b4379-f5f7-4b2b-56b0-9ab7e96eed95::7445d9db-c31e-410d-8dc5-9f79ec3fc26f",
   102  					},
   103  				}))
   104  			})
   105  		})
   106  
   107  		Context("when the error is from the cloud controller", func() {
   108  			Context("when an empty list of errors is returned", func() {
   109  				BeforeEach(func() {
   110  					serverResponseCode = http.StatusUnauthorized
   111  					response = `{ "errors": [] }`
   112  				})
   113  
   114  				It("returns an UnexpectedResponseError", func() {
   115  					_, _, err := client.GetApplications(nil)
   116  					Expect(err).To(MatchError(UnexpectedResponseError{
   117  						ResponseCode:    http.StatusUnauthorized,
   118  						CCErrorResponse: CCErrorResponse{Errors: []CCError{}},
   119  					}))
   120  				})
   121  			})
   122  
   123  			Context("(401) Unauthorized", func() {
   124  				BeforeEach(func() {
   125  					serverResponseCode = http.StatusUnauthorized
   126  				})
   127  
   128  				Context("generic 401", func() {
   129  					It("returns a UnauthorizedError", func() {
   130  						_, _, err := client.GetApplications(nil)
   131  						Expect(err).To(MatchError(cloudcontroller.UnauthorizedError{Message: "SomeCC Error Message"}))
   132  					})
   133  				})
   134  
   135  				Context("invalid token", func() {
   136  					BeforeEach(func() {
   137  						response = `{
   138  							"errors": [
   139  								{
   140  									"code": 1000,
   141  									"detail": "Invalid Auth Token",
   142  									"title": "CF-InvalidAuthToken"
   143  								}
   144  							]
   145  						}`
   146  					})
   147  
   148  					It("returns an InvalidAuthTokenError", func() {
   149  						_, _, err := client.GetApplications(nil)
   150  						Expect(err).To(MatchError(cloudcontroller.InvalidAuthTokenError{Message: "Invalid Auth Token"}))
   151  					})
   152  				})
   153  			})
   154  
   155  			Context("(403) Forbidden", func() {
   156  				BeforeEach(func() {
   157  					serverResponseCode = http.StatusForbidden
   158  				})
   159  
   160  				It("returns a ForbiddenError", func() {
   161  					_, _, err := client.GetApplications(nil)
   162  					Expect(err).To(MatchError(cloudcontroller.ForbiddenError{Message: "SomeCC Error Message"}))
   163  				})
   164  			})
   165  
   166  			Context("(404) Not Found", func() {
   167  				BeforeEach(func() {
   168  					serverResponseCode = http.StatusNotFound
   169  				})
   170  
   171  				It("returns a ResourceNotFoundError", func() {
   172  					_, _, err := client.GetApplications(nil)
   173  					Expect(err).To(MatchError(cloudcontroller.ResourceNotFoundError{Message: "SomeCC Error Message"}))
   174  				})
   175  
   176  				Context("when the error is not from the cloud controller API", func() {
   177  					BeforeEach(func() {
   178  						response = "an error not from the CC API"
   179  					})
   180  
   181  					It("returns a NotFoundError", func() {
   182  						_, _, err := client.GetApplications(nil)
   183  						Expect(err).To(MatchError(cloudcontroller.NotFoundError{Message: response}))
   184  					})
   185  				})
   186  			})
   187  
   188  			Context("(422) Unprocessable Entity", func() {
   189  				BeforeEach(func() {
   190  					serverResponseCode = http.StatusUnprocessableEntity
   191  				})
   192  
   193  				It("returns a UnprocessableEntityError", func() {
   194  					_, _, err := client.GetApplications(nil)
   195  					Expect(err).To(MatchError(cloudcontroller.UnprocessableEntityError{Message: "SomeCC Error Message"}))
   196  				})
   197  			})
   198  
   199  			Context("(503) Service Unavailable", func() {
   200  				BeforeEach(func() {
   201  					serverResponseCode = http.StatusServiceUnavailable
   202  				})
   203  
   204  				It("returns a ServiceUnavailableError", func() {
   205  					_, _, err := client.GetApplications(nil)
   206  					Expect(err).To(MatchError(cloudcontroller.ServiceUnavailableError{Message: "SomeCC Error Message"}))
   207  				})
   208  
   209  				Context("when the title is 'CF-TaskWorkersUnavailable'", func() {
   210  					BeforeEach(func() {
   211  						response = `{
   212    "errors": [
   213      {
   214        "code": 170020,
   215        "detail": "Task workers are unavailable: Failed to open TCP connection to nsync.service.cf.internal:8787 (getaddrinfo: Name or service not known)",
   216        "title": "CF-TaskWorkersUnavailable"
   217      }
   218    ]
   219  }`
   220  					})
   221  
   222  					It("returns a TaskWorkersUnavailableError", func() {
   223  						_, _, err := client.GetApplications(nil)
   224  						Expect(err).To(MatchError(TaskWorkersUnavailableError{Message: "Task workers are unavailable: Failed to open TCP connection to nsync.service.cf.internal:8787 (getaddrinfo: Name or service not known)"}))
   225  					})
   226  				})
   227  			})
   228  
   229  			Context("Unhandled Error Codes", func() {
   230  				BeforeEach(func() {
   231  					serverResponseCode = http.StatusTeapot
   232  				})
   233  
   234  				It("returns an UnexpectedResponseError", func() {
   235  					_, _, err := client.GetApplications(nil)
   236  					Expect(err).To(MatchError(UnexpectedResponseError{
   237  						ResponseCode: http.StatusTeapot,
   238  						CCErrorResponse: CCErrorResponse{
   239  							Errors: []CCError{
   240  								{
   241  									Code:   777,
   242  									Detail: "SomeCC Error Message",
   243  									Title:  "CF-SomeError",
   244  								},
   245  							},
   246  						},
   247  						RequestIDs: []string{
   248  							"6e0b4379-f5f7-4b2b-56b0-9ab7e96eed95",
   249  							"6e0b4379-f5f7-4b2b-56b0-9ab7e96eed95::7445d9db-c31e-410d-8dc5-9f79ec3fc26f",
   250  						},
   251  					}))
   252  				})
   253  			})
   254  		})
   255  	})
   256  })