github.com/stripe/stripe-go/v76@v76.25.0/testing/testing.go (about)

     1  package testing
     2  
     3  import (
     4  	"crypto/tls"
     5  	"fmt"
     6  	"net/http"
     7  	"os"
     8  	"strconv"
     9  	"strings"
    10  
    11  	stripe "github.com/stripe/stripe-go/v76"
    12  	"github.com/stripe/stripe-go/v76/form"
    13  	"golang.org/x/net/http2"
    14  )
    15  
    16  // This file should contain any testing helpers that should be commonly
    17  // available across all tests in the Stripe package.
    18  //
    19  // There's not much in here because it' a relatively recent addition to the
    20  // package, but should be used as appropriate for any new changes.
    21  
    22  const (
    23  	// MockMinimumVersion is the minimum acceptable version for stripe-mock.
    24  	// It's here so that if the library depends on new endpoints or features
    25  	// added in a more recent version of stripe-mock, we can show people a
    26  	// better error message instead of the test suite crashing with a bunch of
    27  	// confusing 404 errors or the like.
    28  	MockMinimumVersion = "0.109.0"
    29  
    30  	// TestMerchantID is a token that can be used to represent a merchant ID in
    31  	// simple tests.
    32  	TestMerchantID = "acct_123"
    33  )
    34  
    35  func init() {
    36  	// Enable strict mode on form encoding so that we'll panic if any kind of
    37  	// malformed param struct is detected
    38  	form.Strict = true
    39  
    40  	port := os.Getenv("STRIPE_MOCK_PORT")
    41  	if port == "" {
    42  		port = "12112"
    43  	}
    44  
    45  	// stripe-mock's certificate for localhost is self-signed so configure a
    46  	// specialized client that skips the certificate authority check.
    47  	transport := &http.Transport{
    48  		TLSClientConfig: &tls.Config{
    49  			InsecureSkipVerify: true,
    50  		},
    51  	}
    52  
    53  	// Go can often enable HTTP/2 automatically if it's supported, but
    54  	// confusingly, if you set `TLSClientConfig`, it disables it and you have
    55  	// to explicitly invoke http2's `ConfigureTransport` to get it back.
    56  	//
    57  	// See the incorrectly closed bug report here:
    58  	//
    59  	//     https://github.com/golang/go/issues/20645
    60  	//
    61  	err := http2.ConfigureTransport(transport)
    62  	if err != nil {
    63  		fmt.Fprintf(os.Stderr, "Failed to initialize HTTP/2 transport: %v\n", err)
    64  		os.Exit(1)
    65  	}
    66  
    67  	httpClient := &http.Client{
    68  		Transport: transport,
    69  	}
    70  
    71  	resp, err := httpClient.Get("https://localhost:" + port)
    72  	if err != nil {
    73  		fmt.Fprintf(os.Stderr, "Couldn't reach stripe-mock at `localhost:%s` (%v). Is "+
    74  			"it running? Please see README for setup instructions.\n", port, err)
    75  		os.Exit(1)
    76  	}
    77  	version := resp.Header.Get("Stripe-Mock-Version")
    78  	if version != "master" && compareVersions(version, MockMinimumVersion) > 0 {
    79  		fmt.Fprintf(os.Stderr, "Your version of stripe-mock (%s) is too old. The "+
    80  			"minimum version to run this test suite is %s. Please see its "+
    81  			"repository for upgrade instructions.\n", version, MockMinimumVersion)
    82  		os.Exit(1)
    83  	}
    84  
    85  	stripe.Key = "sk_test_myTestKey"
    86  
    87  	// Configure a backend for stripe-mock and set it for both the API and
    88  	// Uploads (unlike the real Stripe API, stripe-mock supports both these
    89  	// backends).
    90  	stripeMockBackend := stripe.GetBackendWithConfig(
    91  		stripe.APIBackend,
    92  		&stripe.BackendConfig{
    93  			URL:           stripe.String("https://localhost:" + port),
    94  			HTTPClient:    httpClient,
    95  			LeveledLogger: stripe.DefaultLeveledLogger,
    96  		},
    97  	)
    98  	stripe.SetBackend(stripe.APIBackend, stripeMockBackend)
    99  	stripe.SetBackend(stripe.UploadsBackend, stripeMockBackend)
   100  }
   101  
   102  // compareVersions compares two semantic version strings. We need this because
   103  // with more complex double-digit numbers, lexical comparison breaks down.
   104  func compareVersions(a, b string) (ret int) {
   105  	as := strings.Split(a, ".")
   106  	bs := strings.Split(b, ".")
   107  
   108  	loopMax := len(bs)
   109  	if len(as) > len(bs) {
   110  		loopMax = len(as)
   111  	}
   112  
   113  	for i := 0; i < loopMax; i++ {
   114  		var x, y string
   115  		if len(as) > i {
   116  			x = as[i]
   117  		}
   118  		if len(bs) > i {
   119  			y = bs[i]
   120  		}
   121  
   122  		xi, _ := strconv.Atoi(x)
   123  		yi, _ := strconv.Atoi(y)
   124  
   125  		if xi > yi {
   126  			ret = -1
   127  		} else if xi < yi {
   128  			ret = 1
   129  		}
   130  		if ret != 0 {
   131  			break
   132  		}
   133  	}
   134  	return
   135  }