github.com/loggregator/cli@v6.33.1-0.20180224010324-82334f081791+incompatible/cf/commands/curl_test.go (about)

     1  package commands_test
     2  
     3  import (
     4  	"io/ioutil"
     5  	"os"
     6  	"path/filepath"
     7  
     8  	"code.cloudfoundry.org/cli/cf/api/apifakes"
     9  	"code.cloudfoundry.org/cli/cf/configuration/coreconfig"
    10  	"code.cloudfoundry.org/cli/cf/errors"
    11  	"code.cloudfoundry.org/cli/cf/requirements"
    12  	"code.cloudfoundry.org/cli/cf/requirements/requirementsfakes"
    13  	testcmd "code.cloudfoundry.org/cli/util/testhelpers/commands"
    14  	testconfig "code.cloudfoundry.org/cli/util/testhelpers/configuration"
    15  	testterm "code.cloudfoundry.org/cli/util/testhelpers/terminal"
    16  	"code.cloudfoundry.org/gofileutils/fileutils"
    17  
    18  	"code.cloudfoundry.org/cli/cf/commandregistry"
    19  	"code.cloudfoundry.org/cli/cf/trace"
    20  	. "code.cloudfoundry.org/cli/util/testhelpers/matchers"
    21  	. "github.com/onsi/ginkgo"
    22  	. "github.com/onsi/gomega"
    23  )
    24  
    25  var _ = Describe("curl command", func() {
    26  	var (
    27  		ui                  *testterm.FakeUI
    28  		config              coreconfig.Repository
    29  		requirementsFactory *requirementsfakes.FakeFactory
    30  		curlRepo            *apifakes.OldFakeCurlRepository
    31  		deps                commandregistry.Dependency
    32  	)
    33  
    34  	updateCommandDependency := func(pluginCall bool) {
    35  		deps.UI = ui
    36  		deps.RepoLocator = deps.RepoLocator.SetCurlRepository(curlRepo)
    37  		deps.Config = config
    38  		commandregistry.Commands.SetCommand(commandregistry.Commands.FindCommand("curl").SetDependency(deps, pluginCall))
    39  	}
    40  
    41  	BeforeEach(func() {
    42  		ui = &testterm.FakeUI{}
    43  		config = testconfig.NewRepository()
    44  		requirementsFactory = new(requirementsfakes.FakeFactory)
    45  		requirementsFactory.NewAPIEndpointRequirementReturns(requirements.Passing{})
    46  		curlRepo = new(apifakes.OldFakeCurlRepository)
    47  
    48  		trace.LoggingToStdout = false
    49  	})
    50  
    51  	runCurlWithInputs := func(args []string) bool {
    52  		return testcmd.RunCLICommand("curl", args, requirementsFactory, updateCommandDependency, false, ui)
    53  	}
    54  
    55  	runCurlAsPluginWithInputs := func(args []string) bool {
    56  		return testcmd.RunCLICommand("curl", args, requirementsFactory, updateCommandDependency, true, ui)
    57  	}
    58  
    59  	It("fails with usage when not given enough input", func() {
    60  		runCurlWithInputs([]string{})
    61  		Expect(ui.Outputs()).To(ContainSubstrings(
    62  			[]string{"Incorrect Usage", "An argument is missing or not correctly enclosed"},
    63  		))
    64  	})
    65  
    66  	Context("requirements", func() {
    67  		Context("when no api is set", func() {
    68  			BeforeEach(func() {
    69  				requirementsFactory.NewAPIEndpointRequirementReturns(requirements.Failing{Message: "no api set"})
    70  			})
    71  
    72  			It("fails", func() {
    73  				Expect(runCurlWithInputs([]string{"/foo"})).To(BeFalse())
    74  			})
    75  		})
    76  
    77  		Context("when api is set", func() {
    78  			BeforeEach(func() {
    79  				requirementsFactory.NewAPIEndpointRequirementReturns(requirements.Passing{})
    80  			})
    81  
    82  			It("passes", func() {
    83  				Expect(runCurlWithInputs([]string{"/foo"})).To(BeTrue())
    84  			})
    85  		})
    86  	})
    87  
    88  	It("makes a get request given an endpoint", func() {
    89  		curlRepo.ResponseHeader = "Content-Size:1024"
    90  		curlRepo.ResponseBody = "response for get"
    91  		runCurlWithInputs([]string{"/foo"})
    92  
    93  		Expect(curlRepo.Method).To(Equal(""))
    94  		Expect(curlRepo.Path).To(Equal("/foo"))
    95  		Expect(ui.Outputs()).To(ContainSubstrings([]string{"response for get"}))
    96  		Expect(ui.Outputs()).ToNot(ContainSubstrings(
    97  			[]string{"FAILED"},
    98  			[]string{"Content-Size:1024"},
    99  		))
   100  	})
   101  
   102  	Context("when the --output flag is provided", func() {
   103  		It("saves the body of the response to the given filepath if it exists", func() {
   104  			fileutils.TempFile("poor-mans-pipe", func(tempFile *os.File, err error) {
   105  				Expect(err).ToNot(HaveOccurred())
   106  				curlRepo.ResponseBody = "hai"
   107  
   108  				runCurlWithInputs([]string{"--output", tempFile.Name(), "/foo"})
   109  				contents, err := ioutil.ReadAll(tempFile)
   110  				Expect(err).ToNot(HaveOccurred())
   111  				Expect(string(contents)).To(Equal("hai"))
   112  			})
   113  		})
   114  
   115  		It("saves the body of the response to the given filepath if it doesn't exists", func() {
   116  			fileutils.TempDir("poor-mans-dir", func(tmpDir string, err error) {
   117  				Expect(err).ToNot(HaveOccurred())
   118  				curlRepo.ResponseBody = "hai"
   119  
   120  				filePath := filepath.Join(tmpDir, "subdir1", "banana.txt")
   121  				runCurlWithInputs([]string{"--output", filePath, "/foo"})
   122  
   123  				file, err := os.Open(filePath)
   124  				Expect(err).ToNot(HaveOccurred())
   125  
   126  				contents, err := ioutil.ReadAll(file)
   127  				Expect(err).ToNot(HaveOccurred())
   128  				Expect(string(contents)).To(Equal("hai"))
   129  			})
   130  		})
   131  	})
   132  
   133  	It("makes a post request given -X", func() {
   134  		runCurlWithInputs([]string{"-X", "post", "/foo"})
   135  
   136  		Expect(curlRepo.Method).To(Equal("post"))
   137  		Expect(ui.Outputs()).ToNot(ContainSubstrings([]string{"FAILED"}))
   138  	})
   139  
   140  	It("sends headers given -H", func() {
   141  		runCurlWithInputs([]string{"-H", "Content-Type:cat", "/foo"})
   142  
   143  		Expect(curlRepo.Header).To(Equal("Content-Type:cat"))
   144  		Expect(ui.Outputs()).ToNot(ContainSubstrings([]string{"FAILED"}))
   145  	})
   146  
   147  	It("sends multiple headers given multiple -H flags", func() {
   148  		runCurlWithInputs([]string{"-H", "Content-Type:cat", "-H", "Content-Length:12", "/foo"})
   149  
   150  		Expect(curlRepo.Header).To(Equal("Content-Type:cat\nContent-Length:12"))
   151  		Expect(ui.Outputs()).ToNot(ContainSubstrings([]string{"FAILED"}))
   152  	})
   153  
   154  	It("prints out the response headers given -i", func() {
   155  		curlRepo.ResponseHeader = "Content-Size:1024"
   156  		curlRepo.ResponseBody = "response for get"
   157  		runCurlWithInputs([]string{"-i", "/foo"})
   158  
   159  		Expect(ui.Outputs()).To(ContainSubstrings(
   160  			[]string{"Content-Size:1024"},
   161  			[]string{"response for get"},
   162  		))
   163  		Expect(ui.Outputs()).ToNot(ContainSubstrings([]string{"FAILED"}))
   164  	})
   165  
   166  	Context("when -d is provided", func() {
   167  		It("sets the request body", func() {
   168  			runCurlWithInputs([]string{"-d", "body content to upload", "/foo"})
   169  
   170  			Expect(curlRepo.Body).To(Equal("body content to upload"))
   171  			Expect(ui.Outputs()).ToNot(ContainSubstrings([]string{"FAILED"}))
   172  		})
   173  
   174  		It("does not fail with empty string", func() {
   175  			runCurlWithInputs([]string{"/foo", "-d", ""})
   176  
   177  			Expect(curlRepo.Body).To(Equal(""))
   178  			Expect(curlRepo.Method).To(Equal("POST"))
   179  			Expect(ui.Outputs()).NotTo(ContainSubstrings([]string{"FAILED"}))
   180  		})
   181  
   182  		It("uses given http verb if -X is also provided", func() {
   183  			runCurlWithInputs([]string{"/foo", "-d", "some body", "-X", "PUT"})
   184  
   185  			Expect(curlRepo.Body).To(Equal("some body"))
   186  			Expect(curlRepo.Method).To(Equal("PUT"))
   187  			Expect(ui.Outputs()).NotTo(ContainSubstrings([]string{"FAILED"}))
   188  		})
   189  
   190  		It("sets the request body with an @-prefixed file", func() {
   191  			tempfile, err := ioutil.TempFile("", "get-data-test")
   192  			Expect(err).NotTo(HaveOccurred())
   193  			defer os.RemoveAll(tempfile.Name())
   194  			jsonData := `{"some":"json"}`
   195  			ioutil.WriteFile(tempfile.Name(), []byte(jsonData), os.ModePerm)
   196  
   197  			runCurlWithInputs([]string{"-d", "@" + tempfile.Name(), "/foo"})
   198  
   199  			Expect(curlRepo.Body).To(Equal(`{"some":"json"}`))
   200  			Expect(ui.Outputs()).ToNot(ContainSubstrings([]string{"FAILED"}))
   201  		})
   202  	})
   203  
   204  	It("does not print the response when verbose output is enabled", func() {
   205  		// This is to prevent the response from being printed twice
   206  
   207  		trace.LoggingToStdout = true
   208  
   209  		curlRepo.ResponseHeader = "Content-Size:1024"
   210  		curlRepo.ResponseBody = "response for get"
   211  
   212  		runCurlWithInputs([]string{"/foo"})
   213  
   214  		Expect(ui.Outputs()).ToNot(ContainSubstrings([]string{"response for get"}))
   215  	})
   216  
   217  	It("prints the response even when verbose output is enabled if in a plugin call", func() {
   218  		trace.LoggingToStdout = true
   219  
   220  		curlRepo.ResponseHeader = "Content-Size:1024"
   221  		curlRepo.ResponseBody = "response for get"
   222  
   223  		runCurlAsPluginWithInputs([]string{"/foo"})
   224  
   225  		Expect(ui.Outputs()).To(ContainSubstrings([]string{"response for get"}))
   226  	})
   227  
   228  	It("prints a failure message when the response is not success", func() {
   229  		curlRepo.Error = errors.New("ooops")
   230  		runCurlWithInputs([]string{"/foo"})
   231  
   232  		Expect(ui.Outputs()).To(ContainSubstrings(
   233  			[]string{"FAILED"},
   234  			[]string{"ooops"},
   235  		))
   236  	})
   237  
   238  	Context("Whent the content type is JSON", func() {
   239  		BeforeEach(func() {
   240  			curlRepo.ResponseHeader = "Content-Type: application/json;charset=utf-8"
   241  			curlRepo.ResponseBody = `{"total_results":0,"total_pages":1,"prev_url":null,"next_url":null,"resources":[]}`
   242  		})
   243  
   244  		It("pretty-prints the response body", func() {
   245  			runCurlWithInputs([]string{"/ugly-printed-json-endpoint"})
   246  
   247  			Expect(ui.Outputs()).To(ContainSubstrings(
   248  				[]string{"{"},
   249  				[]string{"  \"total_results", "0"},
   250  				[]string{"  \"total_pages", "1"},
   251  				[]string{"  \"prev_url", "null"},
   252  				[]string{"  \"next_url", "null"},
   253  				[]string{"  \"resources", "[]"},
   254  				[]string{"}"},
   255  			))
   256  		})
   257  
   258  		Context("But the body is not JSON", func() {
   259  			BeforeEach(func() {
   260  				curlRepo.ResponseBody = "FAIL: crumpets need MOAR butterz"
   261  			})
   262  
   263  			It("regular-prints the response body", func() {
   264  				runCurlWithInputs([]string{"/whateverz"})
   265  
   266  				Expect(ui.Outputs()).To(Equal([]string{"FAIL: crumpets need MOAR butterz"}))
   267  			})
   268  		})
   269  	})
   270  })