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  }