github.com/Financial-Times/publish-availability-monitor@v1.12.0/httpcaller/httpCaller_test.go (about) 1 package httpcaller 2 3 import ( 4 "encoding/base64" 5 "net/http" 6 "net/http/httptest" 7 "strings" 8 "testing" 9 10 "github.com/stretchr/testify/assert" 11 ) 12 13 func stubServer(t *testing.T, expectedMethod string, expectedHeaders map[string]string, expectedBody []byte) *httptest.Server { 14 server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 15 assert.Equal(t, expectedMethod, r.Method, "HTTP method") 16 for k, v := range expectedHeaders { 17 actualValue := r.Header.Get(k) 18 assert.Equal(t, v, actualValue, k+" header") 19 } 20 21 if expectedBody != nil { 22 actualBody := make([]byte, 1024) 23 defer r.Body.Close() 24 size, _ := r.Body.Read(actualBody) 25 assert.Equal(t, expectedBody, actualBody[0:size], "entity") 26 // reflect.DeepEqual() 27 } 28 29 w.WriteHeader(http.StatusOK) 30 _, _ = w.Write([]byte("Hello world")) 31 })) 32 33 return server 34 } 35 36 func assertExpectedResponse(t *testing.T, resp *http.Response) { 37 by := make([]byte, 32) 38 i, _ := resp.Body.Read(by) 39 body := string(by[:i]) 40 41 assert.Equal(t, http.StatusOK, resp.StatusCode, "response status") 42 assert.Equal(t, "Hello world", body, "response body") 43 } 44 45 func TestUnauthenticated(t *testing.T) { 46 server := stubServer(t, "GET", map[string]string{ 47 "User-Agent": "UPP Publish Availability Monitor", 48 }, nil) 49 defer server.Close() 50 51 httpCaller := NewCaller(10) 52 resp, err := httpCaller.DoCall(Config{URL: server.URL}) 53 assert.Nil(t, err, "unexpected error") 54 55 assertExpectedResponse(t, resp) 56 } 57 58 func TestAuthenticated(t *testing.T) { 59 username := "scott" 60 password := "tiger" 61 apiKey := "someApiKey" 62 63 server := stubServer(t, "GET", map[string]string{ 64 "User-Agent": "UPP Publish Availability Monitor", 65 "Authorization": "Basic " + base64.StdEncoding.EncodeToString([]byte(username+":"+password)), 66 "X-Api-Key": apiKey, 67 }, nil) 68 defer server.Close() 69 70 httpCaller := NewCaller(10) 71 resp, err := httpCaller.DoCall(Config{URL: server.URL, Username: username, Password: password, APIKey: apiKey}) 72 assert.Nil(t, err, "unexpected error") 73 74 assertExpectedResponse(t, resp) 75 } 76 77 func TestTransactionId(t *testing.T) { 78 tid := "tid_myTxId" 79 80 server := stubServer(t, "GET", map[string]string{ 81 "User-Agent": "UPP Publish Availability Monitor", 82 "X-Request-Id": tid, 83 }, nil) 84 defer server.Close() 85 86 httpCaller := NewCaller(10) 87 resp, err := httpCaller.DoCall(Config{URL: server.URL, TID: tid}) 88 assert.Nil(t, err, "unexpected error") 89 90 assertExpectedResponse(t, resp) 91 } 92 93 func TestRequestWithEntity(t *testing.T) { 94 contentType := "text/plain" 95 body := "Hello world" 96 97 server := stubServer(t, "POST", 98 map[string]string{ 99 "User-Agent": "UPP Publish Availability Monitor", 100 "Content-Type": contentType, 101 }, 102 []byte(body), 103 ) 104 defer server.Close() 105 106 httpCaller := NewCaller(10) 107 resp, err := httpCaller.DoCall(Config{HTTPMethod: "POST", URL: server.URL, ContentType: contentType, Entity: strings.NewReader(body)}) 108 assert.Nil(t, err, "unexpected error") 109 110 assertExpectedResponse(t, resp) 111 } 112 113 func TestClientDoesRetry(t *testing.T) { 114 var retryCount int 115 server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 116 retryCount++ 117 if retryCount%2 != 0 { 118 w.WriteHeader(http.StatusInternalServerError) 119 return 120 } 121 w.WriteHeader(http.StatusOK) 122 })) 123 defer server.Close() 124 125 httpCaller := NewCaller(10) 126 _, err := httpCaller.DoCall(Config{HTTPMethod: "GET", URL: server.URL}) //nolint:bodyclose 127 assert.NoError(t, err) 128 assert.Equal(t, 2, retryCount) 129 } 130 131 func TestClientDoesOnlyTwoRetries(t *testing.T) { 132 var retryCount int 133 server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 134 retryCount++ 135 w.WriteHeader(http.StatusInternalServerError) 136 })) 137 defer server.Close() 138 139 httpCaller := NewCaller(10) 140 _, err := httpCaller.DoCall(Config{HTTPMethod: "GET", URL: server.URL}) //nolint:bodyclose 141 assert.NoError(t, err) 142 assert.Equal(t, 2, retryCount) 143 } 144 145 func TestClientDoesNoRetryAfterSuccessfullResponse(t *testing.T) { 146 var retryCount int 147 server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 148 retryCount++ 149 w.WriteHeader(http.StatusOK) 150 })) 151 defer server.Close() 152 153 httpCaller := NewCaller(10) 154 _, err := httpCaller.DoCall(Config{HTTPMethod: "GET", URL: server.URL}) //nolint:bodyclose 155 assert.NoError(t, err) 156 assert.Equal(t, 1, retryCount) 157 }