github.com/asifdxtreme/cli@v6.1.3-0.20150123051144-9ead8700b4ae+incompatible/cf/commands/curl_test.go (about)

     1  package commands_test
     2  
     3  import (
     4  	"bytes"
     5  	"io/ioutil"
     6  	"os"
     7  	"path/filepath"
     8  
     9  	testapi "github.com/cloudfoundry/cli/cf/api/fakes"
    10  	"github.com/cloudfoundry/cli/cf/configuration/core_config"
    11  	"github.com/cloudfoundry/cli/cf/errors"
    12  	"github.com/cloudfoundry/cli/cf/trace"
    13  	testcmd "github.com/cloudfoundry/cli/testhelpers/commands"
    14  	testconfig "github.com/cloudfoundry/cli/testhelpers/configuration"
    15  	testreq "github.com/cloudfoundry/cli/testhelpers/requirements"
    16  	testterm "github.com/cloudfoundry/cli/testhelpers/terminal"
    17  	"github.com/cloudfoundry/gofileutils/fileutils"
    18  
    19  	. "github.com/cloudfoundry/cli/cf/commands"
    20  	. "github.com/cloudfoundry/cli/testhelpers/matchers"
    21  	. "github.com/onsi/ginkgo"
    22  	. "github.com/onsi/gomega"
    23  )
    24  
    25  var _ = Describe("curl command", func() {
    26  	var deps curlDependencies
    27  
    28  	BeforeEach(func() {
    29  		deps = newCurlDependencies()
    30  	})
    31  
    32  	It("does not pass requirements when not logged in", func() {
    33  		Expect(runCurlWithInputs(deps, []string{"/foo"})).To(BeFalse())
    34  	})
    35  
    36  	Context("when logged in", func() {
    37  		BeforeEach(func() {
    38  			deps.requirementsFactory.LoginSuccess = true
    39  		})
    40  
    41  		It("fails with usage when not given enough input", func() {
    42  			runCurlWithInputs(deps, []string{})
    43  			Expect(deps.ui.FailedWithUsage).To(BeTrue())
    44  		})
    45  
    46  		It("passes requirements", func() {
    47  			Expect(runCurlWithInputs(deps, []string{"/foo"})).To(BeTrue())
    48  		})
    49  
    50  		It("makes a get request given an endpoint", func() {
    51  			deps.curlRepo.ResponseHeader = "Content-Size:1024"
    52  			deps.curlRepo.ResponseBody = "response for get"
    53  			runCurlWithInputs(deps, []string{"/foo"})
    54  
    55  			Expect(deps.curlRepo.Method).To(Equal("GET"))
    56  			Expect(deps.curlRepo.Path).To(Equal("/foo"))
    57  			Expect(deps.ui.Outputs).To(ContainSubstrings([]string{"response for get"}))
    58  			Expect(deps.ui.Outputs).ToNot(ContainSubstrings(
    59  				[]string{"FAILED"},
    60  				[]string{"Content-Size:1024"},
    61  			))
    62  		})
    63  
    64  		Context("when the --output flag is provided", func() {
    65  			It("saves the body of the response to the given filepath if it exists", func() {
    66  				fileutils.TempFile("poor-mans-pipe", func(tempFile *os.File, err error) {
    67  					Expect(err).ToNot(HaveOccurred())
    68  					deps.curlRepo.ResponseBody = "hai"
    69  
    70  					runCurlWithInputs(deps, []string{"--output", tempFile.Name(), "/foo"})
    71  					contents, err := ioutil.ReadAll(tempFile)
    72  					Expect(err).ToNot(HaveOccurred())
    73  					Expect(string(contents)).To(Equal("hai"))
    74  				})
    75  			})
    76  
    77  			It("saves the body of the response to the given filepath if it doesn't exists", func() {
    78  				fileutils.TempDir("poor-mans-dir", func(tmpDir string, err error) {
    79  					Expect(err).ToNot(HaveOccurred())
    80  					deps.curlRepo.ResponseBody = "hai"
    81  
    82  					filePath := filepath.Join(tmpDir, "subdir1", "banana.txt")
    83  					runCurlWithInputs(deps, []string{"--output", filePath, "/foo"})
    84  
    85  					file, err := os.Open(filePath)
    86  					Expect(err).ToNot(HaveOccurred())
    87  
    88  					contents, err := ioutil.ReadAll(file)
    89  					Expect(err).ToNot(HaveOccurred())
    90  					Expect(string(contents)).To(Equal("hai"))
    91  				})
    92  			})
    93  		})
    94  
    95  		It("makes a post request given -X", func() {
    96  			runCurlWithInputs(deps, []string{"-X", "post", "/foo"})
    97  
    98  			Expect(deps.curlRepo.Method).To(Equal("post"))
    99  			Expect(deps.ui.Outputs).ToNot(ContainSubstrings([]string{"FAILED"}))
   100  		})
   101  
   102  		It("sends headers given -H", func() {
   103  			runCurlWithInputs(deps, []string{"-H", "Content-Type:cat", "/foo"})
   104  
   105  			Expect(deps.curlRepo.Header).To(Equal("Content-Type:cat"))
   106  			Expect(deps.ui.Outputs).ToNot(ContainSubstrings([]string{"FAILED"}))
   107  		})
   108  
   109  		It("sends multiple headers given multiple -H flags", func() {
   110  			runCurlWithInputs(deps, []string{"-H", "Content-Type:cat", "-H", "Content-Length:12", "/foo"})
   111  
   112  			Expect(deps.curlRepo.Header).To(Equal("Content-Type:cat\nContent-Length:12"))
   113  			Expect(deps.ui.Outputs).ToNot(ContainSubstrings([]string{"FAILED"}))
   114  		})
   115  
   116  		It("prints out the response headers given -i", func() {
   117  			deps.curlRepo.ResponseHeader = "Content-Size:1024"
   118  			deps.curlRepo.ResponseBody = "response for get"
   119  			runCurlWithInputs(deps, []string{"-i", "/foo"})
   120  
   121  			Expect(deps.ui.Outputs).To(ContainSubstrings(
   122  				[]string{"Content-Size:1024"},
   123  				[]string{"response for get"},
   124  			))
   125  			Expect(deps.ui.Outputs).ToNot(ContainSubstrings([]string{"FAILED"}))
   126  		})
   127  
   128  		It("sets the request body given -d", func() {
   129  			runCurlWithInputs(deps, []string{"-d", "body content to upload", "/foo"})
   130  
   131  			Expect(deps.curlRepo.Body).To(Equal("body content to upload"))
   132  			Expect(deps.ui.Outputs).ToNot(ContainSubstrings([]string{"FAILED"}))
   133  		})
   134  
   135  		It("prints verbose output given the -v flag", func() {
   136  			output := bytes.NewBuffer(make([]byte, 1024))
   137  			trace.SetStdout(output)
   138  
   139  			runCurlWithInputs(deps, []string{"-v", "/foo"})
   140  			trace.Logger.Print("logging enabled")
   141  
   142  			Expect([]string{output.String()}).To(ContainSubstrings([]string{"logging enabled"}))
   143  		})
   144  
   145  		It("prints a failure message when the response is not success", func() {
   146  			deps.curlRepo.Error = errors.New("ooops")
   147  			runCurlWithInputs(deps, []string{"/foo"})
   148  
   149  			Expect(deps.ui.Outputs).To(ContainSubstrings(
   150  				[]string{"FAILED"},
   151  				[]string{"ooops"},
   152  			))
   153  		})
   154  
   155  		Context("Whent the content type is JSON", func() {
   156  			BeforeEach(func() {
   157  				deps.curlRepo.ResponseHeader = "Content-Type: application/json;charset=utf-8"
   158  				deps.curlRepo.ResponseBody = `{"total_results":0,"total_pages":1,"prev_url":null,"next_url":null,"resources":[]}`
   159  			})
   160  
   161  			It("pretty-prints the response body", func() {
   162  				runCurlWithInputs(deps, []string{"/ugly-printed-json-endpoint"})
   163  
   164  				Expect(deps.ui.Outputs).To(ContainSubstrings(
   165  					[]string{"{"},
   166  					[]string{"  \"total_results", "0"},
   167  					[]string{"  \"total_pages", "1"},
   168  					[]string{"  \"prev_url", "null"},
   169  					[]string{"  \"next_url", "null"},
   170  					[]string{"  \"resources", "[]"},
   171  					[]string{"}"},
   172  				))
   173  			})
   174  
   175  			Context("But the body is not JSON", func() {
   176  				BeforeEach(func() {
   177  					deps.curlRepo.ResponseBody = "FAIL: crumpets need MOAR butterz"
   178  				})
   179  
   180  				It("regular-prints the response body", func() {
   181  					runCurlWithInputs(deps, []string{"/whateverz"})
   182  
   183  					Expect(deps.ui.Outputs).To(Equal([]string{"FAIL: crumpets need MOAR butterz"}))
   184  				})
   185  			})
   186  		})
   187  	})
   188  })
   189  
   190  type curlDependencies struct {
   191  	ui                  *testterm.FakeUI
   192  	config              core_config.Reader
   193  	requirementsFactory *testreq.FakeReqFactory
   194  	curlRepo            *testapi.FakeCurlRepository
   195  }
   196  
   197  func newCurlDependencies() (deps curlDependencies) {
   198  	deps.ui = &testterm.FakeUI{}
   199  	deps.config = testconfig.NewRepository()
   200  	deps.requirementsFactory = &testreq.FakeReqFactory{}
   201  	deps.curlRepo = &testapi.FakeCurlRepository{}
   202  	return
   203  }
   204  
   205  func runCurlWithInputs(deps curlDependencies, args []string) bool {
   206  	cmd := NewCurl(deps.ui, deps.config, deps.curlRepo)
   207  	return testcmd.RunCommand(cmd, args, deps.requirementsFactory)
   208  }