github.com/cloudfoundry/cli@v7.1.0+incompatible/util/ui/request_logger_terminal_display_test.go (about)

     1  package ui_test
     2  
     3  import (
     4  	"errors"
     5  	"regexp"
     6  	"time"
     7  
     8  	. "code.cloudfoundry.org/cli/util/ui"
     9  
    10  	. "github.com/onsi/ginkgo"
    11  	. "github.com/onsi/gomega"
    12  	. "github.com/onsi/gomega/gbytes"
    13  )
    14  
    15  var _ = Describe("Request Logger Terminal Display", func() {
    16  	var (
    17  		out     *Buffer
    18  		testUI  *UI
    19  		display *RequestLoggerTerminalDisplay
    20  	)
    21  
    22  	BeforeEach(func() {
    23  		out = NewBuffer()
    24  		testUI = NewTestUI(nil, out, NewBuffer())
    25  		display = testUI.RequestLoggerTerminalDisplay()
    26  		Expect(display.Start()).ToNot(HaveOccurred())
    27  	})
    28  
    29  	Describe("DisplayBody", func() {
    30  		It("displays the redacted value", func() {
    31  			err := display.DisplayBody([]byte("some-string body"))
    32  			Expect(err).ToNot(HaveOccurred())
    33  
    34  			err = display.Stop()
    35  			Expect(err).ToNot(HaveOccurred())
    36  
    37  			Expect(testUI.Out).To(Say(`\[PRIVATE DATA HIDDEN\]`))
    38  		})
    39  	})
    40  
    41  	Describe("DisplayDump", func() {
    42  		It("displays the passed in string", func() {
    43  			err := display.DisplayDump("some-dump-of-string")
    44  			Expect(err).ToNot(HaveOccurred())
    45  
    46  			err = display.Stop()
    47  			Expect(err).ToNot(HaveOccurred())
    48  
    49  			Expect(testUI.Out).To(Say("some-dump-of-string"))
    50  		})
    51  
    52  		It("redacts auth tokens and cookies", func() {
    53  			dump := `GET /apps/ce03a2e2-95c0-4f3b-abb9-32718d408c8b/stream HTTP/1.1
    54  Host: wss://doppler.bosh-lite.com:443
    55  Upgrade: websocket
    56  Connection: Upgrade
    57  Sec-WebSocket-Version: 13
    58  Sec-WebSocket-Key: [HIDDEN]
    59  Set-Cookie: please-redact-this
    60  Authorization: bearer eyJhbGciOiJSUzI1NiIsImtpZCI6ImtleS0xIiwidHlwIjoiSldUIn0.eyJqdGkiOiI3YzRmYWEyZjI5MmQ0MTQ5ODM5NGE3OTU0Y2E3ZWNlMCIsInN1YiI6IjIyMjNiM2IzLTE3ZTktNDJkNi1iNzQzLThjZjcyZWIwOWRlNSIsInNjb3BlIjpbInJvdXRpbmcucm91dGVyX2dyb3Vwcy5yZWFkIiwiY2xvdWRfY29udHJvbGxlci5yZWFkIiwicGFzc3dvcmQud3JpdGUiLCJjbG91ZF9jb250cm9sbGVyLndyaXRlIiwib3BlbmlkIiwicm91dGluZy5yb3V0ZXJfZ3JvdXBzLndyaXRlIiwiZG9wcGxlci5maXJlaG9zZSIsInNjaW0ud3JpdGUiLCJzY2ltLnJlYWQiLCJjbG91ZF9jb250cm9sbGVyLmFkbWluIiwidWFhLnVzZXIiXSwiY2xpZW50X2lkIjoiY2YiLCJjaWQiOiJjZiIsImF6cCI6ImNmIiwiZ3JhbnRfdHlwZSI6InBhc3N3b3JkIiwidXNlcl9pZCI6IjIyMjNiM2IzLTE3ZTktNDJkNi1iNzQzLThjZjcyZWIwOWRlNSIsIm9yaWdpbiI6InVhYSIsInVzZXJfbmFtZSI6ImFkbWluIiwiZW1haWwiOiJhZG1pbiIsInJldl9zaWciOiI4NDBiMDBhMyIsImlhdCI6MTQ5NjQyNTU5NiwiZXhwIjoxNDk2NDI2MTk2LCJpc3MiOiJodHRwczovL3VhYS5ib3NoLWxpdGUuY29tL29hdXRoL3Rva2VuIiwiemlkIjoidWFhIiwiYXVkIjpbInNjaW0iLCJjbG91ZF9jb250cm9sbGVyIiwicGFzc3dvcmQiLCJjZiIsInVhYSIsIm9wZW5pZCIsImRvcHBsZXIiLCJyb3V0aW5nLnJvdXRlcl9ncm91cHMiXX0.TFDmHviKcs-eeNoz79dVwOl-k_dHTdqHkyztont2qnBDchNSpWvR5Yba54MMG8uTUHM72YbCopxdyaLY-g8s5wJFGLaBocrDgqswUh3mQRvynQG6_zne1h_0oHXnm0U-ZPnTyV8qjtHUoLvks4GOuktXc6ZE3NriWODpKIU5WdMgEbvyhuTnUEn88rQnmGJbKvHOIilulb6avSkZfTEq1o8w4VLCeRDlVLNh5JzCUtGzLfImNb31ks_Wv6HuI8kFjQZ5PQiTYjlhkuDQOcNSaAyWxQ_7425hiA7x8omBgEr-uST7GsxLvgoHqQaDH0JSTgMmO_GaN_QD52JVuru9og
    61  Origin: wss://doppler.bosh-lite.com:443`
    62  			err := display.DisplayDump(dump)
    63  			Expect(err).ToNot(HaveOccurred())
    64  
    65  			err = display.Stop()
    66  			Expect(err).ToNot(HaveOccurred())
    67  
    68  			Expect(testUI.Out).To(Say("Connection: Upgrade"))
    69  			Expect(testUI.Out).To(Say(`Set-Cookie: \[PRIVATE DATA HIDDEN\]`))
    70  			Expect(testUI.Out).To(Say(`Authorization: \[PRIVATE DATA HIDDEN\]`))
    71  			Expect(testUI.Out).To(Say("Origin: wss://doppler.bosh-lite.com:443"))
    72  		})
    73  	})
    74  
    75  	Describe("DisplayHeader", func() {
    76  		It("displays the header key and value", func() {
    77  			err := display.DisplayHeader("Header", "Value")
    78  			Expect(err).ToNot(HaveOccurred())
    79  
    80  			err = display.Stop()
    81  			Expect(err).ToNot(HaveOccurred())
    82  
    83  			Expect(testUI.Out).To(Say("Header: Value"))
    84  		})
    85  	})
    86  
    87  	Describe("DisplayHost", func() {
    88  		It("displays the host", func() {
    89  			err := display.DisplayHost("banana")
    90  			Expect(err).ToNot(HaveOccurred())
    91  
    92  			err = display.Stop()
    93  			Expect(err).ToNot(HaveOccurred())
    94  
    95  			Expect(testUI.Out).To(Say("Host: banana"))
    96  		})
    97  	})
    98  
    99  	Describe("DisplayJSONBody", func() {
   100  		When("provided well formed JSON", func() {
   101  			It("displayed a formated output", func() {
   102  				raw := `{"a":"b", "c":"d", "don't html escape":"<&>"}`
   103  				formatted := `{
   104    "a": "b",
   105    "c": "d",
   106    "don't html escape": "<&>"
   107  }`
   108  				err := display.DisplayJSONBody([]byte(raw))
   109  				Expect(err).ToNot(HaveOccurred())
   110  
   111  				err = display.Stop()
   112  				Expect(err).ToNot(HaveOccurred())
   113  
   114  				Expect(testUI.Out).To(Say(formatted))
   115  			})
   116  		})
   117  
   118  		When("the body is empty", func() {
   119  			It("does not display the body", func() {
   120  				err := display.DisplayJSONBody(nil)
   121  				Expect(err).ToNot(HaveOccurred())
   122  
   123  				err = display.Stop()
   124  				Expect(err).ToNot(HaveOccurred())
   125  
   126  				Expect(string(out.Contents())).To(Equal("\n"))
   127  			})
   128  		})
   129  
   130  		When("provided malformed JSON", func() {
   131  			It("displays the raw body", func() {
   132  				raw := `[{"data":1, "banana": 2}`
   133  				err := display.DisplayJSONBody([]byte(raw))
   134  				Expect(err).ToNot(HaveOccurred())
   135  
   136  				err = display.Stop()
   137  				Expect(err).ToNot(HaveOccurred())
   138  
   139  				buff, ok := testUI.Out.(*Buffer)
   140  				Expect(ok).To(BeTrue())
   141  				Expect(string(buff.Contents())).To(Equal(raw + "\n\n"))
   142  			})
   143  		})
   144  	})
   145  
   146  	Describe("DisplayMessage", func() {
   147  		It("writes the message", func() {
   148  			msg := "i am a message!!!!"
   149  			err := display.DisplayMessage(msg)
   150  			Expect(err).ToNot(HaveOccurred())
   151  
   152  			err = display.Stop()
   153  			Expect(err).ToNot(HaveOccurred())
   154  
   155  			Expect(testUI.Out).To(Say(msg))
   156  		})
   157  	})
   158  
   159  	Describe("DisplayRequestHeader", func() {
   160  		It("displays the method, uri and http protocol", func() {
   161  			err := display.DisplayRequestHeader("GET", "/v2/spaces/guid/summary", "HTTP/1.1")
   162  			Expect(err).ToNot(HaveOccurred())
   163  
   164  			err = display.Stop()
   165  			Expect(err).ToNot(HaveOccurred())
   166  
   167  			Expect(testUI.Out).To(Say("GET /v2/spaces/guid/summary HTTP/1.1"))
   168  		})
   169  	})
   170  
   171  	Describe("DisplayResponseHeader", func() {
   172  		It("displays the method, uri and http protocol", func() {
   173  			err := display.DisplayResponseHeader("HTTP/1.1", "200 OK")
   174  			Expect(err).ToNot(HaveOccurred())
   175  
   176  			err = display.Stop()
   177  			Expect(err).ToNot(HaveOccurred())
   178  
   179  			Expect(testUI.Out).To(Say("HTTP/1.1 200 OK"))
   180  		})
   181  	})
   182  
   183  	Describe("DisplayType", func() {
   184  		It("displays the passed type and time in localized ISO 8601", func() {
   185  			passedTime := time.Now()
   186  			err := display.DisplayType("banana", passedTime)
   187  			Expect(err).ToNot(HaveOccurred())
   188  
   189  			err = display.Stop()
   190  			Expect(err).ToNot(HaveOccurred())
   191  
   192  			Expect(testUI.Out).To(Say(`banana: \[%s\]`, regexp.QuoteMeta(passedTime.Format(time.RFC3339))))
   193  		})
   194  	})
   195  
   196  	Describe("HandleInternalError", func() {
   197  		It("sends error to standard error", func() {
   198  			err := errors.New("foobar")
   199  			display.HandleInternalError(err)
   200  
   201  			err = display.Stop()
   202  			Expect(err).ToNot(HaveOccurred())
   203  
   204  			Expect(testUI.Err).To(Say("foobar"))
   205  		})
   206  	})
   207  
   208  	Describe("Start and Stop", func() {
   209  		It("locks and then unlocks the mutex properly", func() {
   210  			c := make(chan bool)
   211  			go func() {
   212  				Expect(display.Start()).NotTo(HaveOccurred())
   213  				c <- true
   214  			}()
   215  			Consistently(c).ShouldNot(Receive())
   216  			Expect(display.Stop()).NotTo(HaveOccurred())
   217  			Eventually(c).Should(Receive())
   218  			Expect(display.Stop()).NotTo(HaveOccurred())
   219  		})
   220  	})
   221  
   222  	Describe("UI", func() {
   223  		Describe("RequestLoggerTerminalDisplay", func() {
   224  			BeforeEach(func() {
   225  				Expect(display.Stop()).ToNot(HaveOccurred())
   226  			})
   227  
   228  			It("returns a RequestLoggerTerminalDisplay with the consistent display mutex", func() {
   229  				logger1 := testUI.RequestLoggerTerminalDisplay()
   230  				logger2 := testUI.RequestLoggerTerminalDisplay()
   231  
   232  				c := make(chan bool)
   233  				err := logger1.Start()
   234  				Expect(err).ToNot(HaveOccurred())
   235  				go func() {
   236  					Expect(logger2.Start()).ToNot(HaveOccurred())
   237  					c <- true
   238  				}()
   239  				Consistently(c).ShouldNot(Receive())
   240  				Expect(logger1.Stop()).ToNot(HaveOccurred())
   241  				Eventually(c).Should(Receive())
   242  			})
   243  		})
   244  	})
   245  })