github.com/go-playground/pkg/v5@v5.29.1/net/http/retryable_test.go (about)

     1  //go:build go1.18
     2  // +build go1.18
     3  
     4  package httpext
     5  
     6  import (
     7  	"context"
     8  	. "github.com/go-playground/assert/v2"
     9  	bytesext "github.com/go-playground/pkg/v5/bytes"
    10  	errorsext "github.com/go-playground/pkg/v5/errors"
    11  	optionext "github.com/go-playground/pkg/v5/values/option"
    12  	"net/http"
    13  	"net/http/httptest"
    14  	"testing"
    15  )
    16  
    17  func TestDoRetryable(t *testing.T) {
    18  
    19  	ctx := context.Background()
    20  	type response struct {
    21  		Name string `json:"name"`
    22  	}
    23  	expected := "Joey Bloggs"
    24  	var requests int
    25  
    26  	mux := http.NewServeMux()
    27  	mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
    28  		requests++
    29  		if requests < 3 {
    30  			w.WriteHeader(http.StatusServiceUnavailable)
    31  			return
    32  		}
    33  		Equal(t, JSON(w, http.StatusOK, response{Name: expected}), nil)
    34  	})
    35  
    36  	server := httptest.NewServer(mux)
    37  	defer server.Close()
    38  
    39  	fn := func(ctx context.Context) (*http.Request, error) {
    40  		return http.NewRequestWithContext(ctx, http.MethodGet, server.URL, nil)
    41  	}
    42  	retryCount := 0
    43  	dummyOnRetryFn := func(ctx context.Context, origErr error, reason string, attempt int) optionext.Option[error] {
    44  		retryCount++
    45  		return optionext.None[error]()
    46  	}
    47  
    48  	result := DoRetryable[response](ctx, errorsext.IsRetryableHTTP, dummyOnRetryFn, IsRetryableStatusCode, nil, http.StatusOK, bytesext.MiB, fn)
    49  	Equal(t, result.IsErr(), false)
    50  	Equal(t, result.Unwrap().Name, expected)
    51  	Equal(t, retryCount, 2)
    52  }