Initial implementation of HTTP mock testing framework (#310)

* Initial implementation of HTTP mock testing framework

Convert to VCR testing server. Segregate live testing via build tags.

Converted Binance to VCR server

Convert Bitstamp to VCR mocking tests

Added VCR mock testing for localbitcoins

* Add server generation for concurrent testing

* Fix linter issues

* Fix linter issue

* fix race - potentially

* revert auto assigning of host vals

* Fix requested changes

* Adds mock testing for ANX
Switch to using TestMain functionality
Added cron job usage for travis-ci to live testing
Added appveyor scheduled build check for live testing

* WOOPS

* silly correction

* Fixes fantastic linter issues

* fixed another whoopsie

* WOOO!

* Adds gemini mock testing with additional fixes

* Add docs and sharedvalue

* Added tls using httptest package

* Fixed issues

* added explicit mock recording reference to error

* Fix requested changes

* strip port from mock files as they are not needed on tls server

* Change incorrect names

* fix requested changes

* lbank update

* Fix another issue

* Updated readme
This commit is contained in:
Ryan O'Hara-Reid
2019-08-23 15:20:02 +10:00
committed by Adrian Gallagher
parent a81ddead9e
commit 6d8ba0a96a
79 changed files with 109268 additions and 1250 deletions

View File

@@ -1,6 +1,7 @@
package bitstamp
import (
"bytes"
"encoding/json"
"errors"
"fmt"
@@ -176,7 +177,6 @@ func (b *Bitstamp) GetFee(feeBuilder *exchange.FeeBuilder) (float64, error) {
switch feeBuilder.FeeType {
case exchange.CryptocurrencyTradeFee:
var err error
b.Balance, err = b.GetBalance()
if err != nil {
return 0, err
@@ -368,16 +368,15 @@ func (b *Bitstamp) GetEURUSDConversionRate() (EURUSDConversionRate, error) {
// GetBalance returns full balance of currency held on the exchange
func (b *Bitstamp) GetBalance() (Balances, error) {
balance := Balances{}
path := fmt.Sprintf("%s/%s", b.APIUrl, bitstampAPIBalance)
return balance, b.SendHTTPRequest(path, &balance)
var balance Balances
return balance,
b.SendAuthenticatedHTTPRequest(bitstampAPIBalance, true, nil, &balance)
}
// GetUserTransactions returns an array of transactions
func (b *Bitstamp) GetUserTransactions(currencyPair string) ([]UserTransactions, error) {
type Response struct {
Date int64 `json:"datetime"`
Date string `json:"datetime"`
TransID int64 `json:"id"`
Type int `json:"type,string"`
USD interface{} `json:"usd"`
@@ -390,12 +389,18 @@ func (b *Bitstamp) GetUserTransactions(currencyPair string) ([]UserTransactions,
}
var response []Response
if currencyPair != "" {
if err := b.SendAuthenticatedHTTPRequest(bitstampAPIUserTransactions, true, url.Values{}, &response); err != nil {
if currencyPair == "" {
if err := b.SendAuthenticatedHTTPRequest(bitstampAPIUserTransactions,
true,
url.Values{},
&response); err != nil {
return nil, err
}
} else {
if err := b.SendAuthenticatedHTTPRequest(bitstampAPIUserTransactions+"/"+currencyPair, true, url.Values{}, &response); err != nil {
if err := b.SendAuthenticatedHTTPRequest(bitstampAPIUserTransactions+"/"+currencyPair,
true,
url.Values{},
&response); err != nil {
return nil, err
}
}
@@ -491,10 +496,11 @@ func (b *Bitstamp) PlaceOrder(currencyPair string, price, amount float64, buy, m
orderType = bitstampAPISell
}
path := fmt.Sprintf("%s/%s", orderType, common.StringToLower(currencyPair))
var path string
if market {
path = fmt.Sprintf("%s/%s/%s", orderType, bitstampAPIMarket, common.StringToLower(currencyPair))
} else {
path = fmt.Sprintf("%s/%s", orderType, common.StringToLower(currencyPair))
}
return response,
@@ -651,28 +657,41 @@ func (b *Bitstamp) GetUnconfirmedBitcoinDeposits() ([]UnconfirmedBTCTransactions
// currency - which currency to transfer
// subaccount - name of account
// toMain - bool either to or from account
func (b *Bitstamp) TransferAccountBalance(amount float64, currency, subAccount string, toMain bool) (bool, error) {
func (b *Bitstamp) TransferAccountBalance(amount float64, currency, subAccount string, toMain bool) error {
var req = url.Values{}
req.Add("amount", strconv.FormatFloat(amount, 'f', -1, 64))
req.Add("currency", currency)
if subAccount == "" {
return errors.New("missing subAccount parameter")
}
req.Add("subAccount", subAccount)
path := bitstampAPITransferToMain
if !toMain {
var path string
if toMain {
path = bitstampAPITransferToMain
} else {
path = bitstampAPITransferFromMain
}
err := b.SendAuthenticatedHTTPRequest(path, true, req, nil)
if err != nil {
return false, err
}
var resp interface{}
return true, nil
return b.SendAuthenticatedHTTPRequest(path, true, req, &resp)
}
// SendHTTPRequest sends an unauthenticated HTTP request
func (b *Bitstamp) SendHTTPRequest(path string, result interface{}) error {
return b.SendPayload(http.MethodGet, path, nil, nil, result, false, false, b.Verbose, b.HTTPDebugging)
return b.SendPayload(http.MethodGet,
path,
nil,
nil,
result,
false,
false,
b.Verbose,
b.HTTPDebugging,
b.HTTPRecording)
}
// SendAuthenticatedHTTPRequest sends an authenticated request
@@ -706,15 +725,26 @@ func (b *Bitstamp) SendAuthenticatedHTTPRequest(path string, v2 bool, values url
headers["Content-Type"] = "application/x-www-form-urlencoded"
encodedValues := values.Encode()
readerValues := strings.NewReader(encodedValues)
readerValues := bytes.NewBufferString(encodedValues)
interim := json.RawMessage{}
errCap := struct {
Error string `json:"error"`
Error string `json:"error"`
Status string `json:"status"`
Reason interface{} `json:"reason"`
}{}
err := b.SendPayload(http.MethodPost, path, headers, readerValues, &interim, true, true, b.Verbose, b.HTTPDebugging)
err := b.SendPayload(http.MethodPost,
path,
headers,
readerValues,
&interim,
true,
true,
b.Verbose,
b.HTTPDebugging,
b.HTTPRecording)
if err != nil {
return err
}
@@ -723,6 +753,21 @@ func (b *Bitstamp) SendAuthenticatedHTTPRequest(path string, v2 bool, values url
if errCap.Error != "" {
return errors.New(errCap.Error)
}
if data, ok := errCap.Reason.(map[string][]string); ok {
var details string
for _, v := range data {
details += strings.Join(v, "")
}
return errors.New(details)
}
if data, ok := errCap.Reason.(string); ok {
return errors.New(data)
}
if errCap.Status != "" {
return errors.New(errCap.Status)
}
}
return common.JSONDecode(interim, result)

View File

@@ -0,0 +1,33 @@
//+build mock_test_off
// This will build if build tag mock_test_off is parsed and will do live testing
// using all tests in (exchange)_test.go
package bitstamp
import (
"log"
"os"
"testing"
"github.com/thrasher-corp/gocryptotrader/config"
"github.com/thrasher-corp/gocryptotrader/exchanges/sharedtestvalues"
)
var mockTests = false
func TestMain(m *testing.M) {
cfg := config.GetConfig()
cfg.LoadConfig("../../testdata/configtest.json")
bitstampConfig, err := cfg.GetExchangeConfig("Bitstamp")
if err != nil {
log.Fatal("Test Failed - Bitstamp Setup() init error", err)
}
bitstampConfig.AuthenticatedAPISupport = true
bitstampConfig.APIKey = apiKey
bitstampConfig.APISecret = apiSecret
bitstampConfig.ClientID = customerID
b.SetDefaults()
b.Setup(&bitstampConfig)
log.Printf(sharedtestvalues.LiveTesting, b.GetName(), b.APIUrl)
os.Exit(m.Run())
}

View File

@@ -0,0 +1,45 @@
//+build !mock_test_off
// This will build if build tag mock_test_off is not parsed and will try to mock
// all tests in _test.go
package bitstamp
import (
"log"
"os"
"testing"
"github.com/thrasher-corp/gocryptotrader/config"
"github.com/thrasher-corp/gocryptotrader/exchanges/mock"
"github.com/thrasher-corp/gocryptotrader/exchanges/sharedtestvalues"
)
const mockfile = "../../testdata/http_mock/bitstamp/bitstamp.json"
var mockTests = true
func TestMain(m *testing.M) {
cfg := config.GetConfig()
cfg.LoadConfig("../../testdata/configtest.json")
bitstampConfig, err := cfg.GetExchangeConfig("Bitstamp")
if err != nil {
log.Fatal("Test Failed - Bitstamp Setup() init error", err)
}
bitstampConfig.AuthenticatedAPISupport = true
bitstampConfig.APIKey = apiKey
bitstampConfig.APISecret = apiSecret
bitstampConfig.ClientID = customerID
b.SetDefaults()
b.Setup(&bitstampConfig)
serverDetails, newClient, err := mock.NewVCRServer(mockfile)
if err != nil {
log.Fatalf("Test Failed - Mock server error %s", err)
}
b.HTTPClient = newClient
b.APIUrl = serverDetails + "/api"
log.Printf(sharedtestvalues.MockTesting, b.GetName(), b.APIUrl)
os.Exit(m.Run())
}

View File

@@ -3,9 +3,7 @@ package bitstamp
import (
"net/url"
"testing"
"time"
"github.com/thrasher-corp/gocryptotrader/config"
"github.com/thrasher-corp/gocryptotrader/currency"
exchange "github.com/thrasher-corp/gocryptotrader/exchanges"
)
@@ -20,45 +18,12 @@ const (
var b Bitstamp
func TestSetDefaults(t *testing.T) {
b.SetDefaults()
if b.Name != "Bitstamp" {
t.Error("Test Failed - SetDefaults() error")
}
if b.Enabled {
t.Error("Test Failed - SetDefaults() error")
}
if b.Verbose {
t.Error("Test Failed - SetDefaults() error")
}
if b.Websocket.IsEnabled() {
t.Error("Test Failed - SetDefaults() error")
}
if b.RESTPollingDelay != 10 {
t.Error("Test Failed - SetDefaults() error")
}
}
func TestSetup(t *testing.T) {
cfg := config.GetConfig()
cfg.LoadConfig("../../testdata/configtest.json")
bConfig, err := cfg.GetExchangeConfig("Bitstamp")
if err != nil {
t.Error("Test Failed - Bitstamp Setup() init error")
}
bConfig.APIKey = apiKey
bConfig.APISecret = apiSecret
bConfig.ClientID = customerID
b.Setup(&bConfig)
b.ClientID = customerID
if !b.IsEnabled() || b.RESTPollingDelay != time.Duration(10) ||
b.Verbose || b.Websocket.IsEnabled() || len(b.BaseCurrencies) < 1 ||
len(b.AvailablePairs) < 1 || len(b.EnabledPairs) < 1 {
t.Error("Test Failed - Bitstamp Setup values not set correctly")
func areTestAPIKeysSet() bool {
if b.APIKey != "" && b.APIKey != "Key" &&
b.APISecret != "" && b.APISecret != "Secret" {
return true
}
return false
}
func setFeeBuilder() *exchange.FeeBuilder {
@@ -72,53 +37,66 @@ func setFeeBuilder() *exchange.FeeBuilder {
// TestGetFeeByTypeOfflineTradeFee logic test
func TestGetFeeByTypeOfflineTradeFee(t *testing.T) {
t.Parallel()
var feeBuilder = setFeeBuilder()
b.GetFeeByType(feeBuilder)
if apiKey == "" || apiSecret == "" {
if !areTestAPIKeysSet() || mockTests {
if feeBuilder.FeeType != exchange.OfflineTradeFee {
t.Errorf("Expected %v, received %v", exchange.OfflineTradeFee, feeBuilder.FeeType)
t.Errorf("Expected %v, received %v",
exchange.OfflineTradeFee,
feeBuilder.FeeType)
}
} else {
if feeBuilder.FeeType != exchange.CryptocurrencyTradeFee {
t.Errorf("Expected %v, received %v", exchange.CryptocurrencyTradeFee, feeBuilder.FeeType)
t.Errorf("Expected %v, received %v",
exchange.CryptocurrencyTradeFee,
feeBuilder.FeeType)
}
}
}
func TestGetFee(t *testing.T) {
b.SetDefaults()
TestSetup(t)
t.Parallel()
var feeBuilder = setFeeBuilder()
// CryptocurrencyTradeFee Basic
if resp, err := b.GetFee(feeBuilder); resp != float64(0) || err != nil {
if resp, err := b.GetFee(feeBuilder); resp != float64(0) || (areTestAPIKeysSet() && err != nil) {
t.Error(err)
t.Errorf("Test Failed - GetFee() error. Expected: %f, Received: %f", float64(0), resp)
t.Errorf("Test Failed - GetFee() error. Expected: %f, Received: %f",
float64(0),
resp)
}
// CryptocurrencyTradeFee High quantity
feeBuilder = setFeeBuilder()
feeBuilder.Amount = 1000
feeBuilder.PurchasePrice = 1000
if resp, err := b.GetFee(feeBuilder); resp != float64(0) || err != nil {
t.Errorf("Test Failed - GetFee() error. Expected: %f, Received: %f", float64(0), resp)
if resp, err := b.GetFee(feeBuilder); resp != float64(0) || (areTestAPIKeysSet() && err != nil) {
t.Errorf("Test Failed - GetFee() error. Expected: %f, Received: %f",
float64(0),
resp)
t.Error(err)
}
// CryptocurrencyTradeFee IsMaker
feeBuilder = setFeeBuilder()
feeBuilder.IsMaker = true
if resp, err := b.GetFee(feeBuilder); resp != float64(0) || err != nil {
t.Errorf("Test Failed - GetFee() error. Expected: %f, Received: %f", float64(0), resp)
if resp, err := b.GetFee(feeBuilder); resp != float64(0) || (areTestAPIKeysSet() && err != nil) {
t.Errorf("Test Failed - GetFee() error. Expected: %f, Received: %f",
float64(0),
resp)
t.Error(err)
}
// CryptocurrencyTradeFee Negative purchase price
feeBuilder = setFeeBuilder()
feeBuilder.PurchasePrice = -1000
if resp, err := b.GetFee(feeBuilder); resp != float64(0) || err != nil {
t.Errorf("Test Failed - GetFee() error. Expected: %f, Received: %f", float64(0), resp)
if resp, err := b.GetFee(feeBuilder); resp != float64(0) || (areTestAPIKeysSet() && err != nil) {
t.Errorf("Test Failed - GetFee() error. Expected: %f, Received: %f",
float64(0),
resp)
t.Error(err)
}
@@ -126,7 +104,9 @@ func TestGetFee(t *testing.T) {
feeBuilder = setFeeBuilder()
feeBuilder.FeeType = exchange.CryptocurrencyWithdrawalFee
if resp, err := b.GetFee(feeBuilder); resp != float64(0) || err != nil {
t.Errorf("Test Failed - GetFee() error. Expected: %f, Received: %f", float64(0), resp)
t.Errorf("Test Failed - GetFee() error. Expected: %f, Received: %f",
float64(0),
resp)
t.Error(err)
}
@@ -134,7 +114,9 @@ func TestGetFee(t *testing.T) {
feeBuilder = setFeeBuilder()
feeBuilder.FeeType = exchange.CyptocurrencyDepositFee
if resp, err := b.GetFee(feeBuilder); resp != float64(0) || err != nil {
t.Errorf("Test Failed - GetFee() error. Expected: %f, Received: %f", float64(0), resp)
t.Errorf("Test Failed - GetFee() error. Expected: %f, Received: %f",
float64(0),
resp)
t.Error(err)
}
@@ -143,7 +125,9 @@ func TestGetFee(t *testing.T) {
feeBuilder.FeeType = exchange.InternationalBankDepositFee
feeBuilder.FiatCurrency = currency.HKD
if resp, err := b.GetFee(feeBuilder); resp != float64(7.5) || err != nil {
t.Errorf("Test Failed - GetFee() error. Expected: %f, Received: %f", float64(7.5), resp)
t.Errorf("Test Failed - GetFee() error. Expected: %f, Received: %f",
float64(7.5),
resp)
t.Error(err)
}
@@ -152,15 +136,15 @@ func TestGetFee(t *testing.T) {
feeBuilder.FeeType = exchange.InternationalBankWithdrawalFee
feeBuilder.FiatCurrency = currency.HKD
if resp, err := b.GetFee(feeBuilder); resp != float64(15) || err != nil {
t.Errorf("Test Failed - GetFee() error. Expected: %f, Received: %f", float64(15), resp)
t.Errorf("Test Failed - GetFee() error. Expected: %f, Received: %f",
float64(15),
resp)
t.Error(err)
}
}
func TestCalculateTradingFee(t *testing.T) {
b.SetDefaults()
TestSetup(t)
b.Balance = Balances{}
t.Parallel()
b.Balance.BTCUSDFee = 1
b.Balance.BTCEURFee = 0
@@ -182,18 +166,16 @@ func TestCalculateTradingFee(t *testing.T) {
func TestGetTicker(t *testing.T) {
t.Parallel()
_, err := b.GetTicker(currency.BTC.String()+currency.USD.String(), false)
if err != nil {
t.Error("Test Failed - GetTicker() error", err)
}
_, err = b.GetTicker(currency.BTC.String()+currency.USD.String(), true)
if err != nil {
t.Error("Test Failed - GetTicker() error", err)
}
}
func TestGetOrderbook(t *testing.T) {
t.Parallel()
_, err := b.GetOrderbook(currency.BTC.String() + currency.USD.String())
if err != nil {
t.Error("Test Failed - GetOrderbook() error", err)
@@ -202,6 +184,7 @@ func TestGetOrderbook(t *testing.T) {
func TestGetTradingPairs(t *testing.T) {
t.Parallel()
_, err := b.GetTradingPairs()
if err != nil {
t.Error("Test Failed - GetTradingPairs() error", err)
@@ -210,6 +193,7 @@ func TestGetTradingPairs(t *testing.T) {
func TestGetTransactions(t *testing.T) {
t.Parallel()
value := url.Values{}
value.Set("time", "hour")
@@ -217,14 +201,11 @@ func TestGetTransactions(t *testing.T) {
if err != nil {
t.Error("Test Failed - GetTransactions() error", err)
}
_, err = b.GetTransactions("wigwham", value)
if err == nil {
t.Error("Test Failed - GetTransactions() error")
}
}
func TestGetEURUSDConversionRate(t *testing.T) {
t.Parallel()
_, err := b.GetEURUSDConversionRate()
if err != nil {
t.Error("Test Failed - GetEURUSDConversionRate() error", err)
@@ -233,21 +214,28 @@ func TestGetEURUSDConversionRate(t *testing.T) {
func TestGetBalance(t *testing.T) {
t.Parallel()
_, err := b.GetBalance()
if err != nil {
switch {
case areTestAPIKeysSet() && err != nil && !mockTests:
t.Error("Test Failed - GetBalance() error", err)
case !areTestAPIKeysSet() && err == nil && !mockTests:
t.Error("Expecting an error when no keys are set")
case mockTests && err != nil:
t.Error("Test Failed - GetBalance() error", err)
}
}
func TestGetUserTransactions(t *testing.T) {
t.Parallel()
_, err := b.GetUserTransactions("")
if err == nil {
t.Error("Test Failed - GetUserTransactions() error", err)
}
_, err = b.GetUserTransactions("btcusd")
if err == nil {
_, err := b.GetUserTransactions("btcusd")
switch {
case areTestAPIKeysSet() && err != nil && !mockTests:
t.Error("Test Failed - GetUserTransactions() error", err)
case !areTestAPIKeysSet() && err == nil && !mockTests:
t.Error("Expecting an error when no keys are set")
case mockTests && err != nil:
t.Error("Test Failed - GetUserTransactions() error", err)
}
}
@@ -256,56 +244,27 @@ func TestGetOpenOrders(t *testing.T) {
t.Parallel()
_, err := b.GetOpenOrders("btcusd")
if err == nil {
switch {
case areTestAPIKeysSet() && err != nil && !mockTests:
t.Error("Test Failed - GetOpenOrders() error", err)
case !areTestAPIKeysSet() && err == nil && !mockTests:
t.Error("Expecting an error when no keys are set")
case mockTests && err != nil:
t.Error("Test Failed - GetOpenOrders() error", err)
}
_, err = b.GetOpenOrders("wigwham")
if err == nil {
t.Error("Test Failed - GetOpenOrders() error")
}
}
func TestGetOrderStatus(t *testing.T) {
t.Parallel()
if !areTestAPIKeysSet() {
t.Skip()
}
_, err := b.GetOrderStatus(1337)
if err == nil {
t.Error("Test Failed - GetOpenOrders() error")
}
}
func TestCancelExistingOrder(t *testing.T) {
t.Parallel()
resp, err := b.CancelExistingOrder(1337)
if err == nil || resp {
t.Error("Test Failed - CancelExistingOrder() error")
}
}
func TestCancelAllExistingOrders(t *testing.T) {
t.Parallel()
_, err := b.CancelAllExistingOrders()
if err == nil {
t.Error("Test Failed - CancelAllExistingOrders() error", err)
}
}
func TestPlaceOrder(t *testing.T) {
t.Parallel()
if !areTestAPIKeysSet() {
t.Skip()
}
_, err := b.PlaceOrder("btcusd", 0.01, 1, true, true)
if err == nil {
t.Error("Test Failed - PlaceOrder() error")
switch {
case areTestAPIKeysSet() && err != nil && !mockTests:
t.Error("Test Failed - GetOrderStatus() error", err)
case !areTestAPIKeysSet() && err == nil && !mockTests:
t.Error("Expecting an error when no keys are set")
case mockTests && err == nil:
t.Error("Expecting an error until a QA pass can be completed")
}
}
@@ -313,34 +272,13 @@ func TestGetWithdrawalRequests(t *testing.T) {
t.Parallel()
_, err := b.GetWithdrawalRequests(0)
if err == nil {
switch {
case areTestAPIKeysSet() && err != nil && !mockTests:
t.Error("Test Failed - GetWithdrawalRequests() error", err)
case !areTestAPIKeysSet() && err == nil && !mockTests:
t.Error("Expecting an error when no keys are set")
case mockTests && err != nil:
t.Error("Test Failed - GetWithdrawalRequests() error", err)
}
_, err = b.GetWithdrawalRequests(-1)
if err == nil {
t.Error("Test Failed - GetWithdrawalRequests() error")
}
}
func TestCryptoWithdrawal(t *testing.T) {
t.Parallel()
if !areTestAPIKeysSet() {
t.Skip()
}
_, err := b.CryptoWithdrawal(0, "bla", "btc", "", true)
if err == nil {
t.Error("Test Failed - CryptoWithdrawal() error", err)
}
}
func TestGetBitcoinDepositAddress(t *testing.T) {
t.Parallel()
_, err := b.GetCryptoDepositAddress(currency.BTC)
if err == nil {
t.Error("Test Failed - GetCryptoDepositAddress() error", err)
}
}
@@ -348,7 +286,12 @@ func TestGetUnconfirmedBitcoinDeposits(t *testing.T) {
t.Parallel()
_, err := b.GetUnconfirmedBitcoinDeposits()
if err == nil {
switch {
case areTestAPIKeysSet() && err != nil && !mockTests:
t.Error("Test Failed - GetUnconfirmedBitcoinDeposits() error", err)
case !areTestAPIKeysSet() && err == nil && !mockTests:
t.Error("Expecting an error when no keys are set")
case mockTests && err != nil:
t.Error("Test Failed - GetUnconfirmedBitcoinDeposits() error", err)
}
}
@@ -356,78 +299,77 @@ func TestGetUnconfirmedBitcoinDeposits(t *testing.T) {
func TestTransferAccountBalance(t *testing.T) {
t.Parallel()
if !areTestAPIKeysSet() {
if !areTestAPIKeysSet() && !mockTests {
t.Skip()
}
_, err := b.TransferAccountBalance(1, "", "", true)
if err == nil {
err := b.TransferAccountBalance(0.01, "btc", "testAccount", true)
if !mockTests && err != nil {
t.Error("Test Failed - TransferAccountBalance() error", err)
}
_, err = b.TransferAccountBalance(1, "btc", "", false)
if err == nil {
t.Error("Test Failed - TransferAccountBalance() error", err)
if mockTests && err == nil {
t.Error("Expecting an error until a QA pass can be completed")
}
}
func TestFormatWithdrawPermissions(t *testing.T) {
b.SetDefaults()
expectedResult := exchange.AutoWithdrawCryptoText + " & " + exchange.AutoWithdrawFiatText
t.Parallel()
expectedResult := exchange.AutoWithdrawCryptoText +
" & " +
exchange.AutoWithdrawFiatText
withdrawPermissions := b.FormatWithdrawPermissions()
if withdrawPermissions != expectedResult {
t.Errorf("Expected: %s, Received: %s", expectedResult, withdrawPermissions)
t.Errorf("Expected: %s, Received: %s",
expectedResult,
withdrawPermissions)
}
}
func TestGetActiveOrders(t *testing.T) {
b.SetDefaults()
TestSetup(t)
t.Parallel()
var getOrdersRequest = exchange.GetOrdersRequest{
OrderType: exchange.AnyOrderType,
}
_, err := b.GetActiveOrders(&getOrdersRequest)
if areTestAPIKeysSet() && err != nil {
switch {
case areTestAPIKeysSet() && err != nil && !mockTests:
t.Errorf("Could not get open orders: %s", err)
} else if !areTestAPIKeysSet() && err == nil {
case !areTestAPIKeysSet() && err == nil && !mockTests:
t.Error("Expecting an error when no keys are set")
case mockTests && err != nil:
t.Errorf("Could not get open orders: %s", err)
}
}
func TestGetOrderHistory(t *testing.T) {
b.SetDefaults()
TestSetup(t)
t.Parallel()
var getOrdersRequest = exchange.GetOrdersRequest{
OrderType: exchange.AnyOrderType,
}
_, err := b.GetOrderHistory(&getOrdersRequest)
if areTestAPIKeysSet() && err != nil {
switch {
case areTestAPIKeysSet() && err != nil && !mockTests:
t.Errorf("Could not get order history: %s", err)
} else if !areTestAPIKeysSet() && err == nil {
case !areTestAPIKeysSet() && err == nil && !mockTests:
t.Error("Expecting an error when no keys are set")
case mockTests && err != nil:
t.Errorf("Could not get order history: %s", err)
}
}
// Any tests below this line have the ability to impact your orders on the exchange. Enable canManipulateRealOrders to run them
// ----------------------------------------------------------------------------------------------------------------------------
func areTestAPIKeysSet() bool {
if b.APIKey != "" && b.APIKey != "Key" &&
b.APISecret != "" && b.APISecret != "Secret" {
return true
}
return false
}
func TestSubmitOrder(t *testing.T) {
b.SetDefaults()
TestSetup(t)
if areTestAPIKeysSet() && !canManipulateRealOrders {
t.Parallel()
if areTestAPIKeysSet() && !canManipulateRealOrders && !mockTests {
t.Skip("API keys set, canManipulateRealOrders false, skipping test")
}
@@ -436,19 +378,26 @@ func TestSubmitOrder(t *testing.T) {
Base: currency.BTC,
Quote: currency.USD,
}
response, err := b.SubmitOrder(p, exchange.BuyOrderSide, exchange.MarketOrderType, 1, 1, "clientId")
if areTestAPIKeysSet() && (err != nil || !response.IsOrderPlaced) {
response, err := b.SubmitOrder(p,
exchange.BuyOrderSide,
exchange.MarketOrderType,
1,
1,
"clientId")
switch {
case areTestAPIKeysSet() && (err != nil || !response.IsOrderPlaced) && !mockTests:
t.Errorf("Order failed to be placed: %v", err)
} else if !areTestAPIKeysSet() && err == nil {
case !areTestAPIKeysSet() && err == nil && !mockTests:
t.Error("Expecting an error when no keys are set")
case mockTests && err == nil:
t.Error("Expecting an error until QA pass is completed")
}
}
func TestCancelExchangeOrder(t *testing.T) {
b.SetDefaults()
TestSetup(t)
t.Parallel()
if areTestAPIKeysSet() && !canManipulateRealOrders {
if areTestAPIKeysSet() && !canManipulateRealOrders && !mockTests {
t.Skip("API keys set, canManipulateRealOrders false, skipping test")
}
@@ -462,19 +411,20 @@ func TestCancelExchangeOrder(t *testing.T) {
}
err := b.CancelOrder(orderCancellation)
if !areTestAPIKeysSet() && err == nil {
switch {
case !areTestAPIKeysSet() && err == nil && !mockTests:
t.Error("Expecting an error when no keys are set")
}
if areTestAPIKeysSet() && err != nil {
case areTestAPIKeysSet() && err != nil && !mockTests:
t.Errorf("Could not cancel orders: %v", err)
case mockTests && err == nil:
t.Error("Expecting an error until QA pass is completed")
}
}
func TestCancelAllExchangeOrders(t *testing.T) {
b.SetDefaults()
TestSetup(t)
t.Parallel()
if areTestAPIKeysSet() && !canManipulateRealOrders {
if areTestAPIKeysSet() && !canManipulateRealOrders && !mockTests {
t.Skip("API keys set, canManipulateRealOrders false, skipping test")
}
@@ -488,11 +438,12 @@ func TestCancelAllExchangeOrders(t *testing.T) {
}
resp, err := b.CancelAllOrders(orderCancellation)
if !areTestAPIKeysSet() && err == nil {
switch {
case !areTestAPIKeysSet() && err == nil && !mockTests:
t.Error("Expecting an error when no keys are set")
}
if areTestAPIKeysSet() && err != nil {
case areTestAPIKeysSet() && err != nil && !mockTests:
t.Errorf("Could not cancel orders: %v", err)
case mockTests && err != nil:
t.Errorf("Could not cancel orders: %v", err)
}
@@ -502,6 +453,8 @@ func TestCancelAllExchangeOrders(t *testing.T) {
}
func TestModifyOrder(t *testing.T) {
t.Parallel()
_, err := b.ModifyOrder(&exchange.ModifyOrder{})
if err == nil {
t.Error("Test failed - ModifyOrder() error")
@@ -509,8 +462,12 @@ func TestModifyOrder(t *testing.T) {
}
func TestWithdraw(t *testing.T) {
b.SetDefaults()
TestSetup(t)
t.Parallel()
if areTestAPIKeysSet() && !canManipulateRealOrders && !mockTests {
t.Skip("API keys set, canManipulateRealOrders false, skipping test")
}
var withdrawCryptoRequest = exchange.WithdrawRequest{
Amount: 100,
Currency: currency.BTC,
@@ -518,24 +475,21 @@ func TestWithdraw(t *testing.T) {
Description: "WITHDRAW IT ALL",
}
if areTestAPIKeysSet() && !canManipulateRealOrders {
t.Skip("API keys set, canManipulateRealOrders false, skipping test")
}
_, err := b.WithdrawCryptocurrencyFunds(&withdrawCryptoRequest)
if !areTestAPIKeysSet() && err == nil {
switch {
case !areTestAPIKeysSet() && err == nil && !mockTests:
t.Error("Expecting an error when no keys are set")
}
if areTestAPIKeysSet() && err != nil {
case areTestAPIKeysSet() && err != nil && !mockTests:
t.Errorf("Withdraw failed to be placed: %v", err)
case mockTests && err == nil:
t.Error("Expecting an error until QA pass is completed")
}
}
func TestWithdrawFiat(t *testing.T) {
b.SetDefaults()
TestSetup(t)
t.Parallel()
if areTestAPIKeysSet() && !canManipulateRealOrders {
if areTestAPIKeysSet() && !canManipulateRealOrders && !mockTests {
t.Skip("API keys set, canManipulateRealOrders false, skipping test")
}
@@ -558,19 +512,20 @@ func TestWithdrawFiat(t *testing.T) {
}
_, err := b.WithdrawFiatFunds(&withdrawFiatRequest)
if !areTestAPIKeysSet() && err == nil {
switch {
case !areTestAPIKeysSet() && err == nil && !mockTests:
t.Error("Expecting an error when no keys are set")
}
if areTestAPIKeysSet() && err != nil {
case areTestAPIKeysSet() && err != nil && !mockTests:
t.Errorf("Withdraw failed to be placed: %v", err)
case mockTests && err == nil:
t.Error("Expecting an error until QA pass is completed")
}
}
func TestWithdrawInternationalBank(t *testing.T) {
b.SetDefaults()
TestSetup(t)
t.Parallel()
if areTestAPIKeysSet() && !canManipulateRealOrders {
if areTestAPIKeysSet() && !canManipulateRealOrders && !mockTests {
t.Skip("API keys set, canManipulateRealOrders false, skipping test")
}
@@ -599,24 +554,26 @@ func TestWithdrawInternationalBank(t *testing.T) {
}
_, err := b.WithdrawFiatFundsToInternationalBank(&withdrawFiatRequest)
if !areTestAPIKeysSet() && err == nil {
switch {
case !areTestAPIKeysSet() && err == nil && !mockTests:
t.Error("Expecting an error when no keys are set")
}
if areTestAPIKeysSet() && err != nil {
case areTestAPIKeysSet() && err != nil && !mockTests:
t.Errorf("Withdraw failed to be placed: %v", err)
case mockTests && err == nil:
t.Error("Expecting an error until QA pass is completed")
}
}
func TestGetDepositAddress(t *testing.T) {
if areTestAPIKeysSet() && customerID != "" {
_, err := b.GetDepositAddress(currency.BTC, "")
if err != nil {
t.Error("Test Failed - GetDepositAddress error", err)
}
} else {
_, err := b.GetDepositAddress(currency.BTC, "")
if err == nil {
t.Error("Test Failed - GetDepositAddress error cannot be nil")
}
t.Parallel()
_, err := b.GetDepositAddress(currency.BTC, "")
switch {
case areTestAPIKeysSet() && customerID != "" && err != nil && !mockTests:
t.Error("Test Failed - GetDepositAddress error", err)
case !areTestAPIKeysSet() && err == nil && !mockTests:
t.Error("Test Failed - GetDepositAddress error cannot be nil")
case mockTests && err != nil:
t.Error("Test Failed - GetDepositAddress error", err)
}
}

View File

@@ -77,7 +77,7 @@ type Balances struct {
// UserTransactions holds user transaction information
type UserTransactions struct {
Date int64 `json:"datetime"`
Date string `json:"datetime"`
TransID int64 `json:"id"`
Type int `json:"type,string"`
USD float64 `json:"usd"`
@@ -125,15 +125,15 @@ type WithdrawalRequests struct {
// CryptoWithdrawalResponse response from a crypto withdrawal request
type CryptoWithdrawalResponse struct {
ID string `json:"id"`
Error string `json:"error"`
ID string `json:"id"`
Error map[string][]string `json:"error"`
}
// FIATWithdrawalResponse response from a fiat withdrawal request
type FIATWithdrawalResponse struct {
ID string `json:"id"`
Status string `json:"status"`
Reason string `json:"reason"`
ID string `json:"id"`
Status string `json:"status"`
Reason map[string][]string `json:"reason"`
}
// UnconfirmedBTCTransactions holds address information about unconfirmed

View File

@@ -262,8 +262,12 @@ func (b *Bitstamp) WithdrawCryptocurrencyFunds(withdrawRequest *exchange.Withdra
if err != nil {
return "", err
}
if resp.Error != "" {
return "", errors.New(resp.Error)
if len(resp.Error) != 0 {
var details string
for _, v := range resp.Error {
details += strings.Join(v, "")
}
return "", errors.New(details)
}
return resp.ID, nil
@@ -280,7 +284,11 @@ func (b *Bitstamp) WithdrawFiatFunds(withdrawRequest *exchange.WithdrawRequest)
return "", err
}
if resp.Status == errStr {
return "", errors.New(resp.Reason)
var details string
for _, v := range resp.Reason {
details += strings.Join(v, "")
}
return "", errors.New(details)
}
return resp.ID, nil
@@ -299,7 +307,11 @@ func (b *Bitstamp) WithdrawFiatFundsToInternationalBank(withdrawRequest *exchang
return "", err
}
if resp.Status == errStr {
return "", errors.New(resp.Reason)
var details string
for _, v := range resp.Reason {
details += strings.Join(v, "")
}
return "", errors.New(details)
}
return resp.ID, nil
@@ -387,7 +399,11 @@ func (b *Bitstamp) GetOrderHistory(getOrdersRequest *exchange.GetOrdersRequest)
quoteCurrency.String(),
b.ConfigCurrencyPairFormat.Delimiter)
}
orderDate := time.Unix(order.Date, 0)
orderDate, err := time.Parse("2006-01-02 15:04:05", order.Date)
if err != nil {
return nil, err
}
orders = append(orders, exchange.OrderDetail{
ID: fmt.Sprintf("%v", order.OrderID),