github.com/LukasHeimann/cloudfoundrycli/v8@v8.4.4/integration/v7/isolated/curl_command_test.go (about)

     1  package isolated
     2  
     3  import (
     4  	"fmt"
     5  	"io/ioutil"
     6  	"os"
     7  	"path/filepath"
     8  	"regexp"
     9  	"strings"
    10  
    11  	. "github.com/LukasHeimann/cloudfoundrycli/v8/cf/util/testhelpers/matchers"
    12  	"github.com/LukasHeimann/cloudfoundrycli/v8/integration/helpers"
    13  	. "github.com/onsi/ginkgo"
    14  	. "github.com/onsi/gomega"
    15  	. "github.com/onsi/gomega/gbytes"
    16  	. "github.com/onsi/gomega/gexec"
    17  )
    18  
    19  var _ = Describe("curl command", func() {
    20  	var ExpectHelpText = func(session *Session) {
    21  		Eventually(session).Should(Say(`NAME:\n`))
    22  		Eventually(session).Should(Say(`curl - Executes a request to the targeted API endpoint\n`))
    23  		Eventually(session).Should(Say(`\n`))
    24  
    25  		Eventually(session).Should(Say(`USAGE:\n`))
    26  		Eventually(session).Should(Say(`\s+cf curl PATH \[-iv\] \[-X METHOD\] \[-H HEADER\]\.\.\. \[-d DATA\] \[--output FILE\]`))
    27  		Eventually(session).Should(Say(`\s+By default 'cf curl' will perform a GET to the specified PATH. If data`))
    28  		Eventually(session).Should(Say(`\s+is provided via -d, a POST will be performed instead, and the Content-Type\n`))
    29  		Eventually(session).Should(Say(`\s+will be set to application/json. You may override headers with -H and the\n`))
    30  		Eventually(session).Should(Say(`\s+request method with -X.\n`))
    31  		Eventually(session).Should(Say(`\s+For API documentation, please visit http://apidocs.cloudfoundry.org.\n`))
    32  		Eventually(session).Should(Say(`\n`))
    33  
    34  		Eventually(session).Should(Say(`EXAMPLES:\n`))
    35  		Eventually(session).Should(Say(`\s+cf curl \"/v2/apps\" -X GET -H \"Content-Type: application/x-www-form-urlencoded\" -d 'q=name:myapp'`))
    36  		Eventually(session).Should(Say(`\s+cf curl \"/v2/apps\" -d @/path/to/file`))
    37  		Eventually(session).Should(Say(`\n`))
    38  
    39  		Eventually(session).Should(Say(`OPTIONS:\n`))
    40  		Eventually(session).Should(Say(`\s+-H\s+Custom headers to include in the request, flag can be specified multiple times`))
    41  		Eventually(session).Should(Say(`\s+-X\s+HTTP method \(GET,POST,PUT,DELETE,etc\)`))
    42  		Eventually(session).Should(Say(`\s+-d\s+HTTP data to include in the request body, or '@' followed by a file name to read the data from`))
    43  		Eventually(session).Should(Say(`\s+--fail,\s+-f\s+Server errors return exit code 22`))
    44  		Eventually(session).Should(Say(`\s+-i\s+Include response headers in the output`))
    45  		Eventually(session).Should(Say(`\s+--output\s+Write curl body to FILE instead of stdout`))
    46  	}
    47  
    48  	var ExpectRequestHeaders = func(session *Session) {
    49  		Eventually(session).Should(Say(`REQUEST: .+`))
    50  		Eventually(session).Should(Say(`(GET|POST|PUT|DELETE) /v2/apps HTTP/1.1`))
    51  		Eventually(session).Should(Say(`Host: .+`))
    52  		Eventually(session).Should(Say(`Accept: .+`))
    53  		Eventually(session).Should(Say(`Authorization:\s+\[PRIVATE DATA HIDDEN\]`))
    54  		Eventually(session).Should(Say(`Content-Type: .+`))
    55  		Eventually(session).Should(Say(`User-Agent: .+`))
    56  	}
    57  
    58  	var ExpectResponseHeaders = func(session *Session) {
    59  		Eventually(session).Should(Say("HTTP/1.1 200 OK"))
    60  		Eventually(session).Should(Say(`Content-Length: .+`))
    61  		Eventually(session).Should(Say(`Content-Type: .+`))
    62  		Eventually(session).Should(Say(`Date: .+`))
    63  		Eventually(session).Should(Say(`Server: .+`))
    64  		Eventually(session).Should(Say(`X-Content-Type-Options: .+`))
    65  		Eventually(session).Should(Say(`X-Vcap-Request-Id: .+`))
    66  	}
    67  
    68  	Describe("Help Text", func() {
    69  		When("--help flag is set", func() {
    70  			It("appears in cf help -a", func() {
    71  				session := helpers.CF("help", "-a")
    72  				Eventually(session).Should(Exit(0))
    73  				Expect(session).To(HaveCommandInCategoryWithDescription("curl", "ADVANCED", "Executes a request to the targeted API endpoint"))
    74  			})
    75  
    76  			It("Displays command usage to the output", func() {
    77  				session := helpers.CF("curl", "--help")
    78  				ExpectHelpText(session)
    79  				Eventually(session).Should(Exit(0))
    80  			})
    81  		})
    82  	})
    83  
    84  	Describe("Incorrect Usage", func() {
    85  		When("no arguments are provided", func() {
    86  			It("fails and displays the help text", func() {
    87  				session := helpers.CF("curl")
    88  				Eventually(session.Err).Should(Say("Incorrect Usage: the required argument `PATH` was not provided"))
    89  				ExpectHelpText(session)
    90  				Eventually(session).Should(Exit(1))
    91  			})
    92  		})
    93  
    94  		When("unknown flag is specified", func() {
    95  			It("fails and displays the help text", func() {
    96  				session := helpers.CF("curl", "--test")
    97  				Eventually(session.Err).Should(Say("Incorrect Usage: unknown flag `test'"))
    98  				ExpectHelpText(session)
    99  				Eventually(session).Should(Exit(1))
   100  			})
   101  		})
   102  	})
   103  
   104  	When("the user is not logged in", func() {
   105  		It("makes the request and receives an unauthenticated error", func() {
   106  			session := helpers.CF("curl", "/v2/apps")
   107  			expectedJSON := `{
   108  				 "description": "Authentication error",
   109  				 "error_code": "CF-NotAuthenticated",
   110  				 "code": 10002
   111  			}`
   112  			Eventually(session).Should(Exit(0))
   113  			Expect(session.Out.Contents()).To(MatchJSON(expectedJSON))
   114  		})
   115  	})
   116  
   117  	Describe("User Agent", func() {
   118  		It("sets the User-Agent Header to contain the CLI version", func() {
   119  			getVersionNumber := func() string {
   120  				versionSession := helpers.CF("version")
   121  				Eventually(versionSession).Should(Exit(0))
   122  				versionPattern := regexp.MustCompile("cf version (.+)")
   123  				version := versionPattern.FindStringSubmatch(string(versionSession.Out.Contents()))
   124  				return regexp.QuoteMeta(version[1])
   125  			}
   126  			session := helpers.CF("curl", "/v2/info", "-v")
   127  			Eventually(session).Should(Exit(0))
   128  
   129  			Expect(session).To(Say(`User-Agent: cf/%s`, getVersionNumber()))
   130  		})
   131  	})
   132  
   133  	When("the user is logged in", func() {
   134  		var orgName string
   135  
   136  		BeforeEach(func() {
   137  			orgName = helpers.NewOrgName()
   138  			spaceName := helpers.NewSpaceName()
   139  
   140  			helpers.SetupCF(orgName, spaceName)
   141  			helpers.SwitchToOrgRole(orgName, "OrgManager")
   142  			helpers.TargetOrg(orgName)
   143  		})
   144  
   145  		When("the path is valid", func() {
   146  			var expectedJSON string
   147  
   148  			BeforeEach(func() {
   149  				expectedJSON = `{
   150              "total_results": 0,
   151              "total_pages": 1,
   152              "prev_url": null,
   153              "next_url": null,
   154              "resources": []
   155  				}`
   156  			})
   157  
   158  			When("the path has multiple initial slashes", func() {
   159  				It("changes the path to use only one slash", func() {
   160  					session := helpers.CF("curl", "////v2/apps", "-v")
   161  					Eventually(session).Should(Exit(0))
   162  
   163  					Eventually(session).Should(Say(`GET /v2/apps HTTP/1.1`))
   164  				})
   165  			})
   166  
   167  			When("the path has no initial slashes", func() {
   168  				It("prepends a slash to the path", func() {
   169  					session := helpers.CF("curl", "v2/apps", "-v")
   170  					Eventually(session).Should(Exit(0))
   171  
   172  					Eventually(session).Should(Say(`GET /v2/apps HTTP/1.1`))
   173  				})
   174  			})
   175  
   176  			When("no flag is set", func() {
   177  				It("makes the request and displays the json response", func() {
   178  					session := helpers.CF("curl", "/v2/apps")
   179  					Eventually(session).Should(Exit(0))
   180  					Expect(session.Out.Contents()).To(MatchJSON(expectedJSON))
   181  				})
   182  			})
   183  
   184  			When("-i flag is set", func() {
   185  				It("displays the response headers", func() {
   186  					session := helpers.CF("curl", "/v2/apps", "-i")
   187  					Eventually(session).Should(Exit(0))
   188  
   189  					ExpectResponseHeaders(session)
   190  					contents := string(session.Out.Contents())
   191  					jsonStartsAt := strings.Index(contents, "{")
   192  
   193  					actualJSON := contents[jsonStartsAt:]
   194  					Expect(actualJSON).To(MatchJSON(expectedJSON))
   195  				})
   196  			})
   197  
   198  			When("-v flag is set", func() {
   199  				It("displays the request headers and response headers", func() {
   200  					session := helpers.CF("curl", "/v2/apps", "-v")
   201  					Eventually(session).Should(Exit(0))
   202  
   203  					ExpectRequestHeaders(session)
   204  					ExpectResponseHeaders(session)
   205  
   206  					contents := string(session.Out.Contents())
   207  					jsonStartsAt := strings.Index(contents, "{")
   208  
   209  					actualJSON := contents[jsonStartsAt:]
   210  					Expect(actualJSON).To(MatchJSON(expectedJSON))
   211  				})
   212  			})
   213  
   214  			When("-H is passed with a custom header", func() {
   215  				When("the custom header is valid", func() {
   216  					It("add the custom header to the request", func() {
   217  						session := helpers.CF("curl", "/v2/apps", "-H", "X-Foo: bar", "-v")
   218  						Eventually(session).Should(Exit(0))
   219  
   220  						Expect(session).To(Say("REQUEST:"))
   221  						Expect(session).To(Say("X-Foo: bar"))
   222  						Expect(session).To(Say("RESPONSE:"))
   223  					})
   224  
   225  					When("multiple headers are provided", func() {
   226  						It("adds all the custom headers to the request", func() {
   227  							session := helpers.CF("curl", "/v2/apps", "-H", "X-Bar: bar", "-H", "X-Foo: foo", "-v")
   228  							Eventually(session).Should(Exit(0))
   229  
   230  							Expect(session).To(Say("REQUEST:"))
   231  							Expect(session).To(Say("X-Bar: bar"))
   232  							Expect(session).To(Say("X-Foo: foo"))
   233  							Expect(session).To(Say("RESPONSE:"))
   234  						})
   235  
   236  						When("the same header field is passed", func() {
   237  							It("adds the same header field twice", func() {
   238  								session := helpers.CF("curl", "/v2/apps", "-H", "X-Foo: bar", "-H", "X-Foo: foo", "-v")
   239  								Eventually(session).Should(Exit(0))
   240  
   241  								Expect(session).To(Say("REQUEST:"))
   242  								Expect(session).To(Say("X-Foo: bar"))
   243  								Expect(session).To(Say("X-Foo: foo"))
   244  								Expect(session).To(Say("RESPONSE:"))
   245  							})
   246  						})
   247  					})
   248  
   249  					When("-H is provided with a default header", func() {
   250  						It("overrides the value of User-Agent header", func() {
   251  							session := helpers.CF("curl", "/v2/apps", "-H", "User-Agent: smith", "-v")
   252  							Eventually(session).Should(Exit(0))
   253  
   254  							Expect(session).To(Say("REQUEST:"))
   255  							Expect(session).To(Say("User-Agent: smith"))
   256  							Expect(session).To(Say("RESPONSE:"))
   257  						})
   258  
   259  						It("does not override the Host header", func() {
   260  							getHost := func() string {
   261  								apiSession := helpers.CF("api")
   262  								Eventually(apiSession).Should(Exit(0))
   263  								output := string(apiSession.Out.Contents())
   264  								lines := strings.Split(output, "\n")
   265  								Expect(len(lines)).To(BeNumerically(">=", 1))
   266  								parts := strings.Split(lines[0], "//")
   267  								Expect(len(parts)).To(BeNumerically(">=", 2))
   268  								return parts[1]
   269  							}
   270  							session := helpers.CF("curl", "/v2/apps", "-H", "Host: example.com", "-v")
   271  							Eventually(session).Should(Exit(0))
   272  							Expect(session).To(Say("Host: " + getHost()))
   273  						})
   274  
   275  						It("overrides the value of Accept header", func() {
   276  							session := helpers.CF("curl", "/v2/apps", "-H", "Accept: application/xml", "-v")
   277  							Eventually(session).Should(Exit(0))
   278  
   279  							Expect(session).To(Say("REQUEST:"))
   280  							Expect(session).To(Say("Accept: application/xml"))
   281  							Expect(session).To(Say("RESPONSE:"))
   282  						})
   283  
   284  						It("overrides the value of Content-Type header", func() {
   285  							session := helpers.CF("curl", "/v2/apps", "-H", "Content-Type: application/xml", "-v")
   286  							Eventually(session).Should(Exit(0))
   287  
   288  							Expect(session).To(Say("REQUEST:"))
   289  							Expect(session).To(Say("Content-Type: application/xml"))
   290  							Expect(session).To(Say("RESPONSE:"))
   291  						})
   292  					})
   293  				})
   294  
   295  				When("the custom header is not valid", func() {
   296  					It("tells the user that the header is not valid", func() {
   297  						session := helpers.CF("curl", "/v2/apps", "-H", "not-a-valid-header", "-v")
   298  						Eventually(session).Should(Exit(1))
   299  
   300  						Expect(session).Should(Say("FAILED"))
   301  						Expect(session.Err).Should(Say(`Error creating request:.+not-a-valid-header`))
   302  					})
   303  				})
   304  			})
   305  
   306  			When("-d is passed with a request body", func() {
   307  				When("the request body is passed as a string", func() {
   308  					It("sets the method to POST and sends the body", func() {
   309  						orgGUID := helpers.GetOrgGUID(orgName)
   310  						spaceName := helpers.NewSpaceName()
   311  						jsonBody := fmt.Sprintf(`{"name":"%s", "organization_guid":"%s"}`, spaceName, orgGUID)
   312  						session := helpers.CF("curl", "/v2/spaces", "-d", jsonBody)
   313  						Eventually(session).Should(Exit(0))
   314  						Eventually(helpers.CF("space", spaceName)).Should(Exit(0))
   315  					})
   316  				})
   317  
   318  				When("the request body is passed as a file", func() {
   319  					var spaceName, filePath, dir string
   320  
   321  					BeforeEach(func() {
   322  						var err error
   323  						dir, err = ioutil.TempDir("", "curl-command")
   324  						Expect(err).ToNot(HaveOccurred())
   325  
   326  						filePath = filepath.Join(dir, "request_body.json")
   327  						orgGUID := helpers.GetOrgGUID(orgName)
   328  						spaceName = helpers.NewSpaceName()
   329  
   330  						jsonBody := fmt.Sprintf(`{"name":"%s", "organization_guid":"%s"}`, spaceName, orgGUID)
   331  						err = ioutil.WriteFile(filePath, []byte(jsonBody), 0666)
   332  						Expect(err).ToNot(HaveOccurred())
   333  					})
   334  
   335  					AfterEach(func() {
   336  						os.RemoveAll(dir)
   337  					})
   338  
   339  					It("sets the method to POST and sends the body", func() {
   340  						session := helpers.CF("curl", "/v2/spaces", "-d", "@"+filePath)
   341  						Eventually(session).Should(Exit(0))
   342  						Eventually(helpers.CF("space", spaceName)).Should(Exit(0))
   343  					})
   344  
   345  					When("the file does not exist", func() {
   346  						It("fails and displays an error message", func() {
   347  							_, err := os.Stat("this-file-does-not-exist")
   348  							Expect(os.IsExist(err)).To(BeFalse())
   349  
   350  							session := helpers.CF("curl", "/v2/spaces", "-d", "@this-file-does-not-exist")
   351  							Eventually(session).Should(Exit(1))
   352  							Expect(session).To(Say("FAILED"))
   353  						})
   354  					})
   355  
   356  					When("the file is a symlink", func() {
   357  						It("follows the symlink", func() {
   358  							linkPath := filepath.Join(dir, "link-name.json")
   359  							Expect(os.Symlink(filePath, linkPath)).To(Succeed())
   360  							session := helpers.CF("curl", "-d", "@"+linkPath, "/v2/spaces")
   361  							Eventually(session).Should(Exit(0))
   362  							Eventually(helpers.CF("space", spaceName)).Should(Exit(0))
   363  						})
   364  					})
   365  				})
   366  			})
   367  
   368  			When("-X is passed with the HTTP method", func() {
   369  				var spaceGUID, spaceName string
   370  
   371  				BeforeEach(func() {
   372  					spaceName = helpers.NewSpaceName()
   373  					helpers.CreateSpace(spaceName)
   374  					spaceGUID = helpers.GetSpaceGUID(spaceName)
   375  				})
   376  
   377  				It("changes the HTTP method of the request", func() {
   378  					path := fmt.Sprintf("/v2/spaces/%s", spaceGUID)
   379  					session := helpers.CF("curl", path, "-X", "DELETE", "-v")
   380  					Eventually(session).Should(Exit(0))
   381  
   382  					Eventually(helpers.CF("space", spaceName)).Should(Exit(1))
   383  				})
   384  			})
   385  
   386  			When("--output is passed with a file name", func() {
   387  				It("writes the response headers and body to the file", func() {
   388  					outFile, err := ioutil.TempFile("", "output*.json")
   389  					Expect(err).ToNot(HaveOccurred())
   390  					session := helpers.CF("curl", "/v2/apps", "-i", "--output", outFile.Name())
   391  					Eventually(session).Should(Exit(0))
   392  					Eventually(session).Should(Say("OK"))
   393  
   394  					body, err := ioutil.ReadFile(outFile.Name())
   395  					Expect(err).ToNot(HaveOccurred())
   396  
   397  					contents := string(body)
   398  					jsonStartsAt := strings.Index(contents, "{")
   399  
   400  					Expect(contents).To(ContainSubstring("HTTP/1.1 200 OK"))
   401  					Expect(contents).To(MatchRegexp(`Content-Length: .+`))
   402  					Expect(contents).To(MatchRegexp(`Content-Type: .+`))
   403  					Expect(contents).To(MatchRegexp(`Date: .+`))
   404  					Expect(contents).To(MatchRegexp(`Server: .+`))
   405  					Expect(contents).To(MatchRegexp(`X-Content-Type-Options: .+`))
   406  					Expect(contents).To(MatchRegexp(`X-Vcap-Request-Id: .+`))
   407  
   408  					actualJSON := contents[jsonStartsAt:]
   409  					Expect(actualJSON).To(MatchJSON(expectedJSON))
   410  				})
   411  
   412  				When("--output is passed and CF_TRACE is set to a file", func() {
   413  					var tempDir, traceFile, outFile string
   414  					BeforeEach(func() {
   415  						var err error
   416  						tempDir, err = ioutil.TempDir("", "")
   417  						Expect(err).ToNot(HaveOccurred())
   418  						traceFile = filepath.Join(tempDir, "trace.log")
   419  						outFile = filepath.Join(tempDir, "output")
   420  					})
   421  
   422  					AfterEach(func() {
   423  						Expect(os.RemoveAll(tempDir)).To(Succeed())
   424  					})
   425  
   426  					It("writes the response body to the --output file and everything to the trace file", func() {
   427  						session := helpers.CFWithEnv(map[string]string{"CF_TRACE": traceFile}, "curl", "/v2/apps", "--output", outFile)
   428  						Eventually(session).Should(Exit(0))
   429  
   430  						outBytes, err := ioutil.ReadFile(outFile)
   431  						Expect(err).ToNot(HaveOccurred())
   432  						Expect(string(outBytes)).To(MatchJSON(expectedJSON))
   433  
   434  						traceBytes, err := ioutil.ReadFile(traceFile)
   435  						Expect(err).ToNot(HaveOccurred())
   436  						Expect(traceBytes).To(ContainSubstring("REQUEST: "))
   437  						Expect(traceBytes).To(ContainSubstring("HTTP/1.1 200 OK"))
   438  					})
   439  				})
   440  			})
   441  
   442  			Describe("Flag combinations", func() {
   443  				When("-i and -v flags are set", func() {
   444  					It("prints both the request and response headers", func() {
   445  						session := helpers.CF("curl", "/v2/apps", "-v", "-i")
   446  						Eventually(session).Should(Exit(0))
   447  
   448  						ExpectRequestHeaders(session)
   449  						ExpectResponseHeaders(session)
   450  
   451  						contents := string(session.Out.Contents())
   452  						jsonStartsAt := strings.Index(contents, "{")
   453  
   454  						actualJSON := contents[jsonStartsAt:]
   455  						Expect(actualJSON).To(MatchJSON(expectedJSON))
   456  					})
   457  				})
   458  
   459  				XWhen("-v and --output flags are passed", func() {
   460  					It("prints the headers to the terminal and the response to the file", func() {
   461  						// TODO This is a bug in the legacy CLI. Please write the test and fix the bug after refactor [#162432878]
   462  					})
   463  				})
   464  
   465  				When("-X, -H and -d flags are passed", func() {
   466  					var spaceName, filePath, dir, jsonBody string
   467  
   468  					BeforeEach(func() {
   469  						var err error
   470  						dir, err = ioutil.TempDir("", "curl-command")
   471  						Expect(err).ToNot(HaveOccurred())
   472  
   473  						filePath = filepath.Join(dir, "request_body.json")
   474  						orgGUID := helpers.GetOrgGUID(orgName)
   475  						spaceName = helpers.NewSpaceName()
   476  
   477  						jsonBody = fmt.Sprintf(`{"name":"%s", "organization_guid":"%s"}`, spaceName, orgGUID)
   478  						err = ioutil.WriteFile(filePath, []byte(jsonBody), 0666)
   479  						Expect(err).ToNot(HaveOccurred())
   480  					})
   481  
   482  					AfterEach(func() {
   483  						os.RemoveAll(dir)
   484  					})
   485  
   486  					It("sets the custom header and use the request body from -d", func() {
   487  						session := helpers.CF("curl", "/v2/spaces", "-X", "POST", "-H", "X-Foo: foo", "-H", "X-Bar: bar", "-d", "@"+filePath, "-v")
   488  						Eventually(session).Should(Exit(0))
   489  
   490  						Expect(session).Should(Say("REQUEST:"))
   491  						Expect(session).Should(Say("POST"))
   492  
   493  						Expect(session).Should(Say("X-Bar: bar"))
   494  						Expect(session).Should(Say("X-Foo: foo"))
   495  
   496  						contents := string(session.Out.Contents())
   497  						outputContents := contents[strings.Index(contents, "X-Foo: foo"):]
   498  						jsonStartsAt := strings.Index(outputContents, "{")
   499  						jsonEndsAt := strings.Index(outputContents[jsonStartsAt:], "}")
   500  
   501  						actualJSON := outputContents[jsonStartsAt : jsonStartsAt+jsonEndsAt+1]
   502  						Expect(actualJSON).To(MatchJSON(jsonBody))
   503  
   504  						Expect(session).Should(Say("RESPONSE:"))
   505  
   506  						Eventually(helpers.CF("space", spaceName)).Should(Exit(0))
   507  					})
   508  				})
   509  			})
   510  
   511  			When("the auth token is invalid", func() {
   512  				var spaceGUID, spaceName string
   513  
   514  				BeforeEach(func() {
   515  					spaceName = helpers.NewSpaceName()
   516  					helpers.CreateSpace(spaceName)
   517  					spaceGUID = helpers.GetSpaceGUID(spaceName)
   518  				})
   519  
   520  				It("returns an Invalid Auth Token error", func() {
   521  					path := fmt.Sprintf("/v2/spaces/%s", spaceGUID)
   522  					authHeader := fmt.Sprintf("Authorization: %s", helpers.ExpiredAccessToken())
   523  					session := helpers.CF("curl", path, "-H", authHeader, "-X", "DELETE", "-v")
   524  					Eventually(session).Should(Exit(0))
   525  
   526  					Expect(session).To(Say("Invalid Auth Token"))
   527  				})
   528  			})
   529  		})
   530  
   531  		When("the path is invalid", func() {
   532  			It("makes the request and displays the unknown request json", func() {
   533  				expectedJSON := `{
   534  				 "description": "Unknown request",
   535  				 "error_code": "CF-NotFound",
   536  				 "code": 10000
   537  				}`
   538  				session := helpers.CF("curl", "/some-random-path")
   539  				Eventually(session).Should(Exit(0))
   540  				Expect(session.Out.Contents()).To(MatchJSON(expectedJSON))
   541  			})
   542  		})
   543  	})
   544  })