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

View File

@@ -4,4 +4,4 @@ test:
.PHONY: integration
integration:
go test -count=1 -v -run "Auction" ./test/integration -integration=true
go test -count=1 -v ./test/integration -integration=true

View File

@@ -6,12 +6,10 @@ import (
"flag"
"fmt"
"io"
"net/http"
"net/url"
"os"
"strings"
"testing"
"time"
_ "github.com/joho/godotenv/autoload"
"github.com/jybp/ebay"
@@ -23,7 +21,6 @@ var (
integration bool
clientID string
clientSecret string
auctionURL string
redirectURL string
)
@@ -35,21 +32,28 @@ func init() {
}
clientID = os.Getenv("SANDBOX_CLIENT_ID")
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 == "" {
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 {
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?).
auctionURL = os.Getenv("SANDOX_AUCTION_URL")
ctx := context.Background()
conf := clientcredentials.Config{
ClientID: clientID,
@@ -77,9 +81,7 @@ func TestAuction(t *testing.T) {
if !isAuction {
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)
b := make([]byte, 16)
@@ -87,30 +89,11 @@ func TestAuction(t *testing.T) {
t.Fatalf("%+v", err)
}
state := url.QueryEscape(string(b))
authCodeC := make(chan string)
mux := setupTLS()
mux.HandleFunc("/accept", func(rw http.ResponseWriter, r *http.Request) {
actualState, err := url.QueryUnescape(r.URL.Query().Get("state"))
serve, teardown, authCodeC, err := oauthServer("ebay test", ":52125", state)
if err != nil {
http.Error(rw, fmt.Sprintf("invalid state: %+v", err), http.StatusBadRequest)
return
t.Fatalf("%+v", err)
}
if string(actualState) != state {
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."))
})
go func() { serve() }()
oauthConf := oauth2.Config{
ClientID: clientID,
@@ -124,6 +107,7 @@ func TestAuction(t *testing.T) {
fmt.Printf("Visit the URL: %v\n", url)
authCode := <-authCodeC
defer func() { teardown() }()
tok, err := oauthConf.Exchange(ctx, authCode)
if err != nil {

View File

@@ -1,25 +1,20 @@
package integration
// From https://gist.github.com/shivakar/cd52b5594d4912fbeb46
import (
"crypto/rand"
"crypto/rsa"
"crypto/tls"
"crypto/x509"
"crypto/x509/pkix"
"fmt"
"log"
"math/big"
"net"
"net/http"
"net/url"
"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 {
*net.TCPListener
keepAlivePeriod time.Duration
@@ -47,41 +42,62 @@ func tlsCert(name string, dur time.Duration) (tls.Certificate, error) {
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth},
KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature | x509.KeyUsageCertSign,
}
priv, err := rsa.GenerateKey(rand.Reader, 2048)
if err != nil {
return tls.Certificate{}, err
}
cert, err := x509.CreateCertificate(rand.Reader, template, template, priv.Public(), priv)
if err != nil {
return tls.Certificate{}, err
}
var outCert tls.Certificate
outCert.Certificate = append(outCert.Certificate, cert)
outCert.PrivateKey = priv
return outCert, nil
}
func setupTLS() *http.ServeMux {
cert, err := tlsCert("eSniper", time.Hour)
func oauthHandler(state string) (http.Handler, <-chan string) {
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 {
log.Fatal(err)
}
mux := http.NewServeMux()
srv := &http.Server{Addr: ":52125", Handler: mux}
handler, authCodeC := oauthHandler(state)
srv := &http.Server{Addr: addr, Handler: handler}
cfg := &tls.Config{}
cfg.NextProtos = []string{"http/1.1"}
cfg.Certificates = make([]tls.Certificate, 1)
cfg.Certificates[0] = cert
ln, err := net.Listen("tcp", ":52125")
ln, err := net.Listen("tcp", addr)
if err != nil {
log.Fatal(err)
return nil, nil, nil, err
}
tlsListener := tls.NewListener(tcpKeepAliveListener{ln.(*net.TCPListener), time.Minute}, cfg)
go func() {
srv.Serve(tlsListener)
}()
return mux
return func() error { return srv.Serve(tlsListener) }, srv.Close, authCodeC, nil
}