Cleanup integration test

This commit is contained in:
JBP
2019-08-18 23:09:14 +02:00
parent 9d5f5e56a5
commit 84d4471770
3 changed files with 56 additions and 56 deletions
+1 -1
View File
@@ -4,4 +4,4 @@ test:
.PHONY: integration .PHONY: integration
integration: integration:
go test -count=1 -v -run "Auction" ./test/integration -integration=true go test -count=1 -v ./test/integration -integration=true
@@ -6,12 +6,10 @@ import (
"flag" "flag"
"fmt" "fmt"
"io" "io"
"net/http"
"net/url" "net/url"
"os" "os"
"strings" "strings"
"testing" "testing"
"time"
_ "github.com/joho/godotenv/autoload" _ "github.com/joho/godotenv/autoload"
"github.com/jybp/ebay" "github.com/jybp/ebay"
@@ -23,7 +21,6 @@ var (
integration bool integration bool
clientID string clientID string
clientSecret string clientSecret string
auctionURL string
redirectURL string redirectURL string
) )
@@ -35,21 +32,28 @@ func init() {
} }
clientID = os.Getenv("SANDBOX_CLIENT_ID") clientID = os.Getenv("SANDBOX_CLIENT_ID")
clientSecret = os.Getenv("SANDBOX_CLIENT_SECRET") clientSecret = os.Getenv("SANDBOX_CLIENT_SECRET")
redirectURL = os.Getenv("SANDBOX_REDIRECT_URL")
// Your accept redirect URL should be setup to redirect to https://localhost:52125/accept
redirectURL = os.Getenv("SANDBOX_RU_NAME")
if clientID == "" || clientSecret == "" || redirectURL == "" { if clientID == "" || clientSecret == "" || redirectURL == "" {
panic("Please set SANDBOX_CLIENT_ID, SANDBOX_CLIENT_SECRET and SANDBOX_REDIRECT_URL.") panic("Please set SANDBOX_CLIENT_ID, SANDBOX_CLIENT_SECRET and SANDBOX_REDIRECT_URL.")
} }
} }
func TestAuction(t *testing.T) { // TestGrantFlows is a verbose integration test that checks the client credentials grant flow as well as the
// authorization code grant flow are working properly on the eBay sandbox.
// Make sure to set the various environment variables required.
func TestGrantFlows(t *testing.T) {
if !integration { if !integration {
t.SkipNow() t.SkipNow()
} }
ctx := context.Background() // You have to manually create an auction in the sandbox and retrieve its URL.
// Auctions can't be created using the rest api (yet?).
auctionURL := os.Getenv("SANDOX_AUCTION_URL")
// You have to manually create an auction in the sandbox. Auctions can't be created using the rest api (yet?). ctx := context.Background()
auctionURL = os.Getenv("SANDOX_AUCTION_URL")
conf := clientcredentials.Config{ conf := clientcredentials.Config{
ClientID: clientID, ClientID: clientID,
@@ -77,9 +81,7 @@ func TestAuction(t *testing.T) {
if !isAuction { if !isAuction {
t.Fatalf("item %s is not an auction. BuyingOptions are: %+v", it.ItemID, it.BuyingOptions) t.Fatalf("item %s is not an auction. BuyingOptions are: %+v", it.ItemID, it.BuyingOptions)
} }
if time.Now().UTC().After(it.ItemEndDate) {
t.Fatalf("item %s end date has been reached. ItemEndDate is: %s", it.ItemID, it.ItemEndDate.String())
}
t.Logf("item %s UniqueBidderCount:%d minimumBidPrice: %+v currentPriceToBid: %+v\n", it.ItemID, it.UniqueBidderCount, it.MinimumPriceToBid, it.CurrentBidPrice) t.Logf("item %s UniqueBidderCount:%d minimumBidPrice: %+v currentPriceToBid: %+v\n", it.ItemID, it.UniqueBidderCount, it.MinimumPriceToBid, it.CurrentBidPrice)
b := make([]byte, 16) b := make([]byte, 16)
@@ -87,30 +89,11 @@ func TestAuction(t *testing.T) {
t.Fatalf("%+v", err) t.Fatalf("%+v", err)
} }
state := url.QueryEscape(string(b)) state := url.QueryEscape(string(b))
authCodeC := make(chan string) serve, teardown, authCodeC, err := oauthServer("ebay test", ":52125", state)
mux := setupTLS()
mux.HandleFunc("/accept", func(rw http.ResponseWriter, r *http.Request) {
actualState, err := url.QueryUnescape(r.URL.Query().Get("state"))
if err != nil { if err != nil {
http.Error(rw, fmt.Sprintf("invalid state: %+v", err), http.StatusBadRequest) t.Fatalf("%+v", err)
return
} }
if string(actualState) != state { go func() { serve() }()
http.Error(rw, fmt.Sprintf("invalid state:\nexpected:%s\nactual:%s", state, string(actualState)), http.StatusBadRequest)
return
}
code := r.URL.Query().Get("code")
authCodeC <- code
t.Logf("The authorization code is %s.\n", code)
t.Logf("The authorization code will expire in %s seconds.\n", r.URL.Query().Get("expires_in"))
rw.Write([]byte("Accept. You can safely close this tab."))
})
mux.HandleFunc("/policy", func(rw http.ResponseWriter, r *http.Request) {
rw.Write([]byte("eBay Sniper Policy"))
})
mux.HandleFunc("/decline", func(rw http.ResponseWriter, r *http.Request) {
rw.Write([]byte("Decline. You can safely close this tab."))
})
oauthConf := oauth2.Config{ oauthConf := oauth2.Config{
ClientID: clientID, ClientID: clientID,
@@ -124,6 +107,7 @@ func TestAuction(t *testing.T) {
fmt.Printf("Visit the URL: %v\n", url) fmt.Printf("Visit the URL: %v\n", url)
authCode := <-authCodeC authCode := <-authCodeC
defer func() { teardown() }()
tok, err := oauthConf.Exchange(ctx, authCode) tok, err := oauthConf.Exchange(ctx, authCode)
if err != nil { if err != nil {
@@ -1,25 +1,20 @@
package integration package integration
// From https://gist.github.com/shivakar/cd52b5594d4912fbeb46
import ( import (
"crypto/rand" "crypto/rand"
"crypto/rsa" "crypto/rsa"
"crypto/tls" "crypto/tls"
"crypto/x509" "crypto/x509"
"crypto/x509/pkix" "crypto/x509/pkix"
"fmt"
"log" "log"
"math/big" "math/big"
"net" "net"
"net/http" "net/http"
"net/url"
"time" "time"
) )
// From https://golang.org/src/net/http/server.go
// tcpKeepAliveListener sets TCP keep-alive timeouts on accepted
// connections. It's used by ListenAndServe and ListenAndServeTLS so
// dead TCP connections (e.g. closing laptop mid-download) eventually
// go away.
type tcpKeepAliveListener struct { type tcpKeepAliveListener struct {
*net.TCPListener *net.TCPListener
keepAlivePeriod time.Duration keepAlivePeriod time.Duration
@@ -47,41 +42,62 @@ func tlsCert(name string, dur time.Duration) (tls.Certificate, error) {
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth}, ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth},
KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature | x509.KeyUsageCertSign, KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature | x509.KeyUsageCertSign,
} }
priv, err := rsa.GenerateKey(rand.Reader, 2048) priv, err := rsa.GenerateKey(rand.Reader, 2048)
if err != nil { if err != nil {
return tls.Certificate{}, err return tls.Certificate{}, err
} }
cert, err := x509.CreateCertificate(rand.Reader, template, template, priv.Public(), priv) cert, err := x509.CreateCertificate(rand.Reader, template, template, priv.Public(), priv)
if err != nil { if err != nil {
return tls.Certificate{}, err return tls.Certificate{}, err
} }
var outCert tls.Certificate var outCert tls.Certificate
outCert.Certificate = append(outCert.Certificate, cert) outCert.Certificate = append(outCert.Certificate, cert)
outCert.PrivateKey = priv outCert.PrivateKey = priv
return outCert, nil return outCert, nil
} }
func setupTLS() *http.ServeMux { func oauthHandler(state string) (http.Handler, <-chan string) {
cert, err := tlsCert("eSniper", time.Hour) authCodeC := make(chan string)
mux := http.NewServeMux()
mux.HandleFunc("/accept", func(rw http.ResponseWriter, r *http.Request) {
actualState, err := url.QueryUnescape(r.URL.Query().Get("state"))
if err != nil {
http.Error(rw, fmt.Sprintf("invalid state: %v", err), http.StatusBadRequest)
return
}
if string(actualState) != state {
http.Error(rw, fmt.Sprintf("state mismatch"), http.StatusBadRequest)
return
}
code := r.URL.Query().Get("code")
authCodeC <- code
rw.Write([]byte("The test will proceed. You can safely close this tab."))
})
mux.HandleFunc("/policy", func(rw http.ResponseWriter, r *http.Request) {
rw.Write([]byte("Accept for the test to proceed."))
})
mux.HandleFunc("/decline", func(rw http.ResponseWriter, r *http.Request) {
close(authCodeC)
rw.Write([]byte("Accept for the test to proceed."))
})
return mux, authCodeC
}
func oauthServer(name, addr, state string) (serve func() error, teardown func() error, authCode <-chan string, err error) {
cert, err := tlsCert(name, time.Hour)
if err != nil { if err != nil {
log.Fatal(err) log.Fatal(err)
} }
mux := http.NewServeMux() handler, authCodeC := oauthHandler(state)
srv := &http.Server{Addr: ":52125", Handler: mux} srv := &http.Server{Addr: addr, Handler: handler}
cfg := &tls.Config{} cfg := &tls.Config{}
cfg.NextProtos = []string{"http/1.1"} cfg.NextProtos = []string{"http/1.1"}
cfg.Certificates = make([]tls.Certificate, 1) cfg.Certificates = make([]tls.Certificate, 1)
cfg.Certificates[0] = cert cfg.Certificates[0] = cert
ln, err := net.Listen("tcp", ":52125") ln, err := net.Listen("tcp", addr)
if err != nil { if err != nil {
log.Fatal(err) return nil, nil, nil, err
} }
tlsListener := tls.NewListener(tcpKeepAliveListener{ln.(*net.TCPListener), time.Minute}, cfg) tlsListener := tls.NewListener(tcpKeepAliveListener{ln.(*net.TCPListener), time.Minute}, cfg)
go func() { return func() error { return srv.Serve(tlsListener) }, srv.Close, authCodeC, nil
srv.Serve(tlsListener)
}()
return mux
} }