mirror of
https://github.com/d0zingcat/gocryptotrader.git
synced 2026-05-13 15:09:42 +00:00
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:
committed by
Adrian Gallagher
parent
a81ddead9e
commit
6d8ba0a96a
@@ -30,7 +30,12 @@ test_script:
|
||||
# test back-end
|
||||
- go get github.com/golangci/golangci-lint/cmd/golangci-lint@v1.16.0
|
||||
- '%GOPATH%\bin\golangci-lint.exe run --verbose'
|
||||
- go test -race ./...
|
||||
- ps: >-
|
||||
if($env:APPVEYOR_SCHEDULED_BUILD -eq 'true') {
|
||||
go test -race ./... -tags=mock_test_off
|
||||
}else {
|
||||
go test -race ./...
|
||||
}
|
||||
|
||||
# test front-end
|
||||
- node --version
|
||||
|
||||
5
Makefile
5
Makefile
@@ -4,6 +4,7 @@ LINTPKG = github.com/golangci/golangci-lint/cmd/golangci-lint@v1.16.0
|
||||
LINTBIN = $(GOPATH)/bin/golangci-lint
|
||||
GCTLISTENPORT=9050
|
||||
GCTPROFILERLISTENPORT=8085
|
||||
CRON = $(TRAVIS_EVENT_TYPE)
|
||||
|
||||
get:
|
||||
GO111MODULE=on go get $(GCTPKG)
|
||||
@@ -16,7 +17,11 @@ linter:
|
||||
check: linter test
|
||||
|
||||
test:
|
||||
ifeq ($(CRON), cron)
|
||||
go test -race -tags=mock_test_off -coverprofile=coverage.txt -covermode=atomic ./...
|
||||
else
|
||||
go test -race -coverprofile=coverage.txt -covermode=atomic ./...
|
||||
endif
|
||||
|
||||
build:
|
||||
GO111MODULE=on go build $(LDFLAGS)
|
||||
|
||||
@@ -732,6 +732,7 @@ func (c *Coinmarketcap) SendHTTPRequest(method, endpoint string, v url.Values, r
|
||||
false,
|
||||
false,
|
||||
c.Verbose,
|
||||
false,
|
||||
false)
|
||||
}
|
||||
|
||||
|
||||
@@ -192,6 +192,7 @@ func (c *CurrencyConverter) SendHTTPRequest(endPoint string, values url.Values,
|
||||
auth,
|
||||
false,
|
||||
c.Verbose,
|
||||
false,
|
||||
false)
|
||||
if err != nil {
|
||||
return fmt.Errorf("currency converter API SendHTTPRequest error %s with path %s",
|
||||
|
||||
@@ -241,5 +241,6 @@ func (c *CurrencyLayer) SendHTTPRequest(endPoint string, values url.Values, resu
|
||||
auth,
|
||||
false,
|
||||
c.Verbose,
|
||||
false,
|
||||
false)
|
||||
}
|
||||
|
||||
@@ -178,6 +178,7 @@ func (e *ExchangeRates) SendHTTPRequest(endPoint string, values url.Values, resu
|
||||
false,
|
||||
false,
|
||||
e.Verbose,
|
||||
false,
|
||||
false)
|
||||
if err != nil {
|
||||
return fmt.Errorf("exchangeRatesAPI SendHTTPRequest error %s with path %s",
|
||||
|
||||
@@ -265,5 +265,6 @@ func (f *Fixer) SendOpenHTTPRequest(endpoint string, v url.Values, result interf
|
||||
auth,
|
||||
false,
|
||||
f.Verbose,
|
||||
false,
|
||||
false)
|
||||
}
|
||||
|
||||
@@ -265,5 +265,6 @@ func (o *OXR) SendHTTPRequest(endpoint string, values url.Values, result interfa
|
||||
false,
|
||||
false,
|
||||
o.Verbose,
|
||||
false,
|
||||
false)
|
||||
}
|
||||
|
||||
@@ -534,7 +534,16 @@ func (a *Alphapoint) SendHTTPRequest(method, path string, data map[string]interf
|
||||
return errors.New("unable to JSON request")
|
||||
}
|
||||
|
||||
return a.SendPayload(method, path, headers, bytes.NewBuffer(PayloadJSON), result, false, false, a.Verbose, a.HTTPDebugging)
|
||||
return a.SendPayload(method,
|
||||
path,
|
||||
headers,
|
||||
bytes.NewBuffer(PayloadJSON),
|
||||
result,
|
||||
false,
|
||||
false,
|
||||
a.Verbose,
|
||||
a.HTTPDebugging,
|
||||
a.HTTPRecording)
|
||||
}
|
||||
|
||||
// SendAuthenticatedHTTPRequest sends an authenticated request
|
||||
@@ -559,5 +568,14 @@ func (a *Alphapoint) SendAuthenticatedHTTPRequest(method, path string, data map[
|
||||
return errors.New("unable to JSON request")
|
||||
}
|
||||
|
||||
return a.SendPayload(method, path, headers, bytes.NewBuffer(PayloadJSON), result, true, true, a.Verbose, a.HTTPDebugging)
|
||||
return a.SendPayload(method,
|
||||
path,
|
||||
headers,
|
||||
bytes.NewBuffer(PayloadJSON),
|
||||
result,
|
||||
true,
|
||||
true,
|
||||
a.Verbose,
|
||||
a.HTTPDebugging,
|
||||
a.HTTPRecording)
|
||||
}
|
||||
|
||||
@@ -83,7 +83,7 @@ func (a *ANX) Setup(exch *config.ExchangeConfig) {
|
||||
} else {
|
||||
a.Enabled = true
|
||||
a.AuthenticatedAPISupport = exch.AuthenticatedAPISupport
|
||||
a.SetAPIKeys(exch.APIKey, exch.APISecret, "", false)
|
||||
a.SetAPIKeys(exch.APIKey, exch.APISecret, "", true)
|
||||
a.SetHTTPClientTimeout(exch.HTTPTimeout)
|
||||
a.SetHTTPClientUserAgent(exch.HTTPUserAgent)
|
||||
a.RESTPollingDelay = exch.RESTPollingDelay
|
||||
@@ -248,9 +248,13 @@ func (a *ANX) NewOrder(orderType string, buy bool, tradedCurrency string, traded
|
||||
// CancelOrderByIDs cancels orders, requires already knowing order IDs
|
||||
// There is no existing API call to retrieve orderIds
|
||||
func (a *ANX) CancelOrderByIDs(orderIds []string) (OrderCancelResponse, error) {
|
||||
var response OrderCancelResponse
|
||||
if len(orderIds) == 0 {
|
||||
return response, errors.New("no order ids provided")
|
||||
}
|
||||
|
||||
req := make(map[string]interface{})
|
||||
req["orderIds"] = orderIds
|
||||
var response OrderCancelResponse
|
||||
|
||||
err := a.SendAuthenticatedHTTPRequest(anxOrderCancel, req, &response)
|
||||
if response.ResultCode != "OK" {
|
||||
@@ -266,7 +270,7 @@ func (a *ANX) GetOrderList(isActiveOrdersOnly bool) ([]OrderResponse, error) {
|
||||
req["activeOnly"] = isActiveOrdersOnly
|
||||
|
||||
type OrderListResponse struct {
|
||||
Timestamp int64 `json:"timestamp"`
|
||||
Timestamp int64 `json:"timestamp,string"`
|
||||
ResultCode string `json:"resultCode"`
|
||||
Count int64 `json:"count"`
|
||||
OrderResponses []OrderResponse `json:"orders"`
|
||||
@@ -278,7 +282,6 @@ func (a *ANX) GetOrderList(isActiveOrdersOnly bool) ([]OrderResponse, error) {
|
||||
}
|
||||
|
||||
if response.ResultCode != "OK" {
|
||||
log.Errorf("Response code is not OK: %s\n", response.ResultCode)
|
||||
return nil, errors.New(response.ResultCode)
|
||||
}
|
||||
|
||||
@@ -304,7 +307,6 @@ func (a *ANX) OrderInfo(orderID string) (OrderResponse, error) {
|
||||
}
|
||||
|
||||
if response.ResultCode != "OK" {
|
||||
log.Errorf("Response code is not OK: %s\n", response.ResultCode)
|
||||
return OrderResponse{}, errors.New(response.ResultCode)
|
||||
}
|
||||
return response.Order, nil
|
||||
@@ -324,7 +326,7 @@ func (a *ANX) Send(currency, address, otp, amount string) (string, error) {
|
||||
type SendResponse struct {
|
||||
TransactionID string `json:"transactionId"`
|
||||
ResultCode string `json:"resultCode"`
|
||||
Timestamp int64 `json:"timestamp"`
|
||||
Timestamp int64 `json:"timestamp,string"`
|
||||
}
|
||||
var response SendResponse
|
||||
|
||||
@@ -335,7 +337,6 @@ func (a *ANX) Send(currency, address, otp, amount string) (string, error) {
|
||||
}
|
||||
|
||||
if response.ResultCode != "OK" {
|
||||
log.Errorf("Response code is not OK: %s\n", response.ResultCode)
|
||||
return "", errors.New(response.ResultCode)
|
||||
}
|
||||
return response.TransactionID, nil
|
||||
@@ -361,7 +362,6 @@ func (a *ANX) CreateNewSubAccount(currency, name string) (string, error) {
|
||||
}
|
||||
|
||||
if response.ResultCode != "OK" {
|
||||
log.Errorf("Response code is not OK: %s\n", response.ResultCode)
|
||||
return "", errors.New(response.ResultCode)
|
||||
}
|
||||
return response.SubAccount, nil
|
||||
@@ -380,7 +380,7 @@ func (a *ANX) GetDepositAddressByCurrency(currency, name string, newAddr bool) (
|
||||
Address string `json:"address"`
|
||||
SubAccount string `json:"subAccount"`
|
||||
ResultCode string `json:"resultCode"`
|
||||
Timestamp int64 `json:"timestamp"`
|
||||
Timestamp int64 `json:"timestamp,string"`
|
||||
}
|
||||
var response AddressResponse
|
||||
|
||||
@@ -395,7 +395,6 @@ func (a *ANX) GetDepositAddressByCurrency(currency, name string, newAddr bool) (
|
||||
}
|
||||
|
||||
if response.ResultCode != "OK" {
|
||||
log.Errorf("Response code is not OK: %s\n", response.ResultCode)
|
||||
return "", errors.New(response.ResultCode)
|
||||
}
|
||||
|
||||
@@ -404,7 +403,16 @@ func (a *ANX) GetDepositAddressByCurrency(currency, name string, newAddr bool) (
|
||||
|
||||
// SendHTTPRequest sends an unauthenticated HTTP request
|
||||
func (a *ANX) SendHTTPRequest(path string, result interface{}) error {
|
||||
return a.SendPayload(http.MethodGet, path, nil, nil, result, false, false, a.Verbose, a.HTTPDebugging)
|
||||
return a.SendPayload(http.MethodGet,
|
||||
path,
|
||||
nil,
|
||||
nil,
|
||||
result,
|
||||
false,
|
||||
false,
|
||||
a.Verbose,
|
||||
a.HTTPDebugging,
|
||||
a.HTTPRecording)
|
||||
}
|
||||
|
||||
// SendAuthenticatedHTTPRequest sends a authenticated HTTP request
|
||||
@@ -437,7 +445,16 @@ func (a *ANX) SendAuthenticatedHTTPRequest(path string, params map[string]interf
|
||||
headers["Rest-Sign"] = common.Base64Encode(hmac)
|
||||
headers["Content-Type"] = "application/json"
|
||||
|
||||
return a.SendPayload(http.MethodPost, a.APIUrl+path, headers, bytes.NewBuffer(PayloadJSON), result, true, true, a.Verbose, a.HTTPDebugging)
|
||||
return a.SendPayload(http.MethodPost,
|
||||
a.APIUrl+path,
|
||||
headers,
|
||||
bytes.NewBuffer(PayloadJSON),
|
||||
result,
|
||||
true,
|
||||
true,
|
||||
a.Verbose,
|
||||
a.HTTPDebugging,
|
||||
a.HTTPRecording)
|
||||
}
|
||||
|
||||
// GetFee returns an estimate of fee based on type of transaction
|
||||
|
||||
32
exchanges/anx/anx_live_test.go
Normal file
32
exchanges/anx/anx_live_test.go
Normal file
@@ -0,0 +1,32 @@
|
||||
//+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 anx
|
||||
|
||||
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")
|
||||
anxConfig, err := cfg.GetExchangeConfig("ANX")
|
||||
if err != nil {
|
||||
log.Fatalf("Test Failed - ANX Setup() init error", err)
|
||||
}
|
||||
anxConfig.AuthenticatedAPISupport = true
|
||||
anxConfig.APIKey = apiKey
|
||||
anxConfig.APISecret = apiSecret
|
||||
a.SetDefaults()
|
||||
a.Setup(&anxConfig)
|
||||
log.Printf(sharedtestvalues.LiveTesting, a.GetName(), a.APIUrl)
|
||||
os.Exit(m.Run())
|
||||
}
|
||||
44
exchanges/anx/anx_mock_test.go
Normal file
44
exchanges/anx/anx_mock_test.go
Normal file
@@ -0,0 +1,44 @@
|
||||
//+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 anx
|
||||
|
||||
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/anx/anx.json"
|
||||
|
||||
var mockTests = true
|
||||
|
||||
func TestMain(m *testing.M) {
|
||||
cfg := config.GetConfig()
|
||||
cfg.LoadConfig("../../testdata/configtest.json")
|
||||
anxConfig, err := cfg.GetExchangeConfig("ANX")
|
||||
if err != nil {
|
||||
log.Fatal("Test Failed - Mock server error", err)
|
||||
}
|
||||
anxConfig.AuthenticatedAPISupport = true
|
||||
anxConfig.APIKey = apiKey
|
||||
anxConfig.APISecret = apiSecret
|
||||
a.SetDefaults()
|
||||
a.Setup(&anxConfig)
|
||||
|
||||
serverDetails, newClient, err := mock.NewVCRServer(mockFile)
|
||||
if err != nil {
|
||||
log.Fatalf("Test Failed - Mock server error %s", err)
|
||||
}
|
||||
|
||||
a.HTTPClient = newClient
|
||||
a.APIUrl = serverDetails + "/"
|
||||
|
||||
log.Printf(sharedtestvalues.MockTesting, a.GetName(), a.APIUrl)
|
||||
os.Exit(m.Run())
|
||||
}
|
||||
@@ -4,7 +4,6 @@ import (
|
||||
"testing"
|
||||
|
||||
"github.com/thrasher-corp/gocryptotrader/common"
|
||||
"github.com/thrasher-corp/gocryptotrader/config"
|
||||
"github.com/thrasher-corp/gocryptotrader/currency"
|
||||
exchange "github.com/thrasher-corp/gocryptotrader/exchanges"
|
||||
)
|
||||
@@ -18,70 +17,8 @@ const (
|
||||
|
||||
var a ANX
|
||||
|
||||
func TestSetDefaults(t *testing.T) {
|
||||
a.SetDefaults()
|
||||
|
||||
if a.Name != "ANX" {
|
||||
t.Error("Test Failed - ANX SetDefaults() incorrect values set")
|
||||
}
|
||||
if a.Enabled {
|
||||
t.Error("Test Failed - ANX SetDefaults() incorrect values set")
|
||||
}
|
||||
if a.TakerFee != 0.02 {
|
||||
t.Error("Test Failed - ANX SetDefaults() incorrect values set")
|
||||
}
|
||||
if a.MakerFee != 0.01 {
|
||||
t.Error("Test Failed - ANX SetDefaults() incorrect values set")
|
||||
}
|
||||
if a.Verbose {
|
||||
t.Error("Test Failed - ANX SetDefaults() incorrect values set")
|
||||
}
|
||||
if a.Websocket.IsEnabled() {
|
||||
t.Error("Test Failed - ANX SetDefaults() incorrect values set")
|
||||
}
|
||||
if a.RESTPollingDelay != 10 {
|
||||
t.Error("Test Failed - ANX SetDefaults() incorrect values set")
|
||||
}
|
||||
}
|
||||
|
||||
func TestSetup(t *testing.T) {
|
||||
anxSetupConfig := config.GetConfig()
|
||||
anxSetupConfig.LoadConfig("../../testdata/configtest.json")
|
||||
anxConfig, err := anxSetupConfig.GetExchangeConfig("ANX")
|
||||
anxConfig.AuthenticatedAPISupport = true
|
||||
|
||||
if err != nil {
|
||||
t.Error("Test Failed - ANX Setup() init error")
|
||||
}
|
||||
a.Setup(&anxConfig)
|
||||
a.APIKey = apiKey
|
||||
a.APISecret = apiSecret
|
||||
a.AuthenticatedAPISupport = true
|
||||
|
||||
if !a.Enabled {
|
||||
t.Error("Test Failed - ANX Setup() incorrect values set")
|
||||
}
|
||||
if a.RESTPollingDelay != 10 {
|
||||
t.Error("Test Failed - ANX Setup() incorrect values set")
|
||||
}
|
||||
if a.Verbose {
|
||||
t.Error("Test Failed - ANX Setup() incorrect values set")
|
||||
}
|
||||
if a.Websocket.IsEnabled() {
|
||||
t.Error("Test Failed - ANX Setup() incorrect values set")
|
||||
}
|
||||
if len(a.BaseCurrencies) == 0 {
|
||||
t.Error("Test Failed - ANX Setup() incorrect values set")
|
||||
}
|
||||
if len(a.AvailablePairs) == 0 {
|
||||
t.Error("Test Failed - ANX Setup() incorrect values set")
|
||||
}
|
||||
if len(a.EnabledPairs) == 0 {
|
||||
t.Error("Test Failed - ANX Setup() incorrect values set")
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetCurrencies(t *testing.T) {
|
||||
t.Parallel()
|
||||
_, err := a.GetCurrencies()
|
||||
if err != nil {
|
||||
t.Fatalf("Test failed. TestGetCurrencies failed. Err: %s", err)
|
||||
@@ -89,6 +26,7 @@ func TestGetCurrencies(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestGetTradablePairs(t *testing.T) {
|
||||
t.Parallel()
|
||||
_, err := a.GetTradablePairs()
|
||||
if err != nil {
|
||||
t.Fatalf("Test failed. TestGetTradablePairs failed. Err: %s", err)
|
||||
@@ -96,6 +34,7 @@ func TestGetTradablePairs(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestGetTicker(t *testing.T) {
|
||||
t.Parallel()
|
||||
ticker, err := a.GetTicker("BTCUSD")
|
||||
if err != nil {
|
||||
t.Errorf("Test Failed - ANX GetTicker() error: %s", err)
|
||||
@@ -106,16 +45,18 @@ func TestGetTicker(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestGetDepth(t *testing.T) {
|
||||
ticker, err := a.GetDepth("BTCUSD")
|
||||
t.Parallel()
|
||||
depth, err := a.GetDepth("BTCUSD")
|
||||
if err != nil {
|
||||
t.Errorf("Test Failed - ANX GetDepth() error: %s", err)
|
||||
}
|
||||
if ticker.Result != "success" {
|
||||
if depth.Result != "success" {
|
||||
t.Error("Test Failed - ANX GetDepth() unsuccessful")
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetAPIKey(t *testing.T) {
|
||||
t.Parallel()
|
||||
apiKey, apiSecret, err := a.GetAPIKey("userName", "passWord", "", "1337")
|
||||
if err == nil {
|
||||
t.Error("Test Failed - ANX GetAPIKey() Incorrect")
|
||||
@@ -140,6 +81,7 @@ func setFeeBuilder() *exchange.FeeBuilder {
|
||||
|
||||
// TestGetFeeByTypeOfflineTradeFee logic test
|
||||
func TestGetFeeByTypeOfflineTradeFee(t *testing.T) {
|
||||
t.Parallel()
|
||||
var feeBuilder = setFeeBuilder()
|
||||
a.GetFeeByType(feeBuilder)
|
||||
if apiKey == "" || apiSecret == "" {
|
||||
@@ -154,9 +96,7 @@ func TestGetFeeByTypeOfflineTradeFee(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestGetFee(t *testing.T) {
|
||||
a.SetDefaults()
|
||||
TestSetup(t)
|
||||
|
||||
t.Parallel()
|
||||
var feeBuilder = setFeeBuilder()
|
||||
|
||||
// CryptocurrencyTradeFee Basic
|
||||
@@ -226,7 +166,7 @@ func TestGetFee(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestFormatWithdrawPermissions(t *testing.T) {
|
||||
a.SetDefaults()
|
||||
t.Parallel()
|
||||
expectedResult := exchange.AutoWithdrawCryptoWithSetupText + " & " + exchange.WithdrawCryptoWith2FAText + " & " +
|
||||
exchange.WithdrawCryptoWithEmailText + " & " + exchange.WithdrawFiatViaWebsiteOnlyText
|
||||
|
||||
@@ -238,34 +178,36 @@ func TestFormatWithdrawPermissions(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestGetActiveOrders(t *testing.T) {
|
||||
a.SetDefaults()
|
||||
TestSetup(t)
|
||||
|
||||
t.Parallel()
|
||||
var getOrdersRequest = exchange.GetOrdersRequest{
|
||||
OrderType: exchange.AnyOrderType,
|
||||
}
|
||||
|
||||
_, err := a.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) {
|
||||
a.SetDefaults()
|
||||
TestSetup(t)
|
||||
|
||||
t.Parallel()
|
||||
var getOrdersRequest = exchange.GetOrdersRequest{
|
||||
OrderType: exchange.AnyOrderType,
|
||||
}
|
||||
|
||||
_, err := a.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.Error("Test Failed - GetBalance() error", err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -281,10 +223,8 @@ func areTestAPIKeysSet() bool {
|
||||
}
|
||||
|
||||
func TestSubmitOrder(t *testing.T) {
|
||||
a.SetDefaults()
|
||||
TestSetup(t)
|
||||
|
||||
if areTestAPIKeysSet() && !canManipulateRealOrders {
|
||||
t.Parallel()
|
||||
if areTestAPIKeysSet() && !canManipulateRealOrders && !mockTests {
|
||||
t.Skip("API keys set, canManipulateRealOrders false, skipping test")
|
||||
}
|
||||
var p = currency.Pair{
|
||||
@@ -292,8 +232,9 @@ func TestSubmitOrder(t *testing.T) {
|
||||
Base: currency.BTC,
|
||||
Quote: currency.USD,
|
||||
}
|
||||
response, err := a.SubmitOrder(p, exchange.BuyOrderSide, exchange.MarketOrderType, 1, 1, "clientId")
|
||||
if areTestAPIKeysSet() && (err != nil || !response.IsOrderPlaced) {
|
||||
// TODO: QA Pass to submit order
|
||||
response, err := a.SubmitOrder(p, exchange.BuyOrderSide, exchange.MarketOrderType, 1, 1, "")
|
||||
if areTestAPIKeysSet() && (err != nil || !response.IsOrderPlaced) && !mockTests {
|
||||
t.Errorf("Order failed to be placed: %v", err)
|
||||
} else if !areTestAPIKeysSet() && err == nil {
|
||||
t.Error("Expecting an error when no keys are set")
|
||||
@@ -301,10 +242,8 @@ func TestSubmitOrder(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestCancelExchangeOrder(t *testing.T) {
|
||||
a.SetDefaults()
|
||||
TestSetup(t)
|
||||
|
||||
if areTestAPIKeysSet() && !canManipulateRealOrders {
|
||||
t.Parallel()
|
||||
if areTestAPIKeysSet() && !canManipulateRealOrders && !mockTests {
|
||||
t.Skip("API keys set, canManipulateRealOrders false, skipping test")
|
||||
}
|
||||
|
||||
@@ -318,18 +257,19 @@ func TestCancelExchangeOrder(t *testing.T) {
|
||||
}
|
||||
|
||||
err := a.CancelOrder(orderCancellation)
|
||||
if areTestAPIKeysSet() && err != nil {
|
||||
switch {
|
||||
case areTestAPIKeysSet() && err != nil && !mockTests:
|
||||
t.Errorf("Could not cancel order: %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 cancel order: %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCancelAllExchangeOrders(t *testing.T) {
|
||||
a.SetDefaults()
|
||||
TestSetup(t)
|
||||
|
||||
if areTestAPIKeysSet() && !canManipulateRealOrders {
|
||||
t.Parallel()
|
||||
if areTestAPIKeysSet() && !canManipulateRealOrders && !mockTests {
|
||||
t.Skip("API keys set, canManipulateRealOrders false, skipping test")
|
||||
}
|
||||
|
||||
@@ -343,11 +283,13 @@ func TestCancelAllExchangeOrders(t *testing.T) {
|
||||
}
|
||||
|
||||
resp, err := a.CancelAllOrders(orderCancellation)
|
||||
|
||||
if areTestAPIKeysSet() && err != nil {
|
||||
switch {
|
||||
case areTestAPIKeysSet() && err != nil && !mockTests:
|
||||
t.Errorf("Could not cancel order: %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("QA pass needs to be completed and mock needs to be updated error cannot be nil")
|
||||
}
|
||||
|
||||
if len(resp.OrderStatus) > 0 {
|
||||
@@ -356,20 +298,20 @@ func TestCancelAllExchangeOrders(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestGetAccountInfo(t *testing.T) {
|
||||
if apiKey != "" || apiSecret != "" {
|
||||
_, err := a.GetAccountInfo()
|
||||
if err != nil {
|
||||
t.Error("test failed - GetAccountInfo() error:", err)
|
||||
}
|
||||
} else {
|
||||
_, err := a.GetAccountInfo()
|
||||
if err == nil {
|
||||
t.Error("test failed - GetAccountInfo() error")
|
||||
}
|
||||
t.Parallel()
|
||||
_, err := a.GetAccountInfo()
|
||||
switch {
|
||||
case areTestAPIKeysSet() && err != nil && !mockTests:
|
||||
t.Error("test failed - GetAccountInfo() error:", err)
|
||||
case !areTestAPIKeysSet() && err == nil && !mockTests:
|
||||
t.Error("test failed - GetAccountInfo() error")
|
||||
case mockTests && err != nil:
|
||||
t.Error("test failed - GetAccountInfo() error:", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestModifyOrder(t *testing.T) {
|
||||
t.Parallel()
|
||||
_, err := a.ModifyOrder(&exchange.ModifyOrder{})
|
||||
if err == nil {
|
||||
t.Error("Test failed - ModifyOrder() error")
|
||||
@@ -377,10 +319,8 @@ func TestModifyOrder(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestWithdraw(t *testing.T) {
|
||||
a.SetDefaults()
|
||||
TestSetup(t)
|
||||
|
||||
if areTestAPIKeysSet() && !canManipulateRealOrders {
|
||||
t.Parallel()
|
||||
if areTestAPIKeysSet() && !canManipulateRealOrders && !mockTests {
|
||||
t.Skip("API keys set, canManipulateRealOrders false, skipping test")
|
||||
}
|
||||
|
||||
@@ -393,61 +333,47 @@ func TestWithdraw(t *testing.T) {
|
||||
}
|
||||
|
||||
_, err := a.WithdrawCryptocurrencyFunds(&withdrawCryptoRequest)
|
||||
if areTestAPIKeysSet() && err != nil {
|
||||
if areTestAPIKeysSet() && err != nil && !mockTests {
|
||||
t.Errorf("Withdraw failed to be placed: %v", err)
|
||||
} else if !areTestAPIKeysSet() && err == nil {
|
||||
} else if !areTestAPIKeysSet() && err == nil && mockTests {
|
||||
t.Error("Expecting an error when no keys are set")
|
||||
}
|
||||
}
|
||||
|
||||
func TestWithdrawFiat(t *testing.T) {
|
||||
a.SetDefaults()
|
||||
TestSetup(t)
|
||||
|
||||
if areTestAPIKeysSet() && !canManipulateRealOrders {
|
||||
t.Skip("API keys set, canManipulateRealOrders false, skipping test")
|
||||
}
|
||||
|
||||
t.Parallel()
|
||||
var withdrawFiatRequest = exchange.WithdrawRequest{}
|
||||
|
||||
_, err := a.WithdrawFiatFunds(&withdrawFiatRequest)
|
||||
if err != common.ErrFunctionNotSupported {
|
||||
t.Errorf("Expected '%v', received: '%v'", common.ErrFunctionNotSupported, err)
|
||||
t.Errorf("Expected '%v', received: '%v'",
|
||||
common.ErrFunctionNotSupported,
|
||||
err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestWithdrawInternationalBank(t *testing.T) {
|
||||
a.SetDefaults()
|
||||
TestSetup(t)
|
||||
|
||||
if areTestAPIKeysSet() && !canManipulateRealOrders {
|
||||
t.Skip("API keys set, canManipulateRealOrders false, skipping test")
|
||||
}
|
||||
|
||||
t.Parallel()
|
||||
var withdrawFiatRequest = exchange.WithdrawRequest{}
|
||||
|
||||
_, err := a.WithdrawFiatFundsToInternationalBank(&withdrawFiatRequest)
|
||||
if err != common.ErrFunctionNotSupported {
|
||||
t.Errorf("Expected '%v', received: '%v'", common.ErrFunctionNotSupported, err)
|
||||
t.Errorf("Expected '%v', received: '%v'",
|
||||
common.ErrFunctionNotSupported,
|
||||
err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetDepositAddress(t *testing.T) {
|
||||
if areTestAPIKeysSet() {
|
||||
_, err := a.GetDepositAddress(currency.BTC, "")
|
||||
if err != nil {
|
||||
t.Error("Test Failed - GetDepositAddress() error", err)
|
||||
}
|
||||
} else {
|
||||
_, err := a.GetDepositAddress(currency.BTC, "")
|
||||
if err == nil {
|
||||
t.Error("Test Failed - GetDepositAddress() error cannot be nil")
|
||||
}
|
||||
t.Parallel()
|
||||
_, err := a.GetDepositAddress(currency.BTC, "")
|
||||
if areTestAPIKeysSet() && err != nil && !mockTests {
|
||||
t.Error("Test Failed - GetDepositAddress() error", err)
|
||||
} else if !areTestAPIKeysSet() && err == nil {
|
||||
t.Error("Test Failed - GetDepositAddress() error cannot be nil")
|
||||
}
|
||||
}
|
||||
|
||||
func TestUpdateOrderbook(t *testing.T) {
|
||||
a.SetDefaults()
|
||||
t.Parallel()
|
||||
q := currency.Pair{
|
||||
Delimiter: "_",
|
||||
Base: currency.BTC,
|
||||
|
||||
@@ -279,20 +279,10 @@ func (b *Binance) GetRecentTrades(rtr RecentTradeRequestParams) ([]RecentTrade,
|
||||
// limit: Optional. Default 500; max 1000.
|
||||
// fromID:
|
||||
func (b *Binance) GetHistoricalTrades(symbol string, limit int, fromID int64) ([]HistoricalTrade, error) {
|
||||
var resp []HistoricalTrade
|
||||
|
||||
if err := b.CheckLimit(limit); err != nil {
|
||||
return resp, err
|
||||
}
|
||||
|
||||
params := url.Values{}
|
||||
params.Set("symbol", common.StringToUpper(symbol))
|
||||
params.Set("limit", strconv.Itoa(limit))
|
||||
params.Set("fromid", strconv.FormatInt(fromID, 10))
|
||||
|
||||
path := fmt.Sprintf("%s%s?%s", b.APIUrl, historicalTrades, params.Encode())
|
||||
|
||||
return resp, b.SendHTTPRequest(path, &resp)
|
||||
// Dropping support due to response for market data is always
|
||||
// {"code":-2014,"msg":"API-key format invalid."}
|
||||
// TODO: replace with newer API vs REST endpoint
|
||||
return nil, common.ErrFunctionNotSupported
|
||||
}
|
||||
|
||||
// GetAggregatedTrades returns aggregated trade activity
|
||||
@@ -617,7 +607,16 @@ func (b *Binance) GetAccount() (*Account, error) {
|
||||
|
||||
// SendHTTPRequest sends an unauthenticated request
|
||||
func (b *Binance) 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)
|
||||
}
|
||||
|
||||
// SendAuthHTTPRequest sends an authenticated HTTP request
|
||||
@@ -653,7 +652,16 @@ func (b *Binance) SendAuthHTTPRequest(method, path string, params url.Values, re
|
||||
Message string `json:"msg"`
|
||||
}{}
|
||||
|
||||
err := b.SendPayload(method, path, headers, bytes.NewBuffer(nil), &interim, true, false, b.Verbose, b.HTTPDebugging)
|
||||
err := b.SendPayload(method,
|
||||
path,
|
||||
headers,
|
||||
bytes.NewBuffer(nil),
|
||||
&interim,
|
||||
true,
|
||||
false,
|
||||
b.Verbose,
|
||||
b.HTTPDebugging,
|
||||
b.HTTPRecording)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -773,7 +781,7 @@ func getCryptocurrencyWithdrawalFee(c currency.Code) float64 {
|
||||
}
|
||||
|
||||
// WithdrawCrypto sends cryptocurrency to the address of your choosing
|
||||
func (b *Binance) WithdrawCrypto(asset, address, addressTag, name, amount string) (int64, error) {
|
||||
func (b *Binance) WithdrawCrypto(asset, address, addressTag, name, amount string) (string, error) {
|
||||
var resp WithdrawResponse
|
||||
path := fmt.Sprintf("%s%s", b.APIUrl, withdraw)
|
||||
|
||||
@@ -789,7 +797,7 @@ func (b *Binance) WithdrawCrypto(asset, address, addressTag, name, amount string
|
||||
}
|
||||
|
||||
if err := b.SendAuthHTTPRequest(http.MethodPost, path, params, &resp); err != nil {
|
||||
return -1, err
|
||||
return "", err
|
||||
}
|
||||
|
||||
if !resp.Success {
|
||||
|
||||
32
exchanges/binance/binance_live_test.go
Normal file
32
exchanges/binance/binance_live_test.go
Normal file
@@ -0,0 +1,32 @@
|
||||
//+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 binance
|
||||
|
||||
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")
|
||||
binanceConfig, err := cfg.GetExchangeConfig("Binance")
|
||||
if err != nil {
|
||||
log.Fatal("Test Failed - Binance Setup() init error", err)
|
||||
}
|
||||
binanceConfig.AuthenticatedAPISupport = true
|
||||
binanceConfig.APIKey = apiKey
|
||||
binanceConfig.APISecret = apiSecret
|
||||
b.SetDefaults()
|
||||
b.Setup(&binanceConfig)
|
||||
log.Printf(sharedtestvalues.LiveTesting, b.GetName(), b.APIUrl)
|
||||
os.Exit(m.Run())
|
||||
}
|
||||
44
exchanges/binance/binance_mock_test.go
Normal file
44
exchanges/binance/binance_mock_test.go
Normal file
@@ -0,0 +1,44 @@
|
||||
//+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 binance
|
||||
|
||||
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/binance/binance.json"
|
||||
|
||||
var mockTests = true
|
||||
|
||||
func TestMain(m *testing.M) {
|
||||
cfg := config.GetConfig()
|
||||
cfg.LoadConfig("../../testdata/configtest.json")
|
||||
binanceConfig, err := cfg.GetExchangeConfig("Binance")
|
||||
if err != nil {
|
||||
log.Fatal("Test Failed - Binance Setup() init error", err)
|
||||
}
|
||||
binanceConfig.AuthenticatedAPISupport = true
|
||||
binanceConfig.APIKey = apiKey
|
||||
binanceConfig.APISecret = apiSecret
|
||||
b.SetDefaults()
|
||||
b.Setup(&binanceConfig)
|
||||
|
||||
serverDetails, newClient, err := mock.NewVCRServer(mockfile)
|
||||
if err != nil {
|
||||
log.Fatalf("Test Failed - Mock server error %s", err)
|
||||
}
|
||||
|
||||
b.HTTPClient = newClient
|
||||
b.APIUrl = serverDetails
|
||||
|
||||
log.Printf(sharedtestvalues.MockTesting, b.GetName(), b.APIUrl)
|
||||
os.Exit(m.Run())
|
||||
}
|
||||
@@ -4,7 +4,6 @@ import (
|
||||
"testing"
|
||||
|
||||
"github.com/thrasher-corp/gocryptotrader/common"
|
||||
"github.com/thrasher-corp/gocryptotrader/config"
|
||||
"github.com/thrasher-corp/gocryptotrader/currency"
|
||||
exchange "github.com/thrasher-corp/gocryptotrader/exchanges"
|
||||
)
|
||||
@@ -18,26 +17,26 @@ const (
|
||||
|
||||
var b Binance
|
||||
|
||||
func TestSetDefaults(t *testing.T) {
|
||||
b.SetDefaults()
|
||||
func areTestAPIKeysSet() bool {
|
||||
if b.APIKey != "" && b.APIKey != "Key" &&
|
||||
b.APISecret != "" && b.APISecret != "Secret" {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func TestSetup(t *testing.T) {
|
||||
cfg := config.GetConfig()
|
||||
cfg.LoadConfig("../../testdata/configtest.json")
|
||||
binanceConfig, err := cfg.GetExchangeConfig("Binance")
|
||||
if err != nil {
|
||||
t.Error("Test Failed - Binance Setup() init error")
|
||||
func setFeeBuilder() *exchange.FeeBuilder {
|
||||
return &exchange.FeeBuilder{
|
||||
Amount: 1,
|
||||
FeeType: exchange.CryptocurrencyTradeFee,
|
||||
Pair: currency.NewPair(currency.BTC, currency.LTC),
|
||||
PurchasePrice: 1,
|
||||
}
|
||||
|
||||
binanceConfig.AuthenticatedAPISupport = true
|
||||
binanceConfig.APIKey = apiKey
|
||||
binanceConfig.APISecret = apiSecret
|
||||
b.Setup(&binanceConfig)
|
||||
}
|
||||
|
||||
func TestGetExchangeValidCurrencyPairs(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
_, err := b.GetExchangeValidCurrencyPairs()
|
||||
if err != nil {
|
||||
t.Error("Test Failed - Binance GetExchangeValidCurrencyPairs() error", err)
|
||||
@@ -46,6 +45,7 @@ func TestGetExchangeValidCurrencyPairs(t *testing.T) {
|
||||
|
||||
func TestGetOrderBook(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
_, err := b.GetOrderBook(OrderBookDataRequestParams{
|
||||
Symbol: "BTCUSDT",
|
||||
Limit: 10,
|
||||
@@ -71,14 +71,19 @@ func TestGetRecentTrades(t *testing.T) {
|
||||
|
||||
func TestGetHistoricalTrades(t *testing.T) {
|
||||
t.Parallel()
|
||||
_, err := b.GetHistoricalTrades("BTCUSDT", 5, 1337)
|
||||
if err == nil {
|
||||
|
||||
_, err := b.GetHistoricalTrades("BTCUSDT", 5, 0)
|
||||
if !mockTests && err == nil {
|
||||
t.Error("Test Failed - Binance GetHistoricalTrades() expecting error")
|
||||
}
|
||||
if mockTests && err == nil {
|
||||
t.Error("Test Failed - Binance GetHistoricalTrades() error", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetAggregatedTrades(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
_, err := b.GetAggregatedTrades("BTCUSDT", 5)
|
||||
if err != nil {
|
||||
t.Error("Test Failed - Binance GetAggregatedTrades() error", err)
|
||||
@@ -87,6 +92,7 @@ func TestGetAggregatedTrades(t *testing.T) {
|
||||
|
||||
func TestGetSpotKline(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
_, err := b.GetSpotKline(KlinesRequestParams{
|
||||
Symbol: "BTCUSDT",
|
||||
Interval: TimeIntervalFiveMinutes,
|
||||
@@ -99,6 +105,7 @@ func TestGetSpotKline(t *testing.T) {
|
||||
|
||||
func TestGetAveragePrice(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
_, err := b.GetAveragePrice("BTCUSDT")
|
||||
if err != nil {
|
||||
t.Error("Test Failed - Binance GetAveragePrice() error", err)
|
||||
@@ -107,6 +114,7 @@ func TestGetAveragePrice(t *testing.T) {
|
||||
|
||||
func TestGetPriceChangeStats(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
_, err := b.GetPriceChangeStats("BTCUSDT")
|
||||
if err != nil {
|
||||
t.Error("Test Failed - Binance GetPriceChangeStats() error", err)
|
||||
@@ -115,6 +123,7 @@ func TestGetPriceChangeStats(t *testing.T) {
|
||||
|
||||
func TestGetTickers(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
_, err := b.GetTickers()
|
||||
if err != nil {
|
||||
t.Error("Test Failed - Binance TestGetTickers error", err)
|
||||
@@ -123,6 +132,7 @@ func TestGetTickers(t *testing.T) {
|
||||
|
||||
func TestGetLatestSpotPrice(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
_, err := b.GetLatestSpotPrice("BTCUSDT")
|
||||
if err != nil {
|
||||
t.Error("Test Failed - Binance GetLatestSpotPrice() error", err)
|
||||
@@ -131,120 +141,62 @@ func TestGetLatestSpotPrice(t *testing.T) {
|
||||
|
||||
func TestGetBestPrice(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
_, err := b.GetBestPrice("BTCUSDT")
|
||||
if err != nil {
|
||||
t.Error("Test Failed - Binance GetBestPrice() error", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestNewOrder(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
if apiKey == "" || apiSecret == "" {
|
||||
t.Skip()
|
||||
}
|
||||
_, err := b.NewOrder(&NewOrderRequest{
|
||||
Symbol: "BTCUSDT",
|
||||
Side: BinanceRequestParamsSideSell,
|
||||
TradeType: BinanceRequestParamsOrderLimit,
|
||||
TimeInForce: BinanceRequestParamsTimeGTC,
|
||||
Quantity: 0.01,
|
||||
Price: 1536.1,
|
||||
})
|
||||
|
||||
if err == nil {
|
||||
t.Error("Test Failed - Binance NewOrder() error", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCancelExistingOrder(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
if apiKey == "" || apiSecret == "" {
|
||||
t.Skip()
|
||||
}
|
||||
|
||||
_, err := b.CancelExistingOrder("BTCUSDT", 82584683, "")
|
||||
if err != nil {
|
||||
t.Error("Test Failed - Binance CancelExistingOrder() error", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestQueryOrder(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
if apiKey == "" || apiSecret == "" {
|
||||
t.Skip()
|
||||
}
|
||||
|
||||
_, err := b.QueryOrder("BTCUSDT", "", 1337)
|
||||
if err == nil {
|
||||
t.Error("Test Failed - Binance QueryOrder() error", err)
|
||||
switch {
|
||||
case areTestAPIKeysSet() && err != nil:
|
||||
t.Error("Test Failed - QueryOrder() error", err)
|
||||
case !areTestAPIKeysSet() && err == nil && !mockTests:
|
||||
t.Error("Test Failed - QueryOrder() expecting an error when no keys are set")
|
||||
case mockTests && err != nil:
|
||||
t.Error("Test Failed - Mock QueryOrder() error", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestOpenOrders(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
if apiKey == "" || apiSecret == "" {
|
||||
t.Skip()
|
||||
}
|
||||
|
||||
_, err := b.OpenOrders("BTCUSDT")
|
||||
if err != nil {
|
||||
t.Error("Test Failed - Binance OpenOrders() error", err)
|
||||
switch {
|
||||
case areTestAPIKeysSet() && err != nil:
|
||||
t.Error("Test Failed - OpenOrders() error", err)
|
||||
case !areTestAPIKeysSet() && err == nil && !mockTests:
|
||||
t.Error("Test Failed - OpenOrders() expecting an error when no keys are set")
|
||||
case mockTests && err != nil:
|
||||
t.Error("Test Failed - Mock OpenOrders() error", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestAllOrders(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
if apiKey == "" || apiSecret == "" {
|
||||
t.Skip()
|
||||
}
|
||||
|
||||
_, err := b.AllOrders("BTCUSDT", "", "")
|
||||
if err != nil {
|
||||
t.Error("Test Failed - Binance AllOrders() error", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetAccount(t *testing.T) {
|
||||
if apiKey == "" || apiSecret == "" {
|
||||
t.Skip()
|
||||
}
|
||||
t.Parallel()
|
||||
b.SetDefaults()
|
||||
TestSetup(t)
|
||||
account, err := b.GetAccount()
|
||||
if err != nil {
|
||||
t.Fatal("Test Failed - Binance GetAccount() error", err)
|
||||
}
|
||||
if account.MakerCommission <= 0 {
|
||||
t.Fatalf("Test Failed. Expected > 0, Received %d", account.MakerCommission)
|
||||
}
|
||||
if account.TakerCommission <= 0 {
|
||||
t.Fatalf("Test Failed. Expected > 0, Received %d", account.TakerCommission)
|
||||
}
|
||||
|
||||
t.Logf("Current makerFee: %d", account.MakerCommission)
|
||||
t.Logf("Current takerFee: %d", account.TakerCommission)
|
||||
}
|
||||
|
||||
func setFeeBuilder() *exchange.FeeBuilder {
|
||||
return &exchange.FeeBuilder{
|
||||
Amount: 1,
|
||||
FeeType: exchange.CryptocurrencyTradeFee,
|
||||
Pair: currency.NewPair(currency.BTC, currency.LTC),
|
||||
PurchasePrice: 1,
|
||||
switch {
|
||||
case areTestAPIKeysSet() && err != nil:
|
||||
t.Error("Test Failed - AllOrders() error", err)
|
||||
case !areTestAPIKeysSet() && err == nil && !mockTests:
|
||||
t.Error("Test Failed - AllOrders() expecting an error when no keys are set")
|
||||
case mockTests && err != nil:
|
||||
t.Error("Test Failed - Mock AllOrders() error", err)
|
||||
}
|
||||
}
|
||||
|
||||
// TestGetFeeByTypeOfflineTradeFee logic test
|
||||
func TestGetFeeByTypeOfflineTradeFee(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
var feeBuilder = setFeeBuilder()
|
||||
b.GetFeeByType(feeBuilder)
|
||||
if apiKey == "" || apiSecret == "" {
|
||||
if !areTestAPIKeysSet() {
|
||||
if feeBuilder.FeeType != exchange.OfflineTradeFee {
|
||||
t.Errorf("Expected %v, received %v", exchange.OfflineTradeFee, feeBuilder.FeeType)
|
||||
}
|
||||
@@ -256,12 +208,11 @@ func TestGetFeeByTypeOfflineTradeFee(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestGetFee(t *testing.T) {
|
||||
b.SetDefaults()
|
||||
TestSetup(t)
|
||||
t.Parallel()
|
||||
|
||||
var feeBuilder = setFeeBuilder()
|
||||
|
||||
if apiKey != "" || apiSecret != "" {
|
||||
if areTestAPIKeysSet() || mockTests {
|
||||
// CryptocurrencyTradeFee Basic
|
||||
if resp, err := b.GetFee(feeBuilder); resp != float64(0.1) || err != nil {
|
||||
t.Error(err)
|
||||
@@ -331,19 +282,18 @@ func TestGetFee(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestFormatWithdrawPermissions(t *testing.T) {
|
||||
b.SetDefaults()
|
||||
t.Parallel()
|
||||
|
||||
expectedResult := exchange.AutoWithdrawCryptoText + " & " + exchange.NoFiatWithdrawalsText
|
||||
|
||||
withdrawPermissions := b.FormatWithdrawPermissions()
|
||||
|
||||
if withdrawPermissions != expectedResult {
|
||||
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,
|
||||
@@ -358,16 +308,18 @@ func TestGetActiveOrders(t *testing.T) {
|
||||
}
|
||||
|
||||
_, err = b.GetActiveOrders(&getOrdersRequest)
|
||||
if areTestAPIKeysSet() && err != nil {
|
||||
t.Errorf("Could not get open orders: %s", err)
|
||||
} else if !areTestAPIKeysSet() && err == nil {
|
||||
t.Error("Expecting an error when no keys are set")
|
||||
switch {
|
||||
case areTestAPIKeysSet() && err != nil:
|
||||
t.Error("Test Failed - GetActiveOrders() error", err)
|
||||
case !areTestAPIKeysSet() && err == nil && !mockTests:
|
||||
t.Error("Test Failed - GetActiveOrders() expecting an error when no keys are set")
|
||||
case mockTests && err != nil:
|
||||
t.Error("Test Failed - Mock GetActiveOrders() error", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetOrderHistory(t *testing.T) {
|
||||
b.SetDefaults()
|
||||
TestSetup(t)
|
||||
t.Parallel()
|
||||
|
||||
var getOrdersRequest = exchange.GetOrdersRequest{
|
||||
OrderType: exchange.AnyOrderType,
|
||||
@@ -383,144 +335,144 @@ func TestGetOrderHistory(t *testing.T) {
|
||||
currency.BTC)}
|
||||
|
||||
_, err = b.GetOrderHistory(&getOrdersRequest)
|
||||
if areTestAPIKeysSet() && err != nil {
|
||||
t.Errorf("Could not get order history: %s", err)
|
||||
} else if !areTestAPIKeysSet() && err == nil {
|
||||
t.Error("Expecting an error when no keys are set")
|
||||
switch {
|
||||
case areTestAPIKeysSet() && err != nil:
|
||||
t.Error("Test Failed - GetOrderHistory() error", err)
|
||||
case !areTestAPIKeysSet() && err == nil && !mockTests:
|
||||
t.Error("Test Failed - GetOrderHistory() expecting an error when no keys are set")
|
||||
case mockTests && err != nil:
|
||||
t.Error("Test Failed - Mock GetOrderHistory() error", 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)
|
||||
t.Parallel()
|
||||
|
||||
var p = currency.Pair{
|
||||
Delimiter: "",
|
||||
Base: currency.LTC,
|
||||
Quote: currency.BTC,
|
||||
if areTestAPIKeysSet() && !canManipulateRealOrders && !mockTests {
|
||||
t.Skip("API keys set, canManipulateRealOrders false, skipping test")
|
||||
}
|
||||
response, err := b.SubmitOrder(p, exchange.BuyOrderSide, exchange.MarketOrderType, 1, 1, "clientId")
|
||||
if areTestAPIKeysSet() && (err != nil || !response.IsOrderPlaced) {
|
||||
t.Errorf("Order failed to be placed: %v", err)
|
||||
} else if !areTestAPIKeysSet() && err == nil {
|
||||
t.Error("Expecting an error when no keys are set")
|
||||
|
||||
_, err := b.SubmitOrder(currency.NewPair(currency.LTC, currency.BTC),
|
||||
exchange.BuyOrderSide,
|
||||
exchange.MarketOrderType,
|
||||
1,
|
||||
1,
|
||||
"clientId")
|
||||
switch {
|
||||
case areTestAPIKeysSet() && err != nil:
|
||||
t.Error("Test Failed - SubmitOrder() error", err)
|
||||
case !areTestAPIKeysSet() && err == nil && !mockTests:
|
||||
t.Error("Test Failed - SubmitOrder() expecting an error when no keys are set")
|
||||
case mockTests && err != nil:
|
||||
t.Error("Test Failed - Mock SubmitOrder() error", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCancelExchangeOrder(t *testing.T) {
|
||||
b.SetDefaults()
|
||||
TestSetup(t)
|
||||
t.Parallel()
|
||||
|
||||
currencyPair := currency.NewPair(currency.LTC, currency.BTC)
|
||||
if areTestAPIKeysSet() && !canManipulateRealOrders && !mockTests {
|
||||
t.Skip("API keys set, canManipulateRealOrders false, skipping test")
|
||||
}
|
||||
|
||||
var orderCancellation = &exchange.OrderCancellation{
|
||||
OrderID: "1",
|
||||
WalletAddress: "1F5zVDgNjorJ51oGebSvNCrSAHpwGkUdDB",
|
||||
AccountID: "1",
|
||||
CurrencyPair: currencyPair,
|
||||
CurrencyPair: currency.NewPair(currency.LTC, currency.BTC),
|
||||
}
|
||||
|
||||
err := b.CancelOrder(orderCancellation)
|
||||
if !areTestAPIKeysSet() && err == nil {
|
||||
t.Error("Expecting an error when no keys are set")
|
||||
}
|
||||
if areTestAPIKeysSet() && err != nil {
|
||||
t.Errorf("Could not cancel orders: %v", err)
|
||||
switch {
|
||||
case areTestAPIKeysSet() && err != nil:
|
||||
t.Error("Test Failed - CancelExchangeOrder() error", err)
|
||||
case !areTestAPIKeysSet() && err == nil && !mockTests:
|
||||
t.Error("Test Failed - CancelExchangeOrder() expecting an error when no keys are set")
|
||||
case mockTests && err != nil:
|
||||
t.Error("Test Failed - Mock CancelExchangeOrder() error", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCancelAllExchangeOrders(t *testing.T) {
|
||||
b.SetDefaults()
|
||||
TestSetup(t)
|
||||
t.Parallel()
|
||||
|
||||
currencyPair := currency.NewPair(currency.LTC, currency.BTC)
|
||||
if areTestAPIKeysSet() && !canManipulateRealOrders && !mockTests {
|
||||
t.Skip("API keys set, canManipulateRealOrders false, skipping test")
|
||||
}
|
||||
|
||||
var orderCancellation = &exchange.OrderCancellation{
|
||||
OrderID: "1",
|
||||
WalletAddress: "1F5zVDgNjorJ51oGebSvNCrSAHpwGkUdDB",
|
||||
AccountID: "1",
|
||||
CurrencyPair: currencyPair,
|
||||
CurrencyPair: currency.NewPair(currency.LTC, currency.BTC),
|
||||
}
|
||||
|
||||
resp, err := b.CancelAllOrders(orderCancellation)
|
||||
|
||||
if !areTestAPIKeysSet() && err == nil {
|
||||
t.Error("Expecting an error when no keys are set")
|
||||
}
|
||||
if areTestAPIKeysSet() && err != nil {
|
||||
t.Errorf("Could not cancel order: %v", err)
|
||||
}
|
||||
|
||||
if len(resp.OrderStatus) > 0 {
|
||||
t.Errorf("%v orders failed to cancel", len(resp.OrderStatus))
|
||||
_, err := b.CancelAllOrders(orderCancellation)
|
||||
switch {
|
||||
case areTestAPIKeysSet() && err != nil:
|
||||
t.Error("Test Failed - CancelAllExchangeOrders() error", err)
|
||||
case !areTestAPIKeysSet() && err == nil && !mockTests:
|
||||
t.Error("Test Failed - CancelAllExchangeOrders() expecting an error when no keys are set")
|
||||
case mockTests && err != nil:
|
||||
t.Error("Test Failed - Mock CancelAllExchangeOrders() error", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetAccountInfo(t *testing.T) {
|
||||
b.SetDefaults()
|
||||
TestSetup(t)
|
||||
if apiKey == "" || apiSecret == "" {
|
||||
t.Skip()
|
||||
}
|
||||
t.Parallel()
|
||||
|
||||
_, err := b.GetAccountInfo()
|
||||
if err != nil {
|
||||
t.Error("test failed - GetAccountInfo() error", err)
|
||||
switch {
|
||||
case areTestAPIKeysSet() && err != nil:
|
||||
t.Error("Test Failed - GetAccountInfo() error", err)
|
||||
case !areTestAPIKeysSet() && err == nil && !mockTests:
|
||||
t.Error("Test Failed - GetAccountInfo() expecting an error when no keys are set")
|
||||
case mockTests && err != nil:
|
||||
t.Error("Test Failed - Mock GetAccountInfo() error", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestModifyOrder(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
_, err := b.ModifyOrder(&exchange.ModifyOrder{})
|
||||
if err == nil {
|
||||
t.Error("Test failed - ModifyOrder() error")
|
||||
t.Error("Test failed - ModifyOrder() error cannot be nil")
|
||||
}
|
||||
}
|
||||
|
||||
func TestWithdraw(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")
|
||||
}
|
||||
|
||||
var withdrawCryptoRequest = exchange.WithdrawRequest{
|
||||
Amount: 100,
|
||||
Amount: 0,
|
||||
Currency: currency.BTC,
|
||||
Address: "1F5zVDgNjorJ51oGebSvNCrSAHpwGkUdDB",
|
||||
Description: "WITHDRAW IT ALL",
|
||||
}
|
||||
|
||||
_, err := b.WithdrawCryptocurrencyFunds(&withdrawCryptoRequest)
|
||||
if !areTestAPIKeysSet() && err == nil {
|
||||
t.Error("Expecting an error when no keys are set")
|
||||
}
|
||||
if areTestAPIKeysSet() && err != nil {
|
||||
t.Errorf("Withdraw failed to be placed: %v", err)
|
||||
switch {
|
||||
case areTestAPIKeysSet() && err != nil:
|
||||
t.Error("Test Failed - Withdraw() error", err)
|
||||
case !areTestAPIKeysSet() && err == nil && !mockTests:
|
||||
t.Error("Test Failed - Withdraw() expecting an error when no keys are set")
|
||||
case mockTests && err != nil:
|
||||
t.Error("Test Failed - Mock Withdraw() error", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestWithdrawFiat(t *testing.T) {
|
||||
b.SetDefaults()
|
||||
TestSetup(t)
|
||||
|
||||
if areTestAPIKeysSet() && !canManipulateRealOrders {
|
||||
t.Skip("API keys set, canManipulateRealOrders false, skipping test")
|
||||
}
|
||||
|
||||
var withdrawFiatRequest = exchange.WithdrawRequest{}
|
||||
t.Parallel()
|
||||
|
||||
var withdrawFiatRequest exchange.WithdrawRequest
|
||||
_, err := b.WithdrawFiatFunds(&withdrawFiatRequest)
|
||||
if err != common.ErrFunctionNotSupported {
|
||||
t.Errorf("Expected '%v', received: '%v'", common.ErrFunctionNotSupported, err)
|
||||
@@ -528,15 +480,9 @@ func TestWithdrawFiat(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestWithdrawInternationalBank(t *testing.T) {
|
||||
b.SetDefaults()
|
||||
TestSetup(t)
|
||||
|
||||
if areTestAPIKeysSet() && !canManipulateRealOrders {
|
||||
t.Skip("API keys set, canManipulateRealOrders false, skipping test")
|
||||
}
|
||||
|
||||
var withdrawFiatRequest = exchange.WithdrawRequest{}
|
||||
t.Parallel()
|
||||
|
||||
var withdrawFiatRequest exchange.WithdrawRequest
|
||||
_, err := b.WithdrawFiatFundsToInternationalBank(&withdrawFiatRequest)
|
||||
if err != common.ErrFunctionNotSupported {
|
||||
t.Errorf("Expected '%v', received: '%v'", common.ErrFunctionNotSupported, err)
|
||||
@@ -544,15 +490,15 @@ func TestWithdrawInternationalBank(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestGetDepositAddress(t *testing.T) {
|
||||
if areTestAPIKeysSet() {
|
||||
_, 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() && err != nil:
|
||||
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 - Mock GetDepositAddress() error", err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -314,7 +314,7 @@ type NewOrderResponse struct {
|
||||
Price float64 `json:"price,string"`
|
||||
Qty float64 `json:"qty,string"`
|
||||
Commission float64 `json:"commission,string"`
|
||||
CommissionAsset float64 `json:"commissionAsset,string"`
|
||||
CommissionAsset string `json:"commissionAsset"`
|
||||
} `json:"fills"`
|
||||
}
|
||||
|
||||
@@ -621,5 +621,5 @@ var WithdrawalFees = map[currency.Code]float64{
|
||||
type WithdrawResponse struct {
|
||||
Success bool `json:"success"`
|
||||
Msg string `json:"msg"`
|
||||
ID int64 `json:"id"`
|
||||
ID string `json:"id"`
|
||||
}
|
||||
|
||||
@@ -301,9 +301,10 @@ func (b *Binance) GetDepositAddress(cryptocurrency currency.Code, _ string) (str
|
||||
// submitted
|
||||
func (b *Binance) WithdrawCryptocurrencyFunds(withdrawRequest *exchange.WithdrawRequest) (string, error) {
|
||||
amountStr := strconv.FormatFloat(withdrawRequest.Amount, 'f', -1, 64)
|
||||
id, err := b.WithdrawCrypto(withdrawRequest.Currency.String(), withdrawRequest.Address, withdrawRequest.AddressTag, withdrawRequest.Description, amountStr)
|
||||
|
||||
return strconv.FormatInt(id, 10), err
|
||||
return b.WithdrawCrypto(withdrawRequest.Currency.String(),
|
||||
withdrawRequest.Address,
|
||||
withdrawRequest.AddressTag,
|
||||
withdrawRequest.Description, amountStr)
|
||||
}
|
||||
|
||||
// WithdrawFiatFunds returns a withdrawal ID when a
|
||||
|
||||
@@ -1030,7 +1030,16 @@ func (b *Bitfinex) CloseMarginFunding(swapID int64) (Offer, error) {
|
||||
|
||||
// SendHTTPRequest sends an unauthenticated request
|
||||
func (b *Bitfinex) SendHTTPRequest(path string, result interface{}, verbose bool) error {
|
||||
return b.SendPayload(http.MethodGet, path, nil, nil, result, false, false, verbose, b.HTTPDebugging)
|
||||
return b.SendPayload(http.MethodGet,
|
||||
path,
|
||||
nil,
|
||||
nil,
|
||||
result,
|
||||
false,
|
||||
false,
|
||||
verbose,
|
||||
b.HTTPDebugging,
|
||||
b.HTTPRecording)
|
||||
}
|
||||
|
||||
// SendAuthenticatedHTTPRequest sends an autheticated http request and json
|
||||
@@ -1076,7 +1085,8 @@ func (b *Bitfinex) SendAuthenticatedHTTPRequest(method, path string, params map[
|
||||
true,
|
||||
true,
|
||||
b.Verbose,
|
||||
b.HTTPDebugging)
|
||||
b.HTTPDebugging,
|
||||
b.HTTPRecording)
|
||||
}
|
||||
|
||||
// GetFee returns an estimate of fee based on type of transaction
|
||||
|
||||
@@ -380,7 +380,16 @@ func (b *Bitflyer) GetTradingCommission() {
|
||||
|
||||
// SendHTTPRequest sends an unauthenticated request
|
||||
func (b *Bitflyer) 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)
|
||||
}
|
||||
|
||||
// SendAuthHTTPRequest sends an authenticated HTTP request
|
||||
|
||||
@@ -531,7 +531,16 @@ func (b *Bithumb) MarketSellOrder(currency string, units float64) (MarketSell, e
|
||||
|
||||
// SendHTTPRequest sends an unauthenticated HTTP request
|
||||
func (b *Bithumb) 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 HTTP request to bithumb
|
||||
@@ -575,7 +584,8 @@ func (b *Bithumb) SendAuthenticatedHTTPRequest(path string, params url.Values, r
|
||||
true,
|
||||
true,
|
||||
b.Verbose,
|
||||
b.HTTPDebugging)
|
||||
b.HTTPDebugging,
|
||||
b.HTTPRecording)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -879,14 +879,32 @@ func (b *Bitmex) SendHTTPRequest(path string, params Parameter, result interface
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = b.SendPayload(http.MethodGet, encodedPath, nil, nil, &respCheck, false, false, b.Verbose, b.HTTPDebugging)
|
||||
err = b.SendPayload(http.MethodGet,
|
||||
encodedPath,
|
||||
nil,
|
||||
nil,
|
||||
&respCheck,
|
||||
false,
|
||||
false,
|
||||
b.Verbose,
|
||||
b.HTTPDebugging,
|
||||
b.HTTPRecording)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return b.CaptureError(respCheck, result)
|
||||
}
|
||||
}
|
||||
err := b.SendPayload(http.MethodGet, path, nil, nil, &respCheck, false, false, b.Verbose, b.HTTPDebugging)
|
||||
err := b.SendPayload(http.MethodGet,
|
||||
path,
|
||||
nil,
|
||||
nil,
|
||||
&respCheck,
|
||||
false,
|
||||
false,
|
||||
b.Verbose,
|
||||
b.HTTPDebugging,
|
||||
b.HTTPRecording)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -938,7 +956,8 @@ func (b *Bitmex) SendAuthenticatedHTTPRequest(verb, path string, params Paramete
|
||||
true,
|
||||
false,
|
||||
b.Verbose,
|
||||
b.HTTPDebugging)
|
||||
b.HTTPDebugging,
|
||||
b.HTTPRecording)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
33
exchanges/bitstamp/bitstamp_live_test.go
Normal file
33
exchanges/bitstamp/bitstamp_live_test.go
Normal 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())
|
||||
}
|
||||
45
exchanges/bitstamp/bitstamp_mock_test.go
Normal file
45
exchanges/bitstamp/bitstamp_mock_test.go
Normal 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())
|
||||
}
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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),
|
||||
|
||||
@@ -495,7 +495,16 @@ func (b *Bittrex) GetDepositHistory(currency string) (WithdrawalHistory, error)
|
||||
|
||||
// SendHTTPRequest sends an unauthenticated HTTP request
|
||||
func (b *Bittrex) 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 http request to a desired
|
||||
@@ -516,7 +525,16 @@ func (b *Bittrex) SendAuthenticatedHTTPRequest(path string, values url.Values, r
|
||||
headers := make(map[string]string)
|
||||
headers["apisign"] = common.HexEncodeToString(hmac)
|
||||
|
||||
return b.SendPayload(http.MethodGet, rawQuery, headers, nil, result, true, true, b.Verbose, b.HTTPDebugging)
|
||||
return b.SendPayload(http.MethodGet,
|
||||
rawQuery,
|
||||
headers,
|
||||
nil,
|
||||
result,
|
||||
true,
|
||||
true,
|
||||
b.Verbose,
|
||||
b.HTTPDebugging,
|
||||
b.HTTPRecording)
|
||||
}
|
||||
|
||||
// GetFee returns an estimate of fee based on type of transaction
|
||||
|
||||
@@ -433,7 +433,16 @@ func (b *BTCMarkets) WithdrawAUD(accountName, accountNumber, bankName, bsbNumber
|
||||
|
||||
// SendHTTPRequest sends an unauthenticated HTTP request
|
||||
func (b *BTCMarkets) 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)
|
||||
}
|
||||
|
||||
// SendAuthenticatedRequest sends an authenticated HTTP request
|
||||
@@ -484,7 +493,8 @@ func (b *BTCMarkets) SendAuthenticatedRequest(reqType, path string, data, result
|
||||
true,
|
||||
true,
|
||||
b.Verbose,
|
||||
b.HTTPDebugging)
|
||||
b.HTTPDebugging,
|
||||
b.HTTPRecording)
|
||||
}
|
||||
|
||||
// GetFee returns an estimate of fee based on type of transaction
|
||||
|
||||
@@ -275,8 +275,16 @@ func (b *BTSE) GetFills(orderID, productID, before, after, limit string) (*Fille
|
||||
|
||||
// SendHTTPRequest sends an HTTP request to the desired endpoint
|
||||
func (b *BTSE) SendHTTPRequest(method, endpoint string, result interface{}) error {
|
||||
p := fmt.Sprintf("%s/%s", btseAPIURL, endpoint)
|
||||
return b.SendPayload(method, p, nil, nil, &result, false, false, b.Verbose, b.HTTPDebugging)
|
||||
return b.SendPayload(method,
|
||||
fmt.Sprintf("%s/%s", btseAPIURL, endpoint),
|
||||
nil,
|
||||
nil,
|
||||
&result,
|
||||
false,
|
||||
false,
|
||||
b.Verbose,
|
||||
b.HTTPDebugging,
|
||||
b.HTTPRecording)
|
||||
}
|
||||
|
||||
// SendAuthenticatedHTTPRequest sends an authenticated HTTP request to the desired endpoint
|
||||
@@ -301,8 +309,16 @@ func (b *BTSE) SendAuthenticatedHTTPRequest(method, endpoint string, req map[str
|
||||
if b.Verbose {
|
||||
log.Debugf("Sending %s request to URL %s with params %s\n", method, p, string(payload))
|
||||
}
|
||||
return b.SendPayload(method, p, headers, strings.NewReader(string(payload)),
|
||||
&result, true, false, b.Verbose, b.HTTPDebugging)
|
||||
return b.SendPayload(method,
|
||||
p,
|
||||
headers,
|
||||
strings.NewReader(string(payload)),
|
||||
&result,
|
||||
true,
|
||||
false,
|
||||
b.Verbose,
|
||||
b.HTTPDebugging,
|
||||
b.HTTPRecording)
|
||||
}
|
||||
|
||||
// GetFee returns an estimate of fee based on type of transaction
|
||||
|
||||
@@ -820,7 +820,16 @@ func (c *CoinbasePro) GetTrailingVolume() ([]Volume, error) {
|
||||
|
||||
// SendHTTPRequest sends an unauthenticated HTTP request
|
||||
func (c *CoinbasePro) SendHTTPRequest(path string, result interface{}) error {
|
||||
return c.SendPayload(http.MethodGet, path, nil, nil, result, false, false, c.Verbose, c.HTTPDebugging)
|
||||
return c.SendPayload(http.MethodGet,
|
||||
path,
|
||||
nil,
|
||||
nil,
|
||||
result,
|
||||
false,
|
||||
false,
|
||||
c.Verbose,
|
||||
c.HTTPDebugging,
|
||||
c.HTTPRecording)
|
||||
}
|
||||
|
||||
// SendAuthenticatedHTTPRequest sends an authenticated HTTP reque
|
||||
@@ -861,7 +870,8 @@ func (c *CoinbasePro) SendAuthenticatedHTTPRequest(method, path string, params m
|
||||
true,
|
||||
true,
|
||||
c.Verbose,
|
||||
c.HTTPDebugging)
|
||||
c.HTTPDebugging,
|
||||
c.HTTPRecording)
|
||||
}
|
||||
|
||||
// GetFee returns an estimate of fee based on type of transaction
|
||||
|
||||
@@ -405,7 +405,7 @@ func (c *COINUT) SendHTTPRequest(apiRequest string, params map[string]interface{
|
||||
true,
|
||||
c.Verbose,
|
||||
c.HTTPDebugging,
|
||||
)
|
||||
c.HTTPRecording)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -286,6 +286,7 @@ type Base struct {
|
||||
HTTPTimeout time.Duration
|
||||
HTTPUserAgent string
|
||||
HTTPDebugging bool
|
||||
HTTPRecording bool
|
||||
WebsocketURL string
|
||||
APIUrl string
|
||||
APIUrlDefault string
|
||||
|
||||
@@ -373,7 +373,16 @@ func (e *EXMO) GetWalletHistory(date int64) (WalletHistory, error) {
|
||||
|
||||
// SendHTTPRequest sends an unauthenticated HTTP request
|
||||
func (e *EXMO) SendHTTPRequest(path string, result interface{}) error {
|
||||
return e.SendPayload(http.MethodGet, path, nil, nil, result, false, false, e.Verbose, e.HTTPDebugging)
|
||||
return e.SendPayload(http.MethodGet,
|
||||
path,
|
||||
nil,
|
||||
nil,
|
||||
result,
|
||||
false,
|
||||
false,
|
||||
e.Verbose,
|
||||
e.HTTPDebugging,
|
||||
e.HTTPRecording)
|
||||
}
|
||||
|
||||
// SendAuthenticatedHTTPRequest sends an authenticated HTTP request
|
||||
@@ -413,7 +422,8 @@ func (e *EXMO) SendAuthenticatedHTTPRequest(method, endpoint string, vals url.Va
|
||||
true,
|
||||
true,
|
||||
e.Verbose,
|
||||
e.HTTPDebugging)
|
||||
e.HTTPDebugging,
|
||||
e.HTTPRecording)
|
||||
}
|
||||
|
||||
// GetFee returns an estimate of fee based on type of transaction
|
||||
|
||||
@@ -421,7 +421,16 @@ func (g *Gateio) CancelExistingOrder(orderID int64, symbol string) (bool, error)
|
||||
|
||||
// SendHTTPRequest sends an unauthenticated HTTP request
|
||||
func (g *Gateio) SendHTTPRequest(path string, result interface{}) error {
|
||||
return g.SendPayload(http.MethodGet, path, nil, nil, result, false, false, g.Verbose, g.HTTPDebugging)
|
||||
return g.SendPayload(http.MethodGet,
|
||||
path,
|
||||
nil,
|
||||
nil,
|
||||
result,
|
||||
false,
|
||||
false,
|
||||
g.Verbose,
|
||||
g.HTTPDebugging,
|
||||
g.HTTPRecording)
|
||||
}
|
||||
|
||||
// CancelAllExistingOrders all orders for a given symbol and side
|
||||
@@ -521,7 +530,8 @@ func (g *Gateio) SendAuthenticatedHTTPRequest(method, endpoint, param string, re
|
||||
true,
|
||||
false,
|
||||
g.Verbose,
|
||||
g.HTTPDebugging)
|
||||
g.HTTPDebugging,
|
||||
g.HTTPRecording)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -6,7 +6,6 @@ import (
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/thrasher-corp/gocryptotrader/common"
|
||||
@@ -56,11 +55,6 @@ const (
|
||||
geminiRoleFundManager = "fundmanager"
|
||||
)
|
||||
|
||||
var (
|
||||
// Session manager
|
||||
Session map[int]*Gemini
|
||||
)
|
||||
|
||||
// Gemini is the overarching type across the Gemini package, create multiple
|
||||
// instances with differing APIkeys for segregation of roles for authenticated
|
||||
// requests & sessions by appending new sessions to the Session map using
|
||||
@@ -73,32 +67,6 @@ type Gemini struct {
|
||||
RequiresHeartBeat bool
|
||||
}
|
||||
|
||||
// AddSession adds a new session to the gemini base
|
||||
func AddSession(g *Gemini, sessionID int, apiKey, apiSecret, role string, needsHeartbeat, isSandbox bool) error {
|
||||
if Session == nil {
|
||||
Session = make(map[int]*Gemini)
|
||||
}
|
||||
|
||||
_, ok := Session[sessionID]
|
||||
if ok {
|
||||
return errors.New("sessionID already being used")
|
||||
}
|
||||
|
||||
g.APIKey = apiKey
|
||||
g.APISecret = apiSecret
|
||||
g.Role = role
|
||||
g.RequiresHeartBeat = needsHeartbeat
|
||||
g.APIUrl = geminiAPIURL
|
||||
|
||||
if isSandbox {
|
||||
g.APIUrl = geminiSandboxAPIURL
|
||||
}
|
||||
|
||||
Session[sessionID] = g
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// SetDefaults sets package defaults for gemini exchange
|
||||
func (g *Gemini) SetDefaults() {
|
||||
g.Name = "Gemini"
|
||||
@@ -259,9 +227,15 @@ func (g *Gemini) GetTicker(currencyPair string) (Ticker, error) {
|
||||
// params - limit_bids or limit_asks [OPTIONAL] default 50, 0 returns all Values
|
||||
// Type is an integer ie "params.Set("limit_asks", 30)"
|
||||
func (g *Gemini) GetOrderbook(currencyPair string, params url.Values) (Orderbook, error) {
|
||||
path := common.EncodeURLValues(fmt.Sprintf("%s/v%s/%s/%s", g.APIUrl, geminiAPIVersion, geminiOrderbook, currencyPair), params)
|
||||
orderbook := Orderbook{}
|
||||
path := common.EncodeURLValues(
|
||||
fmt.Sprintf("%s/v%s/%s/%s",
|
||||
g.APIUrl,
|
||||
geminiAPIVersion,
|
||||
geminiOrderbook,
|
||||
currencyPair),
|
||||
params)
|
||||
|
||||
var orderbook Orderbook
|
||||
return orderbook, g.SendHTTPRequest(path, &orderbook)
|
||||
}
|
||||
|
||||
@@ -307,20 +281,9 @@ func (g *Gemini) GetAuctionHistory(currencyPair string, params url.Values) ([]Au
|
||||
return auctionHist, g.SendHTTPRequest(path, &auctionHist)
|
||||
}
|
||||
|
||||
func (g *Gemini) isCorrectSession() error {
|
||||
if g.Role != geminiRoleTrader {
|
||||
return errors.New("incorrect role for APIKEY cannot use this function")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// NewOrder Only limit orders are supported through the API at present.
|
||||
// returns order ID if successful
|
||||
func (g *Gemini) NewOrder(symbol string, amount, price float64, side, orderType string) (int64, error) {
|
||||
if err := g.isCorrectSession(); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
req := make(map[string]interface{})
|
||||
req["symbol"] = symbol
|
||||
req["amount"] = strconv.FormatFloat(amount, 'f', -1, 64)
|
||||
@@ -405,6 +368,7 @@ func (g *Gemini) GetOrders() ([]Order, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
switch r := response.(type) {
|
||||
case orders:
|
||||
return r.orders, nil
|
||||
@@ -422,7 +386,7 @@ func (g *Gemini) GetTradeHistory(currencyPair string, timestamp int64) ([]TradeH
|
||||
req := make(map[string]interface{})
|
||||
req["symbol"] = currencyPair
|
||||
|
||||
if timestamp != 0 {
|
||||
if timestamp > 0 {
|
||||
req["timestamp"] = timestamp
|
||||
}
|
||||
|
||||
@@ -511,7 +475,16 @@ func (g *Gemini) PostHeartbeat() (string, error) {
|
||||
|
||||
// SendHTTPRequest sends an unauthenticated request
|
||||
func (g *Gemini) SendHTTPRequest(path string, result interface{}) error {
|
||||
return g.SendPayload(http.MethodGet, path, nil, nil, result, false, false, g.Verbose, g.HTTPDebugging)
|
||||
return g.SendPayload(http.MethodGet,
|
||||
path,
|
||||
nil,
|
||||
nil,
|
||||
result,
|
||||
false,
|
||||
false,
|
||||
g.Verbose,
|
||||
g.HTTPDebugging,
|
||||
g.HTTPRecording)
|
||||
}
|
||||
|
||||
// SendAuthenticatedHTTPRequest sends an authenticated HTTP request to the
|
||||
@@ -521,7 +494,6 @@ func (g *Gemini) SendAuthenticatedHTTPRequest(method, path string, params map[st
|
||||
return fmt.Errorf(exchange.WarningAuthenticatedRequestWithoutCredentialsSet, g.Name)
|
||||
}
|
||||
|
||||
headers := make(map[string]string)
|
||||
req := make(map[string]interface{})
|
||||
req["request"] = fmt.Sprintf("/v%s/%s", geminiAPIVersion, path)
|
||||
req["nonce"] = g.Requester.GetNonce(true).String()
|
||||
@@ -542,6 +514,7 @@ func (g *Gemini) SendAuthenticatedHTTPRequest(method, path string, params map[st
|
||||
PayloadBase64 := common.Base64Encode(PayloadJSON)
|
||||
hmac := common.GetHMAC(common.HashSHA512_384, []byte(PayloadBase64), []byte(g.APISecret))
|
||||
|
||||
headers := make(map[string]string)
|
||||
headers["Content-Length"] = "0"
|
||||
headers["Content-Type"] = "text/plain"
|
||||
headers["X-GEMINI-APIKEY"] = g.APIKey
|
||||
@@ -549,7 +522,16 @@ func (g *Gemini) SendAuthenticatedHTTPRequest(method, path string, params map[st
|
||||
headers["X-GEMINI-SIGNATURE"] = common.HexEncodeToString(hmac)
|
||||
headers["Cache-Control"] = "no-cache"
|
||||
|
||||
return g.SendPayload(method, g.APIUrl+"/v1/"+path, headers, strings.NewReader(""), result, true, false, g.Verbose, g.HTTPDebugging)
|
||||
return g.SendPayload(method,
|
||||
g.APIUrl+"/v1/"+path,
|
||||
headers,
|
||||
nil,
|
||||
result,
|
||||
true,
|
||||
false,
|
||||
g.Verbose,
|
||||
g.HTTPDebugging,
|
||||
g.HTTPRecording)
|
||||
}
|
||||
|
||||
// GetFee returns an estimate of fee based on type of transaction
|
||||
@@ -585,9 +567,9 @@ func getOfflineTradeFee(price, amount float64) float64 {
|
||||
func calculateTradingFee(notionVolume *NotionalVolume, purchasePrice, amount float64, isMaker bool) float64 {
|
||||
var volumeFee float64
|
||||
if isMaker {
|
||||
volumeFee = (float64(notionVolume.MakerFee) / 100)
|
||||
volumeFee = (float64(notionVolume.APIMakerFeeBPS) / 10000)
|
||||
} else {
|
||||
volumeFee = (float64(notionVolume.TakerFee) / 100)
|
||||
volumeFee = (float64(notionVolume.APITakerFeeBPS) / 10000)
|
||||
}
|
||||
|
||||
return volumeFee * amount * purchasePrice
|
||||
|
||||
33
exchanges/gemini/gemini_live_test.go
Normal file
33
exchanges/gemini/gemini_live_test.go
Normal 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 gemini
|
||||
|
||||
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")
|
||||
geminiConfig, err := cfg.GetExchangeConfig("Gemini")
|
||||
if err != nil {
|
||||
log.Fatal("Test Failed - Gemini Setup() init error", err)
|
||||
}
|
||||
geminiConfig.AuthenticatedAPISupport = true
|
||||
geminiConfig.APIKey = apiKey
|
||||
geminiConfig.APISecret = apiSecret
|
||||
g.SetDefaults()
|
||||
g.Setup(&geminiConfig)
|
||||
g.APIUrl = geminiSandboxAPIURL
|
||||
log.Printf(sharedtestvalues.LiveTesting, g.GetName(), g.APIUrl)
|
||||
os.Exit(m.Run())
|
||||
}
|
||||
44
exchanges/gemini/gemini_mock_test.go
Normal file
44
exchanges/gemini/gemini_mock_test.go
Normal file
@@ -0,0 +1,44 @@
|
||||
//+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 gemini
|
||||
|
||||
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/gemini/gemini.json"
|
||||
|
||||
var mockTests = true
|
||||
|
||||
func TestMain(m *testing.M) {
|
||||
cfg := config.GetConfig()
|
||||
cfg.LoadConfig("../../testdata/configtest.json")
|
||||
geminiConfig, err := cfg.GetExchangeConfig("Gemini")
|
||||
if err != nil {
|
||||
log.Fatal("Test Failed - Mock server error", err)
|
||||
}
|
||||
geminiConfig.AuthenticatedAPISupport = true
|
||||
geminiConfig.APIKey = apiKey
|
||||
geminiConfig.APISecret = apiSecret
|
||||
g.SetDefaults()
|
||||
g.Setup(&geminiConfig)
|
||||
|
||||
serverDetails, newClient, err := mock.NewVCRServer(mockFile)
|
||||
if err != nil {
|
||||
log.Fatalf("Test Failed - Mock server error %s", err)
|
||||
}
|
||||
|
||||
g.HTTPClient = newClient
|
||||
g.APIUrl = serverDetails
|
||||
|
||||
log.Printf(sharedtestvalues.MockTesting, g.GetName(), g.APIUrl)
|
||||
os.Exit(m.Run())
|
||||
}
|
||||
@@ -7,7 +7,6 @@ import (
|
||||
|
||||
"github.com/gorilla/websocket"
|
||||
"github.com/thrasher-corp/gocryptotrader/common"
|
||||
"github.com/thrasher-corp/gocryptotrader/config"
|
||||
"github.com/thrasher-corp/gocryptotrader/currency"
|
||||
exchange "github.com/thrasher-corp/gocryptotrader/exchanges"
|
||||
"github.com/thrasher-corp/gocryptotrader/exchanges/sharedtestvalues"
|
||||
@@ -15,75 +14,21 @@ import (
|
||||
)
|
||||
|
||||
// Please enter sandbox API keys & assigned roles for better testing procedures
|
||||
|
||||
const (
|
||||
apiKey1 = ""
|
||||
apiSecret1 = ""
|
||||
apiKeyRole1 = ""
|
||||
sessionHeartBeat1 = false
|
||||
|
||||
apiKey2 = ""
|
||||
apiSecret2 = ""
|
||||
apiKeyRole2 = ""
|
||||
sessionHeartBeat2 = false
|
||||
|
||||
apiKey = ""
|
||||
apiSecret = ""
|
||||
apiKeyRole = ""
|
||||
sessionHeartBeat = false
|
||||
canManipulateRealOrders = false
|
||||
)
|
||||
|
||||
func TestAddSession(t *testing.T) {
|
||||
var g1 Gemini
|
||||
if Session[1] == nil {
|
||||
err := AddSession(&g1, 1, apiKey1, apiSecret1, apiKeyRole1, true, true)
|
||||
if err != nil {
|
||||
t.Error("Test failed - AddSession() error", err)
|
||||
}
|
||||
err = AddSession(&g1, 1, apiKey1, apiSecret1, apiKeyRole1, true, true)
|
||||
if err == nil {
|
||||
t.Error("Test failed - AddSession() error", err)
|
||||
}
|
||||
}
|
||||
const testCurrency = "btcusd"
|
||||
|
||||
if len(Session) <= 1 {
|
||||
var g2 Gemini
|
||||
err := AddSession(&g2, 2, apiKey2, apiSecret2, apiKeyRole2, false, true)
|
||||
if err != nil {
|
||||
t.Error("Test failed - AddSession() error", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestSetDefaults(t *testing.T) {
|
||||
Session[1].SetDefaults()
|
||||
Session[2].SetDefaults()
|
||||
}
|
||||
|
||||
func TestSetup(t *testing.T) {
|
||||
cfg := config.GetConfig()
|
||||
cfg.LoadConfig("../../testdata/configtest.json")
|
||||
geminiConfig, err := cfg.GetExchangeConfig("Gemini")
|
||||
if err != nil {
|
||||
t.Error("Test Failed - Gemini Setup() init error")
|
||||
}
|
||||
|
||||
geminiConfig.AuthenticatedWebsocketAPISupport = true
|
||||
geminiConfig.AuthenticatedAPISupport = true
|
||||
geminiConfig.Websocket = true
|
||||
Session[1].Setup(&geminiConfig)
|
||||
Session[2].Setup(&geminiConfig)
|
||||
|
||||
Session[1].APIKey = apiKey1
|
||||
Session[1].APISecret = apiSecret1
|
||||
|
||||
Session[2].APIKey = apiKey2
|
||||
Session[2].APISecret = apiSecret2
|
||||
|
||||
Session[1].APIUrl = geminiSandboxAPIURL
|
||||
Session[2].APIUrl = geminiSandboxAPIURL
|
||||
}
|
||||
var g Gemini
|
||||
|
||||
func TestGetSymbols(t *testing.T) {
|
||||
t.Parallel()
|
||||
_, err := Session[1].GetSymbols()
|
||||
_, err := g.GetSymbols()
|
||||
if err != nil {
|
||||
t.Error("Test Failed - GetSymbols() error", err)
|
||||
}
|
||||
@@ -91,11 +36,11 @@ func TestGetSymbols(t *testing.T) {
|
||||
|
||||
func TestGetTicker(t *testing.T) {
|
||||
t.Parallel()
|
||||
_, err := Session[2].GetTicker("BTCUSD")
|
||||
_, err := g.GetTicker("BTCUSD")
|
||||
if err != nil {
|
||||
t.Error("Test Failed - GetTicker() error", err)
|
||||
}
|
||||
_, err = Session[1].GetTicker("bla")
|
||||
_, err = g.GetTicker("bla")
|
||||
if err == nil {
|
||||
t.Error("Test Failed - GetTicker() error", err)
|
||||
}
|
||||
@@ -103,7 +48,7 @@ func TestGetTicker(t *testing.T) {
|
||||
|
||||
func TestGetOrderbook(t *testing.T) {
|
||||
t.Parallel()
|
||||
_, err := Session[1].GetOrderbook("btcusd", url.Values{})
|
||||
_, err := g.GetOrderbook(testCurrency, url.Values{})
|
||||
if err != nil {
|
||||
t.Error("Test Failed - GetOrderbook() error", err)
|
||||
}
|
||||
@@ -111,25 +56,25 @@ func TestGetOrderbook(t *testing.T) {
|
||||
|
||||
func TestGetTrades(t *testing.T) {
|
||||
t.Parallel()
|
||||
_, err := Session[2].GetTrades("btcusd", url.Values{})
|
||||
_, err := g.GetTrades(testCurrency, url.Values{})
|
||||
if err != nil {
|
||||
t.Error("Test Failed - GetTrades() error", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetNotionalVolume(t *testing.T) {
|
||||
if apiKey2 != "" && apiSecret2 != "" {
|
||||
t.Parallel()
|
||||
_, err := Session[2].GetNotionalVolume()
|
||||
if err != nil {
|
||||
t.Error("Test Failed - GetNotionalVolume() error", err)
|
||||
}
|
||||
t.Parallel()
|
||||
_, err := g.GetNotionalVolume()
|
||||
if err != nil && mockTests {
|
||||
t.Error("Test Failed - GetNotionalVolume() error", err)
|
||||
} else if err == nil && !mockTests {
|
||||
t.Error("Test Failed - GetNotionalVolume() error cannot be nil")
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetAuction(t *testing.T) {
|
||||
t.Parallel()
|
||||
_, err := Session[1].GetAuction("btcusd")
|
||||
_, err := g.GetAuction(testCurrency)
|
||||
if err != nil {
|
||||
t.Error("Test Failed - GetAuction() error", err)
|
||||
}
|
||||
@@ -137,7 +82,7 @@ func TestGetAuction(t *testing.T) {
|
||||
|
||||
func TestGetAuctionHistory(t *testing.T) {
|
||||
t.Parallel()
|
||||
_, err := Session[2].GetAuctionHistory("btcusd", url.Values{})
|
||||
_, err := g.GetAuctionHistory(testCurrency, url.Values{})
|
||||
if err != nil {
|
||||
t.Error("Test Failed - GetAuctionHistory() error", err)
|
||||
}
|
||||
@@ -145,79 +90,87 @@ func TestGetAuctionHistory(t *testing.T) {
|
||||
|
||||
func TestNewOrder(t *testing.T) {
|
||||
t.Parallel()
|
||||
_, err := Session[1].NewOrder("btcusd", 1, 4500, "buy", "exchange limit")
|
||||
if err == nil {
|
||||
t.Error("Test Failed - NewOrder() error", err)
|
||||
}
|
||||
_, err = Session[2].NewOrder("btcusd", 1, 4500, "buy", "exchange limit")
|
||||
if err == nil {
|
||||
_, err := g.NewOrder(testCurrency, 1, 9000, "buy", "exchange limit")
|
||||
if err != nil && mockTests {
|
||||
t.Error("Test Failed - NewOrder() error", err)
|
||||
} else if err == nil && !mockTests {
|
||||
t.Error("Test Failed - NewOrder() error cannot be nil")
|
||||
}
|
||||
}
|
||||
|
||||
func TestCancelExistingOrder(t *testing.T) {
|
||||
t.Parallel()
|
||||
_, err := Session[1].CancelExistingOrder(1337)
|
||||
if err == nil {
|
||||
_, err := g.CancelExistingOrder(265555413)
|
||||
if err != nil && mockTests {
|
||||
t.Error("Test Failed - CancelExistingOrder() error", err)
|
||||
} else if err == nil && !mockTests {
|
||||
t.Error("Test Failed - CancelExistingOrder() error cannot be nil")
|
||||
}
|
||||
}
|
||||
|
||||
func TestCancelExistingOrders(t *testing.T) {
|
||||
t.Parallel()
|
||||
_, err := Session[1].CancelExistingOrders(false)
|
||||
if err == nil {
|
||||
t.Error("Test Failed - CancelExistingOrders() error", err)
|
||||
}
|
||||
_, err = Session[2].CancelExistingOrders(true)
|
||||
if err == nil {
|
||||
_, err := g.CancelExistingOrders(false)
|
||||
if err != nil && mockTests {
|
||||
t.Error("Test Failed - CancelExistingOrders() error", err)
|
||||
} else if err == nil && !mockTests {
|
||||
t.Error("Test Failed - CancelExistingOrders() error cannot be nil")
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetOrderStatus(t *testing.T) {
|
||||
t.Parallel()
|
||||
_, err := Session[2].GetOrderStatus(1337)
|
||||
if err == nil {
|
||||
_, err := g.GetOrderStatus(265563260)
|
||||
if err != nil && mockTests {
|
||||
t.Error("Test Failed - GetOrderStatus() error", err)
|
||||
} else if err == nil && !mockTests {
|
||||
t.Error("Test Failed - GetOrderStatus() error cannot be nil")
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetOrders(t *testing.T) {
|
||||
t.Parallel()
|
||||
_, err := Session[1].GetOrders()
|
||||
if err == nil {
|
||||
_, err := g.GetOrders()
|
||||
if err != nil && mockTests {
|
||||
t.Error("Test Failed - GetOrders() error", err)
|
||||
} else if err == nil && !mockTests {
|
||||
t.Error("Test Failed - GetOrders() error cannot be nil")
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetTradeHistory(t *testing.T) {
|
||||
t.Parallel()
|
||||
_, err := Session[1].GetTradeHistory("btcusd", 0)
|
||||
if err == nil {
|
||||
_, err := g.GetTradeHistory(testCurrency, 0)
|
||||
if err != nil && mockTests {
|
||||
t.Error("Test Failed - GetTradeHistory() error", err)
|
||||
} else if err == nil && !mockTests {
|
||||
t.Error("Test Failed - GetTradeHistory() error cannot be nil")
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetTradeVolume(t *testing.T) {
|
||||
t.Parallel()
|
||||
_, err := Session[2].GetTradeVolume()
|
||||
if err == nil {
|
||||
_, err := g.GetTradeVolume()
|
||||
if err != nil && mockTests {
|
||||
t.Error("Test Failed - GetTradeVolume() error", err)
|
||||
} else if err == nil && !mockTests {
|
||||
t.Error("Test Failed - GetTradeVolume() error cannot be nil")
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetBalances(t *testing.T) {
|
||||
t.Parallel()
|
||||
_, err := Session[1].GetBalances()
|
||||
if err == nil {
|
||||
_, err := g.GetBalances()
|
||||
if err != nil && mockTests {
|
||||
t.Error("Test Failed - GetBalances() error", err)
|
||||
} else if err == nil && !mockTests {
|
||||
t.Error("Test Failed - GetBalances() error cannot be nil")
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetCryptoDepositAddress(t *testing.T) {
|
||||
t.Parallel()
|
||||
_, err := Session[1].GetCryptoDepositAddress("LOL123", "btc")
|
||||
_, err := g.GetCryptoDepositAddress("LOL123", "btc")
|
||||
if err == nil {
|
||||
t.Error("Test Failed - GetCryptoDepositAddress() error", err)
|
||||
}
|
||||
@@ -225,7 +178,7 @@ func TestGetCryptoDepositAddress(t *testing.T) {
|
||||
|
||||
func TestWithdrawCrypto(t *testing.T) {
|
||||
t.Parallel()
|
||||
_, err := Session[1].WithdrawCrypto("LOL123", "btc", 1)
|
||||
_, err := g.WithdrawCrypto("LOL123", "btc", 1)
|
||||
if err == nil {
|
||||
t.Error("Test Failed - WithdrawCrypto() error", err)
|
||||
}
|
||||
@@ -233,9 +186,11 @@ func TestWithdrawCrypto(t *testing.T) {
|
||||
|
||||
func TestPostHeartbeat(t *testing.T) {
|
||||
t.Parallel()
|
||||
_, err := Session[2].PostHeartbeat()
|
||||
if err == nil {
|
||||
_, err := g.PostHeartbeat()
|
||||
if err != nil && mockTests {
|
||||
t.Error("Test Failed - PostHeartbeat() error", err)
|
||||
} else if err == nil && !mockTests {
|
||||
t.Error("Test Failed - PostHeartbeat() error cannot be nil")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -254,61 +209,75 @@ func setFeeBuilder() *exchange.FeeBuilder {
|
||||
|
||||
// TestGetFeeByTypeOfflineTradeFee logic test
|
||||
func TestGetFeeByTypeOfflineTradeFee(t *testing.T) {
|
||||
TestAddSession(t)
|
||||
TestSetDefaults(t)
|
||||
TestSetup(t)
|
||||
t.Parallel()
|
||||
var feeBuilder = setFeeBuilder()
|
||||
Session[1].GetFeeByType(feeBuilder)
|
||||
if apiKey1 == "" || apiSecret1 == "" {
|
||||
g.GetFeeByType(feeBuilder)
|
||||
|
||||
if !areTestAPIKeysSet() {
|
||||
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) {
|
||||
t.Parallel()
|
||||
var feeBuilder = setFeeBuilder()
|
||||
if apiKey1 != "" && apiSecret1 != "" {
|
||||
if areTestAPIKeysSet() || mockTests {
|
||||
// CryptocurrencyTradeFee Basic
|
||||
if resp, err := Session[1].GetFee(feeBuilder); resp != float64(0.01) || err != nil {
|
||||
if resp, err := g.GetFee(feeBuilder); resp != float64(0.0035) || err != nil {
|
||||
t.Errorf("Test Failed - GetFee() error. Expected: %f, Received: %f",
|
||||
float64(0.0035),
|
||||
resp)
|
||||
t.Error(err)
|
||||
t.Errorf("Test Failed - GetFee() error. Expected: %f, Received: %f", float64(0.01), resp)
|
||||
}
|
||||
|
||||
// CryptocurrencyTradeFee High quantity
|
||||
feeBuilder = setFeeBuilder()
|
||||
feeBuilder.Amount = 1000
|
||||
feeBuilder.PurchasePrice = 1000
|
||||
if resp, err := Session[1].GetFee(feeBuilder); resp != float64(100) || err != nil {
|
||||
t.Errorf("Test Failed - GetFee() error. Expected: %f, Received: %f", float64(100), resp)
|
||||
if resp, err := g.GetFee(feeBuilder); resp != float64(3500) || err != nil {
|
||||
t.Errorf("Test Failed - GetFee() error. Expected: %f, Received: %f",
|
||||
float64(3500),
|
||||
resp)
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
// CryptocurrencyTradeFee IsMaker
|
||||
feeBuilder = setFeeBuilder()
|
||||
feeBuilder.IsMaker = true
|
||||
if resp, err := Session[1].GetFee(feeBuilder); resp != float64(0.01) || err != nil {
|
||||
t.Errorf("Test Failed - GetFee() error. Expected: %f, Received: %f", float64(0.01), resp)
|
||||
if resp, err := g.GetFee(feeBuilder); resp != float64(0.001) || err != nil {
|
||||
t.Errorf("Test Failed - GetFee() error. Expected: %f, Received: %f",
|
||||
float64(0.001),
|
||||
resp)
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
// CryptocurrencyTradeFee Negative purchase price
|
||||
feeBuilder = setFeeBuilder()
|
||||
feeBuilder.PurchasePrice = -1000
|
||||
if resp, err := Session[1].GetFee(feeBuilder); resp != float64(0) || err != nil {
|
||||
t.Errorf("Test Failed - GetFee() error. Expected: %f, Received: %f", float64(0), resp)
|
||||
if resp, err := g.GetFee(feeBuilder); resp != float64(0) || err != nil {
|
||||
t.Errorf("Test Failed - GetFee() error. Expected: %f, Received: %f",
|
||||
float64(0),
|
||||
resp)
|
||||
t.Error(err)
|
||||
}
|
||||
}
|
||||
// CryptocurrencyWithdrawalFee Basic
|
||||
feeBuilder = setFeeBuilder()
|
||||
feeBuilder.FeeType = exchange.CryptocurrencyWithdrawalFee
|
||||
if resp, err := Session[1].GetFee(feeBuilder); resp != float64(0) || err != nil {
|
||||
t.Errorf("Test Failed - GetFee() error. Expected: %f, Received: %f", float64(0), resp)
|
||||
if resp, err := g.GetFee(feeBuilder); resp != float64(0) || err != nil {
|
||||
t.Errorf("Test Failed - GetFee() error. Expected: %f, Received: %f",
|
||||
float64(0),
|
||||
resp)
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
@@ -316,24 +285,30 @@ func TestGetFee(t *testing.T) {
|
||||
feeBuilder = setFeeBuilder()
|
||||
feeBuilder.Pair.Base = currency.NewCode("hello")
|
||||
feeBuilder.FeeType = exchange.CryptocurrencyWithdrawalFee
|
||||
if resp, err := Session[1].GetFee(feeBuilder); resp != float64(0) || err != nil {
|
||||
t.Errorf("Test Failed - GetFee() error. Expected: %f, Received: %f", float64(0), resp)
|
||||
if resp, err := g.GetFee(feeBuilder); resp != float64(0) || err != nil {
|
||||
t.Errorf("Test Failed - GetFee() error. Expected: %f, Received: %f",
|
||||
float64(0),
|
||||
resp)
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
// CyptocurrencyDepositFee Basic
|
||||
feeBuilder = setFeeBuilder()
|
||||
feeBuilder.FeeType = exchange.CyptocurrencyDepositFee
|
||||
if resp, err := Session[1].GetFee(feeBuilder); resp != float64(0) || err != nil {
|
||||
t.Errorf("Test Failed - GetFee() error. Expected: %f, Received: %f", float64(0), resp)
|
||||
if resp, err := g.GetFee(feeBuilder); resp != float64(0) || err != nil {
|
||||
t.Errorf("Test Failed - GetFee() error. Expected: %f, Received: %f",
|
||||
float64(0),
|
||||
resp)
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
// InternationalBankDepositFee Basic
|
||||
feeBuilder = setFeeBuilder()
|
||||
feeBuilder.FeeType = exchange.InternationalBankDepositFee
|
||||
if resp, err := Session[1].GetFee(feeBuilder); resp != float64(0) || err != nil {
|
||||
t.Errorf("Test Failed - GetFee() error. Expected: %f, Received: %f", float64(0), resp)
|
||||
if resp, err := g.GetFee(feeBuilder); resp != float64(0) || err != nil {
|
||||
t.Errorf("Test Failed - GetFee() error. Expected: %f, Received: %f",
|
||||
float64(0),
|
||||
resp)
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
@@ -341,78 +316,82 @@ func TestGetFee(t *testing.T) {
|
||||
feeBuilder = setFeeBuilder()
|
||||
feeBuilder.FeeType = exchange.InternationalBankWithdrawalFee
|
||||
feeBuilder.FiatCurrency = currency.USD
|
||||
if resp, err := Session[1].GetFee(feeBuilder); resp != float64(0) || err != nil {
|
||||
t.Errorf("Test Failed - GetFee() error. Expected: %f, Received: %f", float64(0), resp)
|
||||
if resp, err := g.GetFee(feeBuilder); resp != float64(0) || err != nil {
|
||||
t.Errorf("Test Failed - GetFee() error. Expected: %f, Received: %f",
|
||||
float64(0),
|
||||
resp)
|
||||
t.Error(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestFormatWithdrawPermissions(t *testing.T) {
|
||||
TestAddSession(t)
|
||||
TestSetDefaults(t)
|
||||
TestSetup(t)
|
||||
t.Parallel()
|
||||
expectedResult := exchange.AutoWithdrawCryptoWithAPIPermissionText +
|
||||
" & " +
|
||||
exchange.AutoWithdrawCryptoWithSetupText +
|
||||
" & " +
|
||||
exchange.WithdrawFiatViaWebsiteOnlyText
|
||||
|
||||
expectedResult := exchange.AutoWithdrawCryptoWithAPIPermissionText + " & " + exchange.AutoWithdrawCryptoWithSetupText + " & " + exchange.WithdrawFiatViaWebsiteOnlyText
|
||||
|
||||
withdrawPermissions := Session[1].FormatWithdrawPermissions()
|
||||
withdrawPermissions := g.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) {
|
||||
TestAddSession(t)
|
||||
TestSetDefaults(t)
|
||||
TestSetup(t)
|
||||
|
||||
t.Parallel()
|
||||
var getOrdersRequest = exchange.GetOrdersRequest{
|
||||
OrderType: exchange.AnyOrderType,
|
||||
Currencies: []currency.Pair{currency.NewPair(currency.LTC, currency.BTC)},
|
||||
OrderType: exchange.AnyOrderType,
|
||||
Currencies: []currency.Pair{
|
||||
currency.NewPair(currency.LTC, currency.BTC),
|
||||
},
|
||||
}
|
||||
|
||||
_, err := Session[1].GetActiveOrders(&getOrdersRequest)
|
||||
if areTestAPIKeysSet() && err != nil {
|
||||
_, err := g.GetActiveOrders(&getOrdersRequest)
|
||||
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) {
|
||||
TestAddSession(t)
|
||||
TestSetDefaults(t)
|
||||
TestSetup(t)
|
||||
|
||||
t.Parallel()
|
||||
var getOrdersRequest = exchange.GetOrdersRequest{
|
||||
OrderType: exchange.AnyOrderType,
|
||||
Currencies: []currency.Pair{currency.NewPair(currency.LTC, currency.BTC)},
|
||||
}
|
||||
|
||||
_, err := Session[1].GetOrderHistory(&getOrdersRequest)
|
||||
if areTestAPIKeysSet() && err != nil {
|
||||
_, err := g.GetOrderHistory(&getOrdersRequest)
|
||||
switch {
|
||||
case areTestAPIKeysSet() && err != nil:
|
||||
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 err != nil && mockTests:
|
||||
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 Session[1].APIKey != "" && Session[1].APIKey != "Key" &&
|
||||
Session[1].APISecret != "" && Session[1].APISecret != "Secret" {
|
||||
if g.APIKey != "" && g.APIKey != "Key" &&
|
||||
g.APISecret != "" && g.APISecret != "Secret" {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func TestSubmitOrder(t *testing.T) {
|
||||
TestAddSession(t)
|
||||
TestSetDefaults(t)
|
||||
TestSetup(t)
|
||||
|
||||
if areTestAPIKeysSet() && !canManipulateRealOrders {
|
||||
t.Parallel()
|
||||
if areTestAPIKeysSet() && !canManipulateRealOrders && !mockTests {
|
||||
t.Skip("API keys set, canManipulateRealOrders false, skipping test")
|
||||
}
|
||||
|
||||
@@ -421,47 +400,47 @@ func TestSubmitOrder(t *testing.T) {
|
||||
Base: currency.LTC,
|
||||
Quote: currency.BTC,
|
||||
}
|
||||
response, err := Session[1].SubmitOrder(p, exchange.BuyOrderSide, exchange.MarketOrderType, 1, 10, "1234234")
|
||||
if areTestAPIKeysSet() && (err != nil || !response.IsOrderPlaced) {
|
||||
|
||||
response, err := g.SubmitOrder(p,
|
||||
exchange.BuyOrderSide,
|
||||
exchange.LimitOrderType,
|
||||
1,
|
||||
10,
|
||||
"1234234")
|
||||
switch {
|
||||
case areTestAPIKeysSet() && (err != nil || !response.IsOrderPlaced):
|
||||
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.Errorf("Order failed to be placed: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCancelExchangeOrder(t *testing.T) {
|
||||
TestAddSession(t)
|
||||
TestSetDefaults(t)
|
||||
TestSetup(t)
|
||||
|
||||
if areTestAPIKeysSet() && !canManipulateRealOrders {
|
||||
t.Parallel()
|
||||
if areTestAPIKeysSet() && !canManipulateRealOrders && !mockTests {
|
||||
t.Skip("API keys set, canManipulateRealOrders false, skipping test")
|
||||
}
|
||||
|
||||
currencyPair := currency.NewPair(currency.LTC, currency.BTC)
|
||||
|
||||
var orderCancellation = &exchange.OrderCancellation{
|
||||
OrderID: "1",
|
||||
WalletAddress: "1F5zVDgNjorJ51oGebSvNCrSAHpwGkUdDB",
|
||||
AccountID: "1",
|
||||
CurrencyPair: currencyPair,
|
||||
OrderID: "266029865",
|
||||
}
|
||||
|
||||
err := Session[1].CancelOrder(orderCancellation)
|
||||
if !areTestAPIKeysSet() && err == nil {
|
||||
err := g.CancelOrder(orderCancellation)
|
||||
switch {
|
||||
case !areTestAPIKeysSet() && err == nil && !mockTests:
|
||||
t.Error("Expecting an error when no keys are set")
|
||||
}
|
||||
if areTestAPIKeysSet() && err != nil {
|
||||
case areTestAPIKeysSet() && err != nil:
|
||||
t.Errorf("Could not cancel orders: %v", err)
|
||||
case err != nil && mockTests:
|
||||
t.Errorf("Could not cancel orders: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCancelAllExchangeOrders(t *testing.T) {
|
||||
TestAddSession(t)
|
||||
TestSetDefaults(t)
|
||||
TestSetup(t)
|
||||
|
||||
if areTestAPIKeysSet() && !canManipulateRealOrders {
|
||||
t.Parallel()
|
||||
if areTestAPIKeysSet() && !canManipulateRealOrders && !mockTests {
|
||||
t.Skip("API keys set, canManipulateRealOrders false, skipping test")
|
||||
}
|
||||
|
||||
@@ -474,12 +453,13 @@ func TestCancelAllExchangeOrders(t *testing.T) {
|
||||
CurrencyPair: currencyPair,
|
||||
}
|
||||
|
||||
resp, err := Session[1].CancelAllOrders(orderCancellation)
|
||||
|
||||
if !areTestAPIKeysSet() && err == nil {
|
||||
resp, err := g.CancelAllOrders(orderCancellation)
|
||||
switch {
|
||||
case !areTestAPIKeysSet() && err == nil && !mockTests:
|
||||
t.Error("Expecting an error when no keys are set")
|
||||
}
|
||||
if areTestAPIKeysSet() && err != nil {
|
||||
case areTestAPIKeysSet() && err != nil:
|
||||
t.Errorf("Could not cancel orders: %v", err)
|
||||
case mockTests && err != nil:
|
||||
t.Errorf("Could not cancel orders: %v", err)
|
||||
}
|
||||
|
||||
@@ -489,16 +469,15 @@ func TestCancelAllExchangeOrders(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestModifyOrder(t *testing.T) {
|
||||
_, err := Session[1].ModifyOrder(&exchange.ModifyOrder{})
|
||||
t.Parallel()
|
||||
_, err := g.ModifyOrder(&exchange.ModifyOrder{})
|
||||
if err == nil {
|
||||
t.Error("Test failed - ModifyOrder() error")
|
||||
}
|
||||
}
|
||||
|
||||
func TestWithdraw(t *testing.T) {
|
||||
TestAddSession(t)
|
||||
TestSetDefaults(t)
|
||||
TestSetup(t)
|
||||
t.Parallel()
|
||||
var withdrawCryptoRequest = exchange.WithdrawRequest{
|
||||
Amount: 100,
|
||||
Currency: currency.BTC,
|
||||
@@ -506,55 +485,55 @@ func TestWithdraw(t *testing.T) {
|
||||
Description: "WITHDRAW IT ALL",
|
||||
}
|
||||
|
||||
if areTestAPIKeysSet() && !canManipulateRealOrders {
|
||||
if areTestAPIKeysSet() && !canManipulateRealOrders && !mockTests {
|
||||
t.Skip("API keys set, canManipulateRealOrders false, skipping test")
|
||||
}
|
||||
|
||||
_, err := Session[1].WithdrawCryptocurrencyFunds(&withdrawCryptoRequest)
|
||||
_, err := g.WithdrawCryptocurrencyFunds(&withdrawCryptoRequest)
|
||||
if !areTestAPIKeysSet() && err == nil {
|
||||
t.Error("Expecting an error when no keys are set")
|
||||
}
|
||||
if areTestAPIKeysSet() && err != nil {
|
||||
if areTestAPIKeysSet() && err != nil && !mockTests {
|
||||
t.Errorf("Withdraw failed to be placed: %v", err)
|
||||
}
|
||||
if areTestAPIKeysSet() && err == nil && mockTests {
|
||||
t.Errorf("Withdraw failed to be placed: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestWithdrawFiat(t *testing.T) {
|
||||
TestAddSession(t)
|
||||
TestSetDefaults(t)
|
||||
TestSetup(t)
|
||||
|
||||
if areTestAPIKeysSet() && !canManipulateRealOrders {
|
||||
t.Parallel()
|
||||
if areTestAPIKeysSet() && !canManipulateRealOrders && !mockTests {
|
||||
t.Skip("API keys set, canManipulateRealOrders false, skipping test")
|
||||
}
|
||||
|
||||
var withdrawFiatRequest = exchange.WithdrawRequest{}
|
||||
|
||||
_, err := Session[1].WithdrawFiatFunds(&withdrawFiatRequest)
|
||||
_, err := g.WithdrawFiatFunds(&withdrawFiatRequest)
|
||||
if err != common.ErrFunctionNotSupported {
|
||||
t.Errorf("Expected '%v', received: '%v'", common.ErrFunctionNotSupported, err)
|
||||
t.Errorf("Expected '%v', received: '%v'",
|
||||
common.ErrFunctionNotSupported,
|
||||
err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestWithdrawInternationalBank(t *testing.T) {
|
||||
TestAddSession(t)
|
||||
TestSetDefaults(t)
|
||||
TestSetup(t)
|
||||
|
||||
if areTestAPIKeysSet() && !canManipulateRealOrders {
|
||||
t.Parallel()
|
||||
if areTestAPIKeysSet() && !canManipulateRealOrders && !mockTests {
|
||||
t.Skip("API keys set, canManipulateRealOrders false, skipping test")
|
||||
}
|
||||
|
||||
var withdrawFiatRequest = exchange.WithdrawRequest{}
|
||||
|
||||
_, err := Session[1].WithdrawFiatFundsToInternationalBank(&withdrawFiatRequest)
|
||||
_, err := g.WithdrawFiatFundsToInternationalBank(&withdrawFiatRequest)
|
||||
if err != common.ErrFunctionNotSupported {
|
||||
t.Errorf("Expected '%v', received: '%v'", common.ErrFunctionNotSupported, err)
|
||||
t.Errorf("Expected '%v', received: '%v'",
|
||||
common.ErrFunctionNotSupported,
|
||||
err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetDepositAddress(t *testing.T) {
|
||||
_, err := Session[1].GetDepositAddress(currency.BTC, "")
|
||||
t.Parallel()
|
||||
_, err := g.GetDepositAddress(currency.BTC, "")
|
||||
if err == nil {
|
||||
t.Error("Test Failed - GetDepositAddress error cannot be nil")
|
||||
}
|
||||
@@ -562,13 +541,12 @@ func TestGetDepositAddress(t *testing.T) {
|
||||
|
||||
// TestWsAuth dials websocket, sends login request.
|
||||
func TestWsAuth(t *testing.T) {
|
||||
TestAddSession(t)
|
||||
TestSetDefaults(t)
|
||||
TestSetup(t)
|
||||
g := Session[1]
|
||||
t.Parallel()
|
||||
g.WebsocketURL = geminiWebsocketSandboxEndpoint
|
||||
|
||||
if !g.Websocket.IsEnabled() && !g.AuthenticatedWebsocketAPISupport || !areTestAPIKeysSet() {
|
||||
if !g.Websocket.IsEnabled() &&
|
||||
!g.AuthenticatedWebsocketAPISupport ||
|
||||
!areTestAPIKeysSet() {
|
||||
t.Skip(wshandler.WebsocketNotEnabled)
|
||||
}
|
||||
var dialer websocket.Dialer
|
||||
|
||||
@@ -145,16 +145,23 @@ type TradeVolume struct {
|
||||
SellTakerCount float64 `json:"sell_taker_count"`
|
||||
}
|
||||
|
||||
// NotionalVolume api call for fees
|
||||
// NotionalVolume api call for fees, all return fee amounts are in basis points
|
||||
type NotionalVolume struct {
|
||||
MakerFee int64 `json:"maker_fee_bps"`
|
||||
TakerFee int64 `json:"taker_fee_bps"`
|
||||
AuctionFee int64 `json:"auction_fee_bps"`
|
||||
ThirtyDayVolume float64 `json:"notional_30d_volume"`
|
||||
LastedUpdated int64 `json:"last_updated_ms"`
|
||||
AccountID int64 `json:"account_id"`
|
||||
Date string `json:"date"`
|
||||
APIAuctionFeeBPS int64 `json:"api_auction_fee_bps"`
|
||||
APIMakerFeeBPS int64 `json:"api_maker_fee_bps"`
|
||||
APITakerFeeBPS int64 `json:"api_taker_fee_bps"`
|
||||
BlockMakerFeeBPS int64 `json:"block_maker_fee_bps"`
|
||||
BlockTakerFeeBPS int64 `json:"block_taker_fee_bps"`
|
||||
FixAuctionFeeBPS int64 `json:"fix_auction_fee_bps"`
|
||||
FixMakerFeeBPS int64 `json:"fix_maker_fee_bps"`
|
||||
FixTakerFeeBPS int64 `json:"fix_taker_fee_bps"`
|
||||
OneDayNotionalVolumes []OneDayNotionalVolume `json:"notional_1d_volume"`
|
||||
ThirtyDayVolume float64 `json:"notional_30d_volume"`
|
||||
WebAuctionFeeBPS int64 `json:"web_auction_fee_bps"`
|
||||
WebMakerFeeBPS int64 `json:"web_maker_fee_bps"`
|
||||
WebTakerFeeBPS int64 `json:"web_taker_fee_bps"`
|
||||
LastedUpdated int64 `json:"last_updated_ms"`
|
||||
Date string `json:"date"`
|
||||
}
|
||||
|
||||
// OneDayNotionalVolume Contains the notioanl volume for a single day
|
||||
|
||||
@@ -161,11 +161,17 @@ func (g *Gemini) GetExchangeHistory(p currency.Pair, assetType string) ([]exchan
|
||||
// SubmitOrder submits a new order
|
||||
func (g *Gemini) SubmitOrder(p currency.Pair, side exchange.OrderSide, orderType exchange.OrderType, amount, price float64, _ string) (exchange.SubmitOrderResponse, error) {
|
||||
var submitOrderResponse exchange.SubmitOrderResponse
|
||||
p = exchange.FormatExchangeCurrency(g.Name, p)
|
||||
|
||||
if orderType != exchange.LimitOrderType {
|
||||
return submitOrderResponse, errors.New("only limit orders are enabled through this API")
|
||||
}
|
||||
|
||||
response, err := g.NewOrder(p.String(),
|
||||
amount,
|
||||
price,
|
||||
side.ToString(),
|
||||
orderType.ToString())
|
||||
"exchange limit")
|
||||
|
||||
if response > 0 {
|
||||
submitOrderResponse.OrderID = fmt.Sprintf("%v", response)
|
||||
|
||||
@@ -622,7 +622,16 @@ func (h *HitBTC) TransferBalance(currency, from, to string, amount float64) (boo
|
||||
|
||||
// SendHTTPRequest sends an unauthenticated HTTP request
|
||||
func (h *HitBTC) SendHTTPRequest(path string, result interface{}) error {
|
||||
return h.SendPayload(http.MethodGet, path, nil, nil, result, false, false, h.Verbose, h.HTTPDebugging)
|
||||
return h.SendPayload(http.MethodGet,
|
||||
path,
|
||||
nil,
|
||||
nil,
|
||||
result,
|
||||
false,
|
||||
false,
|
||||
h.Verbose,
|
||||
h.HTTPDebugging,
|
||||
h.HTTPRecording)
|
||||
}
|
||||
|
||||
// SendAuthenticatedHTTPRequest sends an authenticated http request
|
||||
@@ -644,7 +653,8 @@ func (h *HitBTC) SendAuthenticatedHTTPRequest(method, endpoint string, values ur
|
||||
true,
|
||||
false,
|
||||
h.Verbose,
|
||||
h.HTTPDebugging)
|
||||
h.HTTPDebugging,
|
||||
h.HTTPRecording)
|
||||
}
|
||||
|
||||
// GetFee returns an estimate of fee based on type of transaction
|
||||
|
||||
@@ -895,7 +895,16 @@ func (h *HUOBI) CancelWithdraw(withdrawID int64) (int64, error) {
|
||||
|
||||
// SendHTTPRequest sends an unauthenticated HTTP request
|
||||
func (h *HUOBI) SendHTTPRequest(path string, result interface{}) error {
|
||||
return h.SendPayload(http.MethodGet, path, nil, nil, result, false, false, h.Verbose, h.HTTPDebugging)
|
||||
return h.SendPayload(http.MethodGet,
|
||||
path,
|
||||
nil,
|
||||
nil,
|
||||
result,
|
||||
false,
|
||||
false,
|
||||
h.Verbose,
|
||||
h.HTTPDebugging,
|
||||
h.HTTPRecording)
|
||||
}
|
||||
|
||||
// SendAuthenticatedHTTPRequest sends authenticated requests to the HUOBI API
|
||||
@@ -972,7 +981,16 @@ func (h *HUOBI) SendAuthenticatedHTTPRequest(method, endpoint string, values url
|
||||
body = encoded
|
||||
}
|
||||
|
||||
return h.SendPayload(method, urlPath, headers, bytes.NewReader(body), result, true, false, h.Verbose, h.HTTPDebugging)
|
||||
return h.SendPayload(method,
|
||||
urlPath,
|
||||
headers,
|
||||
bytes.NewReader(body),
|
||||
result,
|
||||
true,
|
||||
false,
|
||||
h.Verbose,
|
||||
h.HTTPDebugging,
|
||||
h.HTTPRecording)
|
||||
}
|
||||
|
||||
// GetFee returns an estimate of fee based on type of transaction
|
||||
|
||||
@@ -890,7 +890,16 @@ func (h *HUOBIHADAX) CancelWithdraw(withdrawID int64) (int64, error) {
|
||||
|
||||
// SendHTTPRequest sends an unauthenticated HTTP request
|
||||
func (h *HUOBIHADAX) SendHTTPRequest(path string, result interface{}) error {
|
||||
return h.SendPayload(http.MethodGet, path, nil, nil, result, false, false, h.Verbose, h.HTTPDebugging)
|
||||
return h.SendPayload(http.MethodGet,
|
||||
path,
|
||||
nil,
|
||||
nil,
|
||||
result,
|
||||
false,
|
||||
false,
|
||||
h.Verbose,
|
||||
h.HTTPDebugging,
|
||||
h.HTTPRecording)
|
||||
}
|
||||
|
||||
// SendAuthenticatedHTTPPostRequest sends authenticated requests to the HUOBI API
|
||||
@@ -917,7 +926,16 @@ func (h *HUOBIHADAX) SendAuthenticatedHTTPPostRequest(method, endpoint, postBody
|
||||
signatureParams.Set("Signature", common.Base64Encode(hmac))
|
||||
urlPath := common.EncodeURLValues(fmt.Sprintf("%s%s", h.APIUrl, endpoint),
|
||||
signatureParams)
|
||||
return h.SendPayload(method, urlPath, headers, bytes.NewBufferString(postBodyValues), result, true, false, h.Verbose, h.HTTPDebugging)
|
||||
return h.SendPayload(method,
|
||||
urlPath,
|
||||
headers,
|
||||
bytes.NewBufferString(postBodyValues),
|
||||
result,
|
||||
true,
|
||||
false,
|
||||
h.Verbose,
|
||||
h.HTTPDebugging,
|
||||
h.HTTPRecording)
|
||||
}
|
||||
|
||||
// SendAuthenticatedHTTPRequest sends authenticated requests to the HUOBI API
|
||||
@@ -943,7 +961,16 @@ func (h *HUOBIHADAX) SendAuthenticatedHTTPRequest(method, endpoint string, value
|
||||
|
||||
urlPath := common.EncodeURLValues(fmt.Sprintf("%s%s", h.APIUrl, endpoint),
|
||||
values)
|
||||
return h.SendPayload(method, urlPath, headers, bytes.NewBufferString(""), result, true, false, h.Verbose, h.HTTPDebugging)
|
||||
return h.SendPayload(method,
|
||||
urlPath,
|
||||
headers,
|
||||
bytes.NewBufferString(""),
|
||||
result,
|
||||
true,
|
||||
false,
|
||||
h.Verbose,
|
||||
h.HTTPDebugging,
|
||||
h.HTTPRecording)
|
||||
}
|
||||
|
||||
// GetFee returns an estimate of fee based on type of transaction
|
||||
|
||||
@@ -345,7 +345,16 @@ func (i *ItBit) WalletTransfer(walletID, sourceWallet, destWallet string, amount
|
||||
|
||||
// SendHTTPRequest sends an unauthenticated HTTP request
|
||||
func (i *ItBit) SendHTTPRequest(path string, result interface{}) error {
|
||||
return i.SendPayload(http.MethodGet, path, nil, nil, result, false, false, i.Verbose, i.HTTPDebugging)
|
||||
return i.SendPayload(http.MethodGet,
|
||||
path,
|
||||
nil,
|
||||
nil,
|
||||
result,
|
||||
false,
|
||||
false,
|
||||
i.Verbose,
|
||||
i.HTTPDebugging,
|
||||
i.HTTPRecording)
|
||||
}
|
||||
|
||||
// SendAuthenticatedHTTPRequest sends an authenticated request to itBit
|
||||
@@ -405,7 +414,16 @@ func (i *ItBit) SendAuthenticatedHTTPRequest(method, path string, params map[str
|
||||
RequestID string `json:"requestId"`
|
||||
}{}
|
||||
|
||||
err = i.SendPayload(method, urlPath, headers, bytes.NewBuffer(PayloadJSON), &intermediary, true, true, i.Verbose, i.HTTPDebugging)
|
||||
err = i.SendPayload(method,
|
||||
urlPath,
|
||||
headers,
|
||||
bytes.NewBuffer(PayloadJSON),
|
||||
&intermediary,
|
||||
true,
|
||||
true,
|
||||
i.Verbose,
|
||||
i.HTTPDebugging,
|
||||
i.HTTPRecording)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -952,7 +952,16 @@ func GetError(apiErrors []string) error {
|
||||
|
||||
// SendHTTPRequest sends an unauthenticated HTTP requests
|
||||
func (k *Kraken) SendHTTPRequest(path string, result interface{}) error {
|
||||
return k.SendPayload(http.MethodGet, path, nil, nil, result, false, false, k.Verbose, k.HTTPDebugging)
|
||||
return k.SendPayload(http.MethodGet,
|
||||
path,
|
||||
nil,
|
||||
nil,
|
||||
result,
|
||||
false,
|
||||
false,
|
||||
k.Verbose,
|
||||
k.HTTPDebugging,
|
||||
k.HTTPRecording)
|
||||
}
|
||||
|
||||
// SendAuthenticatedHTTPRequest sends an authenticated HTTP request
|
||||
@@ -996,7 +1005,8 @@ func (k *Kraken) SendAuthenticatedHTTPRequest(method string, params url.Values,
|
||||
true,
|
||||
true,
|
||||
k.Verbose,
|
||||
k.HTTPDebugging)
|
||||
k.HTTPDebugging,
|
||||
k.HTTPRecording)
|
||||
}
|
||||
|
||||
// GetFee returns an estimate of fee based on type of transaction
|
||||
|
||||
@@ -360,7 +360,16 @@ func (l *LakeBTC) CreateWithdraw(amount float64, accountID string) (Withdraw, er
|
||||
|
||||
// SendHTTPRequest sends an unauthenticated http request
|
||||
func (l *LakeBTC) SendHTTPRequest(path string, result interface{}) error {
|
||||
return l.SendPayload(http.MethodGet, path, nil, nil, result, false, false, l.Verbose, l.HTTPDebugging)
|
||||
return l.SendPayload(http.MethodGet,
|
||||
path,
|
||||
nil,
|
||||
nil,
|
||||
result,
|
||||
false,
|
||||
false,
|
||||
l.Verbose,
|
||||
l.HTTPDebugging,
|
||||
l.HTTPRecording)
|
||||
}
|
||||
|
||||
// SendAuthenticatedHTTPRequest sends an autheticated HTTP request to a LakeBTC
|
||||
@@ -393,7 +402,16 @@ func (l *LakeBTC) SendAuthenticatedHTTPRequest(method, params string, result int
|
||||
headers["Authorization"] = "Basic " + common.Base64Encode([]byte(l.APIKey+":"+common.HexEncodeToString(hmac)))
|
||||
headers["Content-Type"] = "application/json-rpc"
|
||||
|
||||
return l.SendPayload(http.MethodPost, l.APIUrl, headers, strings.NewReader(string(data)), result, true, true, l.Verbose, l.HTTPDebugging)
|
||||
return l.SendPayload(http.MethodPost,
|
||||
l.APIUrl,
|
||||
headers,
|
||||
strings.NewReader(string(data)),
|
||||
result,
|
||||
true,
|
||||
true,
|
||||
l.Verbose,
|
||||
l.HTTPDebugging,
|
||||
l.HTTPRecording)
|
||||
}
|
||||
|
||||
// GetFee returns an estimate of fee based on type of transaction
|
||||
|
||||
@@ -551,7 +551,16 @@ func ErrorCapture(code int64) error {
|
||||
|
||||
// SendHTTPRequest sends an unauthenticated HTTP request
|
||||
func (l *Lbank) SendHTTPRequest(path string, result interface{}) error {
|
||||
return l.SendPayload(http.MethodGet, path, nil, nil, &result, false, false, l.Verbose, l.HTTPDebugging)
|
||||
return l.SendPayload(http.MethodGet,
|
||||
path,
|
||||
nil,
|
||||
nil,
|
||||
&result,
|
||||
false,
|
||||
false,
|
||||
l.Verbose,
|
||||
l.HTTPDebugging,
|
||||
l.HTTPRecording)
|
||||
}
|
||||
|
||||
func (l *Lbank) loadPrivKey() error {
|
||||
@@ -618,5 +627,6 @@ func (l *Lbank) SendAuthHTTPRequest(method, endpoint string, vals url.Values, re
|
||||
true,
|
||||
false,
|
||||
l.Verbose,
|
||||
l.HTTPDebugging)
|
||||
l.HTTPDebugging,
|
||||
l.HTTPRecording)
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package localbitcoins
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/http"
|
||||
@@ -204,16 +205,36 @@ func (l *LocalBitcoins) GetAccountInformation(username string, self bool) (Accou
|
||||
// adID - [optional] string if omitted returns all ads
|
||||
func (l *LocalBitcoins) Getads(args ...string) (AdData, error) {
|
||||
var resp struct {
|
||||
Data AdData `json:"data"`
|
||||
Data AdData `json:"data"`
|
||||
Error struct {
|
||||
Message string `json:"message"`
|
||||
Code int `json:"error_code"`
|
||||
} `json:"error"`
|
||||
}
|
||||
|
||||
var err error
|
||||
if len(args) == 0 {
|
||||
return resp.Data, l.SendAuthenticatedHTTPRequest(http.MethodGet, localbitcoinsAPIAds, nil, &resp)
|
||||
err = l.SendAuthenticatedHTTPRequest(http.MethodGet,
|
||||
localbitcoinsAPIAds,
|
||||
nil,
|
||||
&resp)
|
||||
} else {
|
||||
params := url.Values{"ads": {strings.Join(args, ",")}}
|
||||
|
||||
err = l.SendAuthenticatedHTTPRequest(http.MethodGet,
|
||||
localbitcoinsAPIAdGet,
|
||||
params,
|
||||
&resp)
|
||||
}
|
||||
|
||||
params := url.Values{"ads": {strings.Join(args, ",")}}
|
||||
if err != nil {
|
||||
return resp.Data, err
|
||||
}
|
||||
|
||||
return resp.Data, l.SendAuthenticatedHTTPRequest(http.MethodGet, localbitcoinsAPIAdGet, params, &resp)
|
||||
if resp.Error.Message != "" {
|
||||
return resp.Data, errors.New(resp.Error.Message)
|
||||
}
|
||||
return resp.Data, nil
|
||||
}
|
||||
|
||||
// EditAd updates set advertisements
|
||||
@@ -222,12 +243,27 @@ func (l *LocalBitcoins) Getads(args ...string) (AdData, error) {
|
||||
// adID - string for the ad you already created
|
||||
// TODO
|
||||
func (l *LocalBitcoins) EditAd(_ *AdEdit, adID string) error {
|
||||
type response struct {
|
||||
Data AdData `json:"data"`
|
||||
resp := struct {
|
||||
Data AdData `json:"data"`
|
||||
Error struct {
|
||||
Message string `json:"message"`
|
||||
Code int `json:"error_code"`
|
||||
}
|
||||
}{}
|
||||
|
||||
err := l.SendAuthenticatedHTTPRequest(http.MethodPost,
|
||||
localbitcoinsAPIAdEdit+adID+"/",
|
||||
nil,
|
||||
&resp)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
resp := response{}
|
||||
return l.SendAuthenticatedHTTPRequest(http.MethodPost, localbitcoinsAPIAdEdit+adID+"/", nil, &resp)
|
||||
if resp.Error.Message != "" {
|
||||
return errors.New(resp.Error.Message)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// CreateAd creates a new advertisement
|
||||
@@ -254,7 +290,26 @@ func (l *LocalBitcoins) UpdatePriceEquation(adID string) error {
|
||||
// adID - string of specific ad identification
|
||||
// TODO
|
||||
func (l *LocalBitcoins) DeleteAd(adID string) error {
|
||||
return l.SendAuthenticatedHTTPRequest(http.MethodPost, localbitcoinsAPIDeleteAd+adID, nil, nil)
|
||||
resp := struct {
|
||||
Error struct {
|
||||
Message string `json:"message"`
|
||||
Code int `json:"error_code"`
|
||||
} `json:"error"`
|
||||
}{}
|
||||
|
||||
err := l.SendAuthenticatedHTTPRequest(http.MethodPost,
|
||||
localbitcoinsAPIDeleteAd+adID+"/",
|
||||
nil,
|
||||
&resp)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if resp.Error.Message != "" {
|
||||
return errors.New(resp.Error.Message)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// ReleaseFunds releases Bitcoin trades specified by ID {contact_id}. If the
|
||||
@@ -579,7 +634,7 @@ func (l *LocalBitcoins) GetWalletBalance() (WalletBalanceInfo, error) {
|
||||
// On success, the response returns a message indicating success. It is highly
|
||||
// recommended to minimize the lifetime of access tokens with the money
|
||||
// permission. Use Logout() to make the current token expire instantly.
|
||||
func (l *LocalBitcoins) WalletSend(address string, amount float64, pin int64) (bool, error) {
|
||||
func (l *LocalBitcoins) WalletSend(address string, amount float64, pin int64) error {
|
||||
values := url.Values{}
|
||||
values.Set("address", address)
|
||||
values.Set("amount", strconv.FormatFloat(amount, 'f', -1, 64))
|
||||
@@ -590,23 +645,34 @@ func (l *LocalBitcoins) WalletSend(address string, amount float64, pin int64) (b
|
||||
path = localbitcoinsAPIWalletSendPin
|
||||
}
|
||||
|
||||
type response struct {
|
||||
resp := struct {
|
||||
Error struct {
|
||||
Message string `json:"message"`
|
||||
Errors map[string]string `json:"errors"`
|
||||
Code int `json:"error_code"`
|
||||
} `json:"error"`
|
||||
Data struct {
|
||||
Message string `json:"message"`
|
||||
} `json:"data"`
|
||||
}
|
||||
}{}
|
||||
|
||||
resp := response{}
|
||||
err := l.SendAuthenticatedHTTPRequest(http.MethodPost, path, values, &resp)
|
||||
if err != nil {
|
||||
return false, err
|
||||
return err
|
||||
}
|
||||
|
||||
if resp.Data.Message != "Money is being sent" {
|
||||
return false, errors.New("unable to send Bitcoins")
|
||||
if len(resp.Error.Errors) != 0 {
|
||||
var details string
|
||||
for _, val := range resp.Error.Errors {
|
||||
details += val
|
||||
}
|
||||
return errors.New(details)
|
||||
}
|
||||
return errors.New(resp.Data.Message)
|
||||
}
|
||||
|
||||
return true, nil
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetWalletAddress returns an unused receiving address from the token owner's
|
||||
@@ -728,7 +794,16 @@ func (l *LocalBitcoins) GetOrderbook(currency string) (Orderbook, error) {
|
||||
|
||||
// SendHTTPRequest sends an unauthenticated HTTP request
|
||||
func (l *LocalBitcoins) SendHTTPRequest(path string, result interface{}) error {
|
||||
return l.SendPayload(http.MethodGet, path, nil, nil, result, false, false, l.Verbose, l.HTTPDebugging)
|
||||
return l.SendPayload(http.MethodGet,
|
||||
path,
|
||||
nil,
|
||||
nil,
|
||||
result,
|
||||
false,
|
||||
false,
|
||||
l.Verbose,
|
||||
l.HTTPDebugging,
|
||||
l.HTTPRecording)
|
||||
}
|
||||
|
||||
// SendAuthenticatedHTTPRequest sends an authenticated HTTP request to
|
||||
@@ -758,7 +833,16 @@ func (l *LocalBitcoins) SendAuthenticatedHTTPRequest(method, path string, params
|
||||
path += "?" + encoded
|
||||
}
|
||||
|
||||
return l.SendPayload(method, l.APIUrl+path, headers, strings.NewReader(encoded), result, true, true, l.Verbose, l.HTTPDebugging)
|
||||
return l.SendPayload(method,
|
||||
l.APIUrl+path,
|
||||
headers,
|
||||
bytes.NewBufferString(encoded),
|
||||
result,
|
||||
true,
|
||||
true,
|
||||
l.Verbose,
|
||||
l.HTTPDebugging,
|
||||
l.HTTPRecording)
|
||||
}
|
||||
|
||||
// GetFee returns an estimate of fee based on type of transaction
|
||||
|
||||
32
exchanges/localbitcoins/localbitcoins_live_test.go
Normal file
32
exchanges/localbitcoins/localbitcoins_live_test.go
Normal file
@@ -0,0 +1,32 @@
|
||||
//+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 localbitcoins
|
||||
|
||||
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")
|
||||
localbitcoinsConfig, err := cfg.GetExchangeConfig("LocalBitcoins")
|
||||
if err != nil {
|
||||
log.Fatal("Test Failed - LocalBitcoins Setup() init error", err)
|
||||
}
|
||||
localbitcoinsConfig.AuthenticatedAPISupport = true
|
||||
localbitcoinsConfig.APIKey = apiKey
|
||||
localbitcoinsConfig.APISecret = apiSecret
|
||||
l.SetDefaults()
|
||||
l.Setup(&localbitcoinsConfig)
|
||||
log.Printf(sharedtestvalues.LiveTesting, l.GetName(), l.APIUrl)
|
||||
os.Exit(m.Run())
|
||||
}
|
||||
44
exchanges/localbitcoins/localbitcoins_mock_test.go
Normal file
44
exchanges/localbitcoins/localbitcoins_mock_test.go
Normal file
@@ -0,0 +1,44 @@
|
||||
//+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 localbitcoins
|
||||
|
||||
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/localbitcoins/localbitcoins.json"
|
||||
|
||||
var mockTests = true
|
||||
|
||||
func TestMain(m *testing.M) {
|
||||
cfg := config.GetConfig()
|
||||
cfg.LoadConfig("../../testdata/configtest.json")
|
||||
localbitcoinsConfig, err := cfg.GetExchangeConfig("LocalBitcoins")
|
||||
if err != nil {
|
||||
log.Fatal("Test Failed - Localbitcoins Setup() init error", err)
|
||||
}
|
||||
localbitcoinsConfig.AuthenticatedAPISupport = true
|
||||
localbitcoinsConfig.APIKey = apiKey
|
||||
localbitcoinsConfig.APISecret = apiSecret
|
||||
l.SetDefaults()
|
||||
l.Setup(&localbitcoinsConfig)
|
||||
|
||||
serverDetails, newClient, err := mock.NewVCRServer(mockfile)
|
||||
if err != nil {
|
||||
log.Fatalf("Test Failed - Mock server error %s", err)
|
||||
}
|
||||
|
||||
l.HTTPClient = newClient
|
||||
l.APIUrl = serverDetails
|
||||
|
||||
log.Printf(sharedtestvalues.MockTesting, l.GetName(), l.APIUrl)
|
||||
os.Exit(m.Run())
|
||||
}
|
||||
@@ -4,13 +4,10 @@ import (
|
||||
"testing"
|
||||
|
||||
"github.com/thrasher-corp/gocryptotrader/common"
|
||||
"github.com/thrasher-corp/gocryptotrader/config"
|
||||
"github.com/thrasher-corp/gocryptotrader/currency"
|
||||
exchange "github.com/thrasher-corp/gocryptotrader/exchanges"
|
||||
)
|
||||
|
||||
var l LocalBitcoins
|
||||
|
||||
// Please supply your own APIKEYS here for due diligence testing
|
||||
|
||||
const (
|
||||
@@ -19,26 +16,11 @@ const (
|
||||
canManipulateRealOrders = false
|
||||
)
|
||||
|
||||
func TestSetDefaults(t *testing.T) {
|
||||
l.SetDefaults()
|
||||
}
|
||||
|
||||
func TestSetup(t *testing.T) {
|
||||
cfg := config.GetConfig()
|
||||
cfg.LoadConfig("../../testdata/configtest.json")
|
||||
localbitcoinsConfig, err := cfg.GetExchangeConfig("LocalBitcoins")
|
||||
if err != nil {
|
||||
t.Error("Test Failed - LakeBTC Setup() init error")
|
||||
}
|
||||
localbitcoinsConfig.AuthenticatedAPISupport = true
|
||||
localbitcoinsConfig.APIKey = apiKey
|
||||
localbitcoinsConfig.APISecret = apiSecret
|
||||
|
||||
l.Setup(&localbitcoinsConfig)
|
||||
}
|
||||
var l LocalBitcoins
|
||||
|
||||
func TestGetTicker(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
_, err := l.GetTicker()
|
||||
if err != nil {
|
||||
t.Errorf("Test failed - GetTicker() returned: %s", err)
|
||||
@@ -47,6 +29,7 @@ func TestGetTicker(t *testing.T) {
|
||||
|
||||
func TestGetTradableCurrencies(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
_, err := l.GetTradableCurrencies()
|
||||
if err != nil {
|
||||
t.Errorf("Test failed - GetTradableCurrencies() returned: %s", err)
|
||||
@@ -55,43 +38,44 @@ func TestGetTradableCurrencies(t *testing.T) {
|
||||
|
||||
func TestGetAccountInfo(t *testing.T) {
|
||||
t.Parallel()
|
||||
if l.APIKey == "" || l.APISecret == "" {
|
||||
t.Skip()
|
||||
}
|
||||
|
||||
_, err := l.GetAccountInformation("", true)
|
||||
if err == nil {
|
||||
t.Error("Test Failed - GetAccountInformation() error", err)
|
||||
}
|
||||
_, err = l.GetAccountInformation("bitcoinbaron", false)
|
||||
if err != nil {
|
||||
t.Error("Test Failed - GetAccountInformation() error", err)
|
||||
switch {
|
||||
case areTestAPIKeysSet() && err != nil && !mockTests:
|
||||
t.Errorf("Could not get AccountInformation: %s", err)
|
||||
case !areTestAPIKeysSet() && err == nil && !mockTests:
|
||||
t.Error("Expecting an error when no keys are set")
|
||||
case mockTests && err != nil:
|
||||
t.Errorf("Could not get AccountInformation: %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetads(t *testing.T) {
|
||||
t.Parallel()
|
||||
if l.APIKey == "" || l.APISecret == "" {
|
||||
t.Skip()
|
||||
}
|
||||
|
||||
_, err := l.Getads("")
|
||||
if err == nil {
|
||||
t.Error("Test Failed - Getads() - Full list, error", err)
|
||||
}
|
||||
_, err = l.Getads("1337")
|
||||
if err == nil {
|
||||
t.Error("Test Failed - Getads() error", err)
|
||||
switch {
|
||||
case areTestAPIKeysSet() && err != nil && !mockTests:
|
||||
t.Errorf("Could not get ads: %s", err)
|
||||
case !areTestAPIKeysSet() && err == nil && !mockTests:
|
||||
t.Error("Expecting an error when no keys are set")
|
||||
case mockTests && err == nil:
|
||||
t.Error("Expecting error until QA pass")
|
||||
}
|
||||
}
|
||||
|
||||
func TestEditAd(t *testing.T) {
|
||||
t.Parallel()
|
||||
if l.APIKey == "" || l.APISecret == "" {
|
||||
t.Skip()
|
||||
}
|
||||
edit := AdEdit{}
|
||||
|
||||
var edit AdEdit
|
||||
err := l.EditAd(&edit, "1337")
|
||||
if err == nil {
|
||||
t.Error("Test Failed - EditAd() error", err)
|
||||
switch {
|
||||
case areTestAPIKeysSet() && err != nil && !mockTests:
|
||||
t.Errorf("Could not edit order: %s", err)
|
||||
case !areTestAPIKeysSet() && err == nil && !mockTests:
|
||||
t.Error("Expecting an error when no keys are set")
|
||||
case mockTests && err == nil:
|
||||
t.Error("Expecting error until QA pass")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -110,6 +94,7 @@ func setFeeBuilder() *exchange.FeeBuilder {
|
||||
|
||||
// TestGetFeeByTypeOfflineTradeFee logic test
|
||||
func TestGetFeeByTypeOfflineTradeFee(t *testing.T) {
|
||||
t.Parallel()
|
||||
var feeBuilder = setFeeBuilder()
|
||||
l.GetFeeByType(feeBuilder)
|
||||
if apiKey == "" || apiSecret == "" {
|
||||
@@ -124,7 +109,7 @@ func TestGetFeeByTypeOfflineTradeFee(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestGetFee(t *testing.T) {
|
||||
l.SetDefaults()
|
||||
t.Parallel()
|
||||
var feeBuilder = setFeeBuilder()
|
||||
// CryptocurrencyTradeFee Basic
|
||||
if resp, err := l.GetFee(feeBuilder); resp != float64(0) || err != nil {
|
||||
@@ -200,45 +185,53 @@ func TestGetFee(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestFormatWithdrawPermissions(t *testing.T) {
|
||||
l.SetDefaults()
|
||||
expectedResult := exchange.AutoWithdrawCryptoText + " & " + exchange.WithdrawFiatViaWebsiteOnlyText
|
||||
t.Parallel()
|
||||
|
||||
expectedResult := exchange.AutoWithdrawCryptoText +
|
||||
" & " +
|
||||
exchange.WithdrawFiatViaWebsiteOnlyText
|
||||
|
||||
withdrawPermissions := l.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) {
|
||||
l.SetDefaults()
|
||||
TestSetup(t)
|
||||
t.Parallel()
|
||||
|
||||
var getOrdersRequest = exchange.GetOrdersRequest{
|
||||
OrderType: exchange.AnyOrderType,
|
||||
}
|
||||
|
||||
_, err := l.GetActiveOrders(&getOrdersRequest)
|
||||
if areTestAPIKeysSet() && err != nil {
|
||||
t.Errorf("Could not get open orders: %s", err)
|
||||
} else if !areTestAPIKeysSet() && err == nil {
|
||||
switch {
|
||||
case areTestAPIKeysSet() && err != nil && !mockTests:
|
||||
t.Errorf("Could not get active orders: %s", err)
|
||||
case !areTestAPIKeysSet() && err == nil && !mockTests:
|
||||
t.Error("Expecting an error when no keys are set")
|
||||
case mockTests && err != nil:
|
||||
t.Errorf("Could not get active orders: %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetOrderHistory(t *testing.T) {
|
||||
l.SetDefaults()
|
||||
TestSetup(t)
|
||||
t.Parallel()
|
||||
|
||||
var getOrdersRequest = exchange.GetOrdersRequest{
|
||||
OrderType: exchange.AnyOrderType,
|
||||
}
|
||||
|
||||
_, err := l.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)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -253,10 +246,9 @@ func areTestAPIKeysSet() bool {
|
||||
}
|
||||
|
||||
func TestSubmitOrder(t *testing.T) {
|
||||
l.SetDefaults()
|
||||
TestSetup(t)
|
||||
t.Parallel()
|
||||
|
||||
if areTestAPIKeysSet() && !canManipulateRealOrders {
|
||||
if areTestAPIKeysSet() && !canManipulateRealOrders && !mockTests {
|
||||
t.Skip("API keys set, canManipulateRealOrders false, skipping test")
|
||||
}
|
||||
|
||||
@@ -266,62 +258,62 @@ func TestSubmitOrder(t *testing.T) {
|
||||
Quote: currency.EUR,
|
||||
}
|
||||
response, err := l.SubmitOrder(p, exchange.BuyOrderSide, exchange.MarketOrderType, 1, 10, "hi")
|
||||
if areTestAPIKeysSet() && (err != nil || !response.IsOrderPlaced) {
|
||||
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")
|
||||
}
|
||||
}
|
||||
|
||||
func TestCancelExchangeOrder(t *testing.T) {
|
||||
l.SetDefaults()
|
||||
TestSetup(t)
|
||||
t.Parallel()
|
||||
|
||||
if areTestAPIKeysSet() && !canManipulateRealOrders {
|
||||
if areTestAPIKeysSet() && !canManipulateRealOrders && !mockTests {
|
||||
t.Skip("API keys set, canManipulateRealOrders false, skipping test")
|
||||
}
|
||||
|
||||
currencyPair := currency.NewPair(currency.LTC, currency.BTC)
|
||||
|
||||
var orderCancellation = &exchange.OrderCancellation{
|
||||
OrderID: "1",
|
||||
WalletAddress: "1F5zVDgNjorJ51oGebSvNCrSAHpwGkUdDB",
|
||||
AccountID: "1",
|
||||
CurrencyPair: currencyPair,
|
||||
CurrencyPair: currency.NewPair(currency.LTC, currency.BTC),
|
||||
}
|
||||
|
||||
err := l.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")
|
||||
}
|
||||
}
|
||||
|
||||
func TestCancelAllExchangeOrders(t *testing.T) {
|
||||
l.SetDefaults()
|
||||
TestSetup(t)
|
||||
t.Parallel()
|
||||
|
||||
if areTestAPIKeysSet() && !canManipulateRealOrders {
|
||||
if areTestAPIKeysSet() && !canManipulateRealOrders && !mockTests {
|
||||
t.Skip("API keys set, canManipulateRealOrders false, skipping test")
|
||||
}
|
||||
|
||||
currencyPair := currency.NewPair(currency.LTC, currency.BTC)
|
||||
|
||||
var orderCancellation = &exchange.OrderCancellation{
|
||||
OrderID: "1",
|
||||
WalletAddress: "1F5zVDgNjorJ51oGebSvNCrSAHpwGkUdDB",
|
||||
AccountID: "1",
|
||||
CurrencyPair: currencyPair,
|
||||
CurrencyPair: currency.NewPair(currency.LTC, currency.BTC),
|
||||
}
|
||||
|
||||
resp, err := l.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)
|
||||
}
|
||||
|
||||
@@ -331,15 +323,17 @@ func TestCancelAllExchangeOrders(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestModifyOrder(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
_, err := l.ModifyOrder(&exchange.ModifyOrder{})
|
||||
if err == nil {
|
||||
t.Error("Test failed - ModifyOrder() error")
|
||||
if err != common.ErrFunctionNotSupported {
|
||||
t.Error("Test failed - ModifyOrder() error", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestWithdraw(t *testing.T) {
|
||||
l.SetDefaults()
|
||||
TestSetup(t)
|
||||
t.Parallel()
|
||||
|
||||
var withdrawCryptoRequest = exchange.WithdrawRequest{
|
||||
Amount: 100,
|
||||
Currency: currency.LTC,
|
||||
@@ -347,61 +341,55 @@ func TestWithdraw(t *testing.T) {
|
||||
Description: "WITHDRAW IT ALL",
|
||||
}
|
||||
|
||||
if areTestAPIKeysSet() && !canManipulateRealOrders {
|
||||
if areTestAPIKeysSet() && !canManipulateRealOrders && !mockTests {
|
||||
t.Skip("API keys set, canManipulateRealOrders false, skipping test")
|
||||
}
|
||||
|
||||
_, err := l.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")
|
||||
}
|
||||
}
|
||||
|
||||
func TestWithdrawFiat(t *testing.T) {
|
||||
l.SetDefaults()
|
||||
TestSetup(t)
|
||||
|
||||
if areTestAPIKeysSet() && !canManipulateRealOrders {
|
||||
t.Skip("API keys set, canManipulateRealOrders false, skipping test")
|
||||
}
|
||||
t.Parallel()
|
||||
|
||||
var withdrawFiatRequest = exchange.WithdrawRequest{}
|
||||
|
||||
_, err := l.WithdrawFiatFunds(&withdrawFiatRequest)
|
||||
if err != common.ErrFunctionNotSupported {
|
||||
t.Errorf("Expected '%v', received: '%v'", common.ErrFunctionNotSupported, err)
|
||||
t.Errorf("Expected '%v', received: '%v'",
|
||||
common.ErrFunctionNotSupported,
|
||||
err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestWithdrawInternationalBank(t *testing.T) {
|
||||
l.SetDefaults()
|
||||
TestSetup(t)
|
||||
|
||||
if areTestAPIKeysSet() && !canManipulateRealOrders {
|
||||
t.Skip("API keys set, canManipulateRealOrders false, skipping test")
|
||||
}
|
||||
t.Parallel()
|
||||
|
||||
var withdrawFiatRequest = exchange.WithdrawRequest{}
|
||||
|
||||
_, err := l.WithdrawFiatFundsToInternationalBank(&withdrawFiatRequest)
|
||||
if err != common.ErrFunctionNotSupported {
|
||||
t.Errorf("Expected '%v', received: '%v'", common.ErrFunctionNotSupported, err)
|
||||
t.Errorf("Expected '%v', received: '%v'",
|
||||
common.ErrFunctionNotSupported,
|
||||
err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetDepositAddress(t *testing.T) {
|
||||
if apiKey != "" || apiSecret != "" {
|
||||
_, err := l.GetDepositAddress(currency.BTC, "")
|
||||
if err != nil {
|
||||
t.Error("Test Failed - GetDepositAddress() error", err)
|
||||
}
|
||||
} else {
|
||||
_, err := l.GetDepositAddress(currency.BTC, "")
|
||||
if err == nil {
|
||||
t.Error("Test Failed - GetDepositAddress() error cannot be nil")
|
||||
}
|
||||
t.Parallel()
|
||||
|
||||
_, err := l.GetDepositAddress(currency.BTC, "")
|
||||
switch {
|
||||
case areTestAPIKeysSet() && err != nil && !mockTests:
|
||||
t.Error("Test Failed - GetDepositAddress() error", err)
|
||||
case !areTestAPIKeysSet() && err == nil && !mockTests:
|
||||
t.Error("Test Failed - GetDepositAddress() expecting an error when no APIKeys are set")
|
||||
case mockTests && err != nil:
|
||||
t.Error("Test Failed - GetDepositAddress() error", err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -280,8 +280,10 @@ func (l *LocalBitcoins) GetDepositAddress(cryptocurrency currency.Code, _ string
|
||||
// WithdrawCryptocurrencyFunds returns a withdrawal ID when a withdrawal is
|
||||
// submitted
|
||||
func (l *LocalBitcoins) WithdrawCryptocurrencyFunds(withdrawRequest *exchange.WithdrawRequest) (string, error) {
|
||||
_, err := l.WalletSend(withdrawRequest.Address, withdrawRequest.Amount, withdrawRequest.PIN)
|
||||
return "", err
|
||||
return "",
|
||||
l.WalletSend(withdrawRequest.Address,
|
||||
withdrawRequest.Amount,
|
||||
withdrawRequest.PIN)
|
||||
}
|
||||
|
||||
// WithdrawFiatFunds returns a withdrawal ID when a
|
||||
|
||||
174
exchanges/mock/README.md
Normal file
174
exchanges/mock/README.md
Normal file
@@ -0,0 +1,174 @@
|
||||
# GoCryptoTrader package Mock
|
||||
|
||||
<img src="https://github.com/thrasher-corp/gocryptotrader/blob/master/web/src/assets/page-logo.png?raw=true" width="350px" height="350px" hspace="70">
|
||||
|
||||
|
||||
[](https://travis-ci.org/thrasher-corp/gocryptotrader)
|
||||
[](https://github.com/thrasher-corp/gocryptotrader/blob/master/LICENSE)
|
||||
[](https://godoc.org/github.com/thrasher-corp/gocryptotrader/exchanges/mock)
|
||||
[](http://codecov.io/github/thrasher-corp/gocryptotrader?branch=master)
|
||||
[](https://goreportcard.com/report/github.com/thrasher-corp/gocryptotrader)
|
||||
|
||||
|
||||
This Mock package is part of the GoCryptoTrader codebase.
|
||||
|
||||
## This is still in active development
|
||||
|
||||
You can track ideas, planned features and what's in progresss on this Trello board: [https://trello.com/b/ZAhMhpOy/gocryptotrader](https://trello.com/b/ZAhMhpOy/gocryptotrader).
|
||||
|
||||
Join our slack to discuss all things related to GoCryptoTrader! [GoCryptoTrader Slack](https://join.slack.com/t/gocryptotrader/shared_invite/enQtNTQ5NDAxMjA2Mjc5LTQyYjIxNGVhMWU5MDZlOGYzMmE0NTJmM2MzYWY5NGMzMmM4MzUwNTBjZTEzNjIwODM5NDcxODQwZDljMGQyNGY)
|
||||
|
||||
## Mock Testing Suite
|
||||
|
||||
### Current Features
|
||||
|
||||
+ REST recording service
|
||||
+ REST mock response server
|
||||
|
||||
### How to enable
|
||||
|
||||
+ Mock testing is enabled by default in some exchanges; to disable and run live endpoint testing parse -tags=mock_test_off as a go test param.
|
||||
|
||||
+ To record a live endpoint create two files for an exchange.
|
||||
|
||||
### file one - your_current_exchange_name_live_test.go
|
||||
|
||||
```go
|
||||
//+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 your_current_exchange_name
|
||||
|
||||
import (
|
||||
"os"
|
||||
"testing"
|
||||
"log"
|
||||
|
||||
"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")
|
||||
your_current_exchange_nameConfig, err := cfg.GetExchangeConfig("your_current_exchange_name")
|
||||
if err != nil {
|
||||
log.Fatal("Test Failed - your_current_exchange_name Setup() init error", err)
|
||||
}
|
||||
your_current_exchange_nameConfig.AuthenticatedAPISupport = true
|
||||
your_current_exchange_nameConfig.APIKey = apiKey
|
||||
your_current_exchange_nameConfig.APISecret = apiSecret
|
||||
l.SetDefaults()
|
||||
l.Setup(&your_current_exchange_nameConfig)
|
||||
log.Printf(sharedtestvalues.LiveTesting, l.GetName(), l.APIUrl)
|
||||
os.Exit(m.Run())
|
||||
}
|
||||
```
|
||||
|
||||
### file two - your_current_exchange_name_mock_test.go
|
||||
|
||||
```go
|
||||
//+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 your_current_exchange_name
|
||||
|
||||
import (
|
||||
"os"
|
||||
"testing"
|
||||
"log"
|
||||
|
||||
"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/your_current_exchange_name/your_current_exchange_name.json"
|
||||
|
||||
var mockTests = true
|
||||
|
||||
func TestMain(m *testing.M) {
|
||||
cfg := config.GetConfig()
|
||||
cfg.LoadConfig("../../testdata/configtest.json")
|
||||
your_current_exchange_nameConfig, err := cfg.GetExchangeConfig("your_current_exchange_name")
|
||||
if err != nil {
|
||||
log.Fatal("Test Failed - your_current_exchange_name Setup() init error", err)
|
||||
}
|
||||
your_current_exchange_nameConfig.AuthenticatedAPISupport = true
|
||||
your_current_exchange_nameConfig.APIKey = apiKey
|
||||
your_current_exchange_nameConfig.APISecret = apiSecret
|
||||
l.SetDefaults()
|
||||
l.Setup(&your_current_exchange_nameConfig)
|
||||
|
||||
serverDetails, newClient, err := mock.NewVCRServer(mockfile)
|
||||
if err != nil {
|
||||
log.Fatalf("Test Failed - Mock server error %s", err)
|
||||
}
|
||||
|
||||
g.HTTPClient = newClient
|
||||
g.APIUrl = serverDetails
|
||||
|
||||
log.Printf(sharedtestvalues.MockTesting, l.GetName(), l.APIUrl)
|
||||
os.Exit(m.Run())
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
+ Once those files are completed go through each invidual test function and add
|
||||
|
||||
```go
|
||||
var s SomeExchange
|
||||
|
||||
func TestDummyTest(t *testing.T) {
|
||||
s.APIURL = exchangeDefaultURL // This will overwrite the current mock url at localhost
|
||||
s.Verbose = true // This will show you some fancy debug output
|
||||
s.HTTPRecording = true // This will record the request and response payloads
|
||||
|
||||
err := s.SomeExchangeEndpointFunction()
|
||||
// check error
|
||||
}
|
||||
```
|
||||
|
||||
+ After this is completed it should populate a new mocktest.json file for you with the relavent payloads in testdata
|
||||
+ To check if the recording was successful, comment out recording and apiurl changes, then re-run test.
|
||||
|
||||
```go
|
||||
var s SomeExchange
|
||||
|
||||
func TestDummyTest(t *testing.T) {
|
||||
// s.APIURL = exchangeDefaultURL // This will overwrite the current mock url at localhost
|
||||
s.Verbose = true // This will show you some fancy debug output
|
||||
// s.HTTPRecording = true // This will record the request and response payloads
|
||||
|
||||
err := s.SomeExchangeEndpointFunction()
|
||||
// check error
|
||||
}
|
||||
```
|
||||
|
||||
+ The payload should be the same.
|
||||
|
||||
### Please click GoDocs chevron above to view current GoDoc information for this package
|
||||
|
||||
## Contribution
|
||||
|
||||
Please feel free to submit any pull requests or suggest any desired features to be added.
|
||||
|
||||
When submitting a PR, please abide by our coding guidelines:
|
||||
|
||||
+ Code must adhere to the official Go [formatting](https://golang.org/doc/effective_go.html#formatting) guidelines (i.e. uses [gofmt](https://golang.org/cmd/gofmt/)).
|
||||
+ Code must be documented adhering to the official Go [commentary](https://golang.org/doc/effective_go.html#commentary) guidelines.
|
||||
+ Code must adhere to our [coding style](https://github.com/thrasher-corp/gocryptotrader/blob/master/doc/coding_style.md).
|
||||
+ Pull requests need to be based on and opened against the `master` branch.
|
||||
|
||||
## Donations
|
||||
|
||||
<img src="https://github.com/thrasher-corp/gocryptotrader/blob/master/web/src/assets/donate.png?raw=true" hspace="70">
|
||||
|
||||
If this framework helped you in any way, or you would like to support the developers working on it, please donate Bitcoin to:
|
||||
|
||||
***1F5zVDgNjorJ51oGebSvNCrSAHpwGkUdDB***
|
||||
|
||||
71
exchanges/mock/common.go
Normal file
71
exchanges/mock/common.go
Normal file
@@ -0,0 +1,71 @@
|
||||
package mock
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"log"
|
||||
"net/url"
|
||||
"reflect"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// MatchURLVals matches url.Value query strings
|
||||
func MatchURLVals(v1, v2 url.Values) bool {
|
||||
if len(v1) != len(v2) {
|
||||
return false
|
||||
}
|
||||
|
||||
if len(v1) == 0 && len(v2) == 0 {
|
||||
return true
|
||||
}
|
||||
|
||||
for key, val := range v1 {
|
||||
if key == "nonce" || key == "signature" || key == "timestamp" || key == "tonce" || key == "key" { // delta values
|
||||
if _, ok := v2[key]; !ok {
|
||||
return false
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
if val2, ok := v2[key]; ok {
|
||||
if strings.Join(val2, "") == strings.Join(val, "") {
|
||||
continue
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// DeriveURLValsFromJSONMap gets url vals from a map[string]string encoded JSON body
|
||||
func DeriveURLValsFromJSONMap(payload []byte) (url.Values, error) {
|
||||
var vals = url.Values{}
|
||||
if string(payload) == "" {
|
||||
return vals, nil
|
||||
}
|
||||
intermediary := make(map[string]interface{})
|
||||
err := json.Unmarshal(payload, &intermediary)
|
||||
if err != nil {
|
||||
return vals, err
|
||||
}
|
||||
|
||||
for k, v := range intermediary {
|
||||
switch val := v.(type) {
|
||||
case string:
|
||||
vals.Add(k, val)
|
||||
case bool:
|
||||
vals.Add(k, strconv.FormatBool(val))
|
||||
case float64:
|
||||
vals.Add(k, strconv.FormatFloat(val, 'f', -1, 64))
|
||||
case map[string]interface{}, []interface{}, nil:
|
||||
vals.Add(k, fmt.Sprintf("%v", val))
|
||||
default:
|
||||
log.Println(reflect.TypeOf(val))
|
||||
return vals, errors.New("unhandled conversion type, please add as needed")
|
||||
}
|
||||
}
|
||||
|
||||
return vals, nil
|
||||
}
|
||||
140
exchanges/mock/common_test.go
Normal file
140
exchanges/mock/common_test.go
Normal file
@@ -0,0 +1,140 @@
|
||||
package mock
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"net/url"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestMatchURLVals(t *testing.T) {
|
||||
testVal, testVal2, testVal3, emptyVal := url.Values{}, url.Values{}, url.Values{}, url.Values{}
|
||||
testVal.Add("test", "test")
|
||||
testVal2.Add("test2", "test2")
|
||||
testVal3.Add("test", "diferentValString")
|
||||
|
||||
nonceVal1, nonceVal2 := url.Values{}, url.Values{}
|
||||
nonceVal1.Add("nonce", "012349723587")
|
||||
nonceVal2.Add("nonce", "9327373874")
|
||||
|
||||
var expected = false
|
||||
received := MatchURLVals(testVal, emptyVal)
|
||||
if received != expected {
|
||||
t.Errorf("Test Failed - MatchURLVals error expected %v received %v",
|
||||
expected,
|
||||
received)
|
||||
}
|
||||
|
||||
received = MatchURLVals(emptyVal, testVal)
|
||||
if received != expected {
|
||||
t.Errorf("Test Failed - MatchURLVals error expected %v received %v",
|
||||
expected,
|
||||
received)
|
||||
}
|
||||
|
||||
received = MatchURLVals(testVal, testVal2)
|
||||
if received != expected {
|
||||
t.Errorf("Test Failed - MatchURLVals error expected %v received %v",
|
||||
expected,
|
||||
received)
|
||||
}
|
||||
|
||||
received = MatchURLVals(testVal2, testVal)
|
||||
if received != expected {
|
||||
t.Errorf("Test Failed - MatchURLVals error expected %v received %v",
|
||||
expected,
|
||||
received)
|
||||
}
|
||||
|
||||
received = MatchURLVals(testVal, testVal3)
|
||||
if received != expected {
|
||||
t.Errorf("Test Failed - MatchURLVals error expected %v received %v",
|
||||
expected,
|
||||
received)
|
||||
}
|
||||
|
||||
received = MatchURLVals(nonceVal1, testVal2)
|
||||
if received != expected {
|
||||
t.Errorf("Test Failed - MatchURLVals error expected %v received %v",
|
||||
expected,
|
||||
received)
|
||||
}
|
||||
|
||||
expected = true
|
||||
received = MatchURLVals(emptyVal, emptyVal)
|
||||
if received != expected {
|
||||
t.Errorf("Test Failed - MatchURLVals error expected %v received %v",
|
||||
expected,
|
||||
received)
|
||||
}
|
||||
|
||||
received = MatchURLVals(testVal, testVal)
|
||||
if received != expected {
|
||||
t.Errorf("Test Failed - MatchURLVals error expected %v received %v",
|
||||
expected,
|
||||
received)
|
||||
}
|
||||
|
||||
received = MatchURLVals(nonceVal1, nonceVal2)
|
||||
if received != expected {
|
||||
t.Errorf("Test Failed - MatchURLVals error expected %v received %v",
|
||||
expected,
|
||||
received)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDeriveURLValsFromJSON(t *testing.T) {
|
||||
test1 := struct {
|
||||
Things []string `json:"things"`
|
||||
Data struct {
|
||||
Numbers []int `json:"numbers"`
|
||||
Number float64 `json:"number"`
|
||||
SomeString string `json:"somestring"`
|
||||
} `json:"data"`
|
||||
}{
|
||||
Things: []string{"hello", "world"},
|
||||
Data: struct {
|
||||
Numbers []int `json:"numbers"`
|
||||
Number float64 `json:"number"`
|
||||
SomeString string `json:"somestring"`
|
||||
}{
|
||||
Numbers: []int{1, 3, 3, 7},
|
||||
Number: 3.14,
|
||||
SomeString: "hello, peoples",
|
||||
},
|
||||
}
|
||||
|
||||
payload, err := json.Marshal(test1)
|
||||
if err != nil {
|
||||
t.Error("Test Failed - marshal error", err)
|
||||
}
|
||||
|
||||
_, err = DeriveURLValsFromJSONMap(payload)
|
||||
if err != nil {
|
||||
t.Error("Test Failed - DeriveURLValsFromJSON error", err)
|
||||
}
|
||||
|
||||
test2 := map[string]string{
|
||||
"val": "1",
|
||||
"val2": "2",
|
||||
"val3": "3",
|
||||
"val4": "4",
|
||||
"val5": "5",
|
||||
"val6": "6",
|
||||
"val7": "7",
|
||||
}
|
||||
|
||||
payload, err = json.Marshal(test2)
|
||||
if err != nil {
|
||||
t.Error("Test Failed - marshal error", err)
|
||||
}
|
||||
|
||||
vals, err := DeriveURLValsFromJSONMap(payload)
|
||||
if err != nil {
|
||||
t.Error("Test Failed - DeriveURLValsFromJSON error", err)
|
||||
}
|
||||
|
||||
if vals["val"][0] != "1" {
|
||||
t.Error("Test Failed - DeriveURLValsFromJSON unexpected value",
|
||||
vals["val"][0])
|
||||
}
|
||||
}
|
||||
439
exchanges/mock/recording.go
Normal file
439
exchanges/mock/recording.go
Normal file
@@ -0,0 +1,439 @@
|
||||
package mock
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"reflect"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"github.com/thrasher-corp/gocryptotrader/common"
|
||||
)
|
||||
|
||||
// HTTPResponse defines expected response from the end point including request
|
||||
// data for pathing on the VCR server
|
||||
type HTTPResponse struct {
|
||||
Data json.RawMessage `json:"data"`
|
||||
QueryString string `json:"queryString"`
|
||||
BodyParams string `json:"bodyParams"`
|
||||
Headers map[string][]string `json:"headers"`
|
||||
}
|
||||
|
||||
// HTTPRecord will record the request and response to a default JSON file for
|
||||
// mocking purposes
|
||||
func HTTPRecord(res *http.Response, service string, respContents []byte) error {
|
||||
if res == nil {
|
||||
return errors.New("http.Response cannot be nil")
|
||||
}
|
||||
|
||||
if res.Request == nil {
|
||||
return errors.New("http.Request cannot be nil")
|
||||
}
|
||||
|
||||
if res.Request.Method == "" {
|
||||
return errors.New("request method not supplied")
|
||||
}
|
||||
|
||||
if service == "" {
|
||||
return errors.New("service not supplied cannot access correct mock file")
|
||||
}
|
||||
service = strings.ToLower(service)
|
||||
|
||||
fileout := filepath.Join(DefaultDirectory, service, service+".json")
|
||||
|
||||
contents, err := common.ReadFile(fileout)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var m VCRMock
|
||||
err = json.Unmarshal(contents, &m)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if m.Routes == nil {
|
||||
m.Routes = make(map[string]map[string][]HTTPResponse)
|
||||
}
|
||||
|
||||
var httpResponse HTTPResponse
|
||||
cleanedContents, err := CheckResponsePayload(respContents)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = json.Unmarshal(cleanedContents, &httpResponse.Data)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var body string
|
||||
if res.Request.GetBody != nil {
|
||||
bodycopy, bodyErr := res.Request.GetBody()
|
||||
if bodyErr != nil {
|
||||
return bodyErr
|
||||
}
|
||||
payload, bodyErr := ioutil.ReadAll(bodycopy)
|
||||
if bodyErr != nil {
|
||||
return bodyErr
|
||||
}
|
||||
body = string(payload)
|
||||
}
|
||||
|
||||
switch res.Request.Header.Get(contentType) {
|
||||
case applicationURLEncoded:
|
||||
vals, urlErr := url.ParseQuery(body)
|
||||
if urlErr != nil {
|
||||
return urlErr
|
||||
}
|
||||
|
||||
httpResponse.BodyParams, urlErr = GetFilteredURLVals(vals)
|
||||
if urlErr != nil {
|
||||
return urlErr
|
||||
}
|
||||
|
||||
case textPlain:
|
||||
payload := res.Request.Header.Get("X-Gemini-Payload")
|
||||
j, dErr := common.Base64Decode(payload)
|
||||
if dErr != nil {
|
||||
return dErr
|
||||
}
|
||||
|
||||
httpResponse.BodyParams = string(j)
|
||||
|
||||
default:
|
||||
httpResponse.BodyParams = body
|
||||
}
|
||||
|
||||
httpResponse.Headers, err = GetFilteredHeader(res)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
httpResponse.QueryString, err = GetFilteredURLVals(res.Request.URL.Query())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
_, ok := m.Routes[res.Request.URL.Path]
|
||||
if !ok {
|
||||
m.Routes[res.Request.URL.Path] = make(map[string][]HTTPResponse)
|
||||
m.Routes[res.Request.URL.Path][res.Request.Method] = []HTTPResponse{httpResponse}
|
||||
} else {
|
||||
mockResponses, ok := m.Routes[res.Request.URL.Path][res.Request.Method]
|
||||
if !ok {
|
||||
m.Routes[res.Request.URL.Path][res.Request.Method] = []HTTPResponse{httpResponse}
|
||||
} else {
|
||||
switch res.Request.Method { // Based off method - check add or replace
|
||||
case http.MethodGet:
|
||||
for i := range mockResponses {
|
||||
mockQuery, urlErr := url.ParseQuery(mockResponses[i].QueryString)
|
||||
if urlErr != nil {
|
||||
return urlErr
|
||||
}
|
||||
|
||||
if MatchURLVals(mockQuery, res.Request.URL.Query()) {
|
||||
mockResponses = append(mockResponses[:i], mockResponses[i+1:]...) // Delete Old
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
case http.MethodPost:
|
||||
for i := range mockResponses {
|
||||
cType, ok := mockResponses[i].Headers[contentType]
|
||||
if !ok {
|
||||
return errors.New("cannot find content type within mock responses")
|
||||
}
|
||||
|
||||
jCType := strings.Join(cType, "")
|
||||
var found bool
|
||||
switch jCType {
|
||||
case applicationURLEncoded:
|
||||
respQueryVals, urlErr := url.ParseQuery(body)
|
||||
if urlErr != nil {
|
||||
return urlErr
|
||||
}
|
||||
|
||||
mockRespVals, urlErr := url.ParseQuery(mockResponses[i].BodyParams)
|
||||
if urlErr != nil {
|
||||
log.Fatal(urlErr)
|
||||
}
|
||||
|
||||
if MatchURLVals(respQueryVals, mockRespVals) {
|
||||
// if found will delete instance and overwrite with new
|
||||
// data
|
||||
mockResponses = append(mockResponses[:i], mockResponses[i+1:]...)
|
||||
found = true
|
||||
}
|
||||
|
||||
case applicationJSON, textPlain:
|
||||
reqVals, jErr := DeriveURLValsFromJSONMap([]byte(body))
|
||||
if jErr != nil {
|
||||
return jErr
|
||||
}
|
||||
|
||||
mockVals, jErr := DeriveURLValsFromJSONMap([]byte(mockResponses[i].BodyParams))
|
||||
if jErr != nil {
|
||||
return jErr
|
||||
}
|
||||
|
||||
if MatchURLVals(reqVals, mockVals) {
|
||||
// if found will delete instance and overwrite with new
|
||||
// data
|
||||
mockResponses = append(mockResponses[:i], mockResponses[i+1:]...)
|
||||
found = true
|
||||
}
|
||||
|
||||
default:
|
||||
return fmt.Errorf("unhandled content type %s", jCType)
|
||||
}
|
||||
if found {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
default:
|
||||
return fmt.Errorf("unhandled request method %s", res.Request.Method)
|
||||
}
|
||||
|
||||
m.Routes[res.Request.URL.Path][res.Request.Method] = append(mockResponses, httpResponse)
|
||||
}
|
||||
}
|
||||
|
||||
payload, err := json.MarshalIndent(m, "", " ")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return common.WriteFile(fileout, payload)
|
||||
}
|
||||
|
||||
// GetFilteredHeader filters excluded http headers for insertion into a mock
|
||||
// test file
|
||||
func GetFilteredHeader(res *http.Response) (http.Header, error) {
|
||||
items, err := GetExcludedItems()
|
||||
if err != nil {
|
||||
return res.Header, err
|
||||
}
|
||||
|
||||
for i := range items.Headers {
|
||||
if res.Request.Header.Get(items.Headers[i]) != "" {
|
||||
res.Request.Header.Set(items.Headers[i], "")
|
||||
}
|
||||
}
|
||||
|
||||
return res.Request.Header, nil
|
||||
}
|
||||
|
||||
// GetFilteredURLVals filters excluded url value variables for insertion into a
|
||||
// mock test file
|
||||
func GetFilteredURLVals(vals url.Values) (string, error) {
|
||||
items, err := GetExcludedItems()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
for key, val := range vals {
|
||||
for i := range items.Variables {
|
||||
if strings.EqualFold(items.Variables[i], val[0]) {
|
||||
vals.Set(key, "")
|
||||
}
|
||||
}
|
||||
}
|
||||
return vals.Encode(), nil
|
||||
}
|
||||
|
||||
// CheckResponsePayload checks to see if there are any response body variables
|
||||
// that should not be there.
|
||||
func CheckResponsePayload(data []byte) ([]byte, error) {
|
||||
items, err := GetExcludedItems()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var intermediary interface{}
|
||||
err = json.Unmarshal(data, &intermediary)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
payload, err := CheckJSON(intermediary, &items)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return json.MarshalIndent(payload, "", " ")
|
||||
}
|
||||
|
||||
// Reflection consts
|
||||
const (
|
||||
Int64 = "int64"
|
||||
Float64 = "float64"
|
||||
Slice = "slice"
|
||||
String = "string"
|
||||
Bool = "bool"
|
||||
Invalid = "invalid"
|
||||
)
|
||||
|
||||
// CheckJSON recursively parses json data to retract keywords, quite intensive.
|
||||
func CheckJSON(data interface{}, excluded *Exclusion) (interface{}, error) {
|
||||
var context map[string]interface{}
|
||||
if reflect.TypeOf(data).String() == "[]interface {}" {
|
||||
var sData []interface{}
|
||||
for i := range data.([]interface{}) {
|
||||
checkedData, err := CheckJSON(data.([]interface{})[i], excluded)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
sData = append(sData, checkedData)
|
||||
}
|
||||
return sData, nil
|
||||
}
|
||||
|
||||
conv, err := json.Marshal(data)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = json.Unmarshal(conv, &context)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if len(context) == 0 {
|
||||
// Nil for some reason, should error out before in json.Unmarshal
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
for key, val := range context {
|
||||
switch reflect.ValueOf(val).Kind().String() {
|
||||
case String:
|
||||
if IsExcluded(key, excluded.Variables) {
|
||||
context[key] = "" // Zero val string
|
||||
}
|
||||
case Int64:
|
||||
if IsExcluded(key, excluded.Variables) {
|
||||
context[key] = 0 // Zero val int
|
||||
}
|
||||
case Float64:
|
||||
if IsExcluded(key, excluded.Variables) {
|
||||
context[key] = 0.0 // Zero val float
|
||||
}
|
||||
case Slice:
|
||||
slice := val.([]interface{})
|
||||
if len(slice) < 1 {
|
||||
// Empty slice found
|
||||
context[key] = slice
|
||||
} else {
|
||||
if _, ok := slice[0].(map[string]interface{}); ok {
|
||||
var cleanSlice []interface{}
|
||||
for i := range slice {
|
||||
cleanMap, sErr := CheckJSON(slice[i], excluded)
|
||||
if sErr != nil {
|
||||
return nil, sErr
|
||||
}
|
||||
cleanSlice = append(cleanSlice, cleanMap)
|
||||
}
|
||||
context[key] = cleanSlice
|
||||
} else if IsExcluded(key, excluded.Variables) {
|
||||
context[key] = nil // Zero val slice
|
||||
}
|
||||
}
|
||||
|
||||
case Bool, Invalid: // Skip these bad boys for now
|
||||
default:
|
||||
// Recursively check map data
|
||||
contextValue, err := CheckJSON(val, excluded)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
context[key] = contextValue
|
||||
}
|
||||
}
|
||||
|
||||
return context, nil
|
||||
}
|
||||
|
||||
// IsExcluded cross references the key with the excluded variables
|
||||
func IsExcluded(key string, excludedVars []string) bool {
|
||||
for i := range excludedVars {
|
||||
if strings.EqualFold(key, excludedVars[i]) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
var excludedList Exclusion
|
||||
var m sync.Mutex
|
||||
var set bool
|
||||
var exclusionFile = DefaultDirectory + "exclusion.json"
|
||||
|
||||
var defaultExcludedHeaders = []string{"Key",
|
||||
"X-Mbx-Apikey",
|
||||
"Rest-Key",
|
||||
"Apiauth-Key"}
|
||||
var defaultExcludedVariables = []string{"bsb",
|
||||
"user",
|
||||
"name",
|
||||
"real_name",
|
||||
"receiver_name",
|
||||
"account_number",
|
||||
"username"}
|
||||
|
||||
// Exclusion defines a list of items to be excluded from the main mock output
|
||||
// this attempts a catch all approach and needs to be updated per exchange basis
|
||||
type Exclusion struct {
|
||||
Headers []string `json:"headers"`
|
||||
Variables []string `json:"variables"`
|
||||
}
|
||||
|
||||
// GetExcludedItems checks to see if the variable is in the exclusion list as to
|
||||
// not display secure items in mock file generator output
|
||||
func GetExcludedItems() (Exclusion, error) {
|
||||
m.Lock()
|
||||
defer m.Unlock()
|
||||
if !set {
|
||||
file, err := ioutil.ReadFile(exclusionFile)
|
||||
if err != nil {
|
||||
if !strings.Contains(err.Error(), "no such file or directory") {
|
||||
return excludedList, err
|
||||
}
|
||||
|
||||
excludedList.Headers = defaultExcludedHeaders
|
||||
excludedList.Variables = defaultExcludedVariables
|
||||
|
||||
data, mErr := json.MarshalIndent(excludedList, "", " ")
|
||||
if mErr != nil {
|
||||
return excludedList, mErr
|
||||
}
|
||||
|
||||
mErr = ioutil.WriteFile(exclusionFile, data, os.ModePerm)
|
||||
if mErr != nil {
|
||||
return excludedList, mErr
|
||||
}
|
||||
|
||||
} else {
|
||||
err = json.Unmarshal(file, &excludedList)
|
||||
if err != nil {
|
||||
return excludedList, err
|
||||
}
|
||||
|
||||
if len(excludedList.Headers) == 0 || len(excludedList.Variables) == 0 {
|
||||
return excludedList, errors.New("exclusion list does not have names")
|
||||
}
|
||||
}
|
||||
|
||||
set = true
|
||||
}
|
||||
|
||||
return excludedList, nil
|
||||
}
|
||||
186
exchanges/mock/recording_test.go
Normal file
186
exchanges/mock/recording_test.go
Normal file
@@ -0,0 +1,186 @@
|
||||
package mock
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestGetFilteredHeader(t *testing.T) {
|
||||
resp := http.Response{}
|
||||
resp.Request = &http.Request{}
|
||||
resp.Request.Header = http.Header{}
|
||||
resp.Request.Header.Set("Key", "RiskyVals")
|
||||
fMap, err := GetFilteredHeader(&resp)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
if fMap.Get("Key") != "" {
|
||||
t.Error("Test Failed - risky vals where not replaced correctly")
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetFilteredURLVals(t *testing.T) {
|
||||
superSecretData := "Dr Seuss"
|
||||
shadyVals := url.Values{}
|
||||
shadyVals.Set("real_name", superSecretData)
|
||||
cleanVals, err := GetFilteredURLVals(shadyVals)
|
||||
if err != nil {
|
||||
t.Error("Test Failed - GetFilteredURLVals error", err)
|
||||
}
|
||||
|
||||
if strings.Contains(cleanVals, superSecretData) {
|
||||
t.Error("Test Failed - Super secret data found")
|
||||
}
|
||||
}
|
||||
|
||||
func TestCheckResponsePayload(t *testing.T) {
|
||||
testbody := struct {
|
||||
SomeJSON string `json:"stuff"`
|
||||
}{
|
||||
SomeJSON: "REAAAAHHHHH",
|
||||
}
|
||||
|
||||
payload, err := json.Marshal(testbody)
|
||||
if err != nil {
|
||||
t.Fatal("Test Failed - json marshal error", err)
|
||||
}
|
||||
|
||||
data, err := CheckResponsePayload(payload)
|
||||
if err != nil {
|
||||
t.Error("Test Failed - CheckBody error", err)
|
||||
}
|
||||
|
||||
expected := `{
|
||||
"stuff": "REAAAAHHHHH"
|
||||
}`
|
||||
|
||||
if string(data) != expected {
|
||||
t.Error("unexpected returned data")
|
||||
}
|
||||
}
|
||||
|
||||
type TestStructLevel0 struct {
|
||||
StringVal string `json:"stringVal"`
|
||||
FloatVal float64 `json:"floatVal"`
|
||||
IntVal int64 `json:"intVal"`
|
||||
StructVal TestStructLevel1 `json:"structVal"`
|
||||
}
|
||||
|
||||
type TestStructLevel1 struct {
|
||||
OkayVal string `json:"okayVal"`
|
||||
OkayVal2 float64 `json:"okayVal2"`
|
||||
BadVal string `json:"user"`
|
||||
BadVal2 int `json:"bsb"`
|
||||
OtherData TestStructLevel2 `json:"otherVals"`
|
||||
}
|
||||
|
||||
type TestStructLevel2 struct {
|
||||
OkayVal string `json:"okayVal"`
|
||||
OkayVal2 float64 `json:"okayVal2"`
|
||||
BadVal float32 `json:"name"`
|
||||
BadVal2 int32 `json:"real_name"`
|
||||
OtherData TestStructLevel3 `json:"moreOtherVals"`
|
||||
}
|
||||
|
||||
type TestStructLevel3 struct {
|
||||
OkayVal string `json:"okayVal"`
|
||||
OkayVal2 float64 `json:"okayVal2"`
|
||||
BadVal int64 `json:"receiver_name"`
|
||||
BadVal2 string `json:"account_number"`
|
||||
}
|
||||
|
||||
func TestCheckJSON(t *testing.T) {
|
||||
level3 := TestStructLevel3{
|
||||
OkayVal: "stuff",
|
||||
OkayVal2: 129219,
|
||||
BadVal: 1337,
|
||||
BadVal2: "Super Secret Password",
|
||||
}
|
||||
|
||||
level2 := TestStructLevel2{
|
||||
OkayVal: "stuff",
|
||||
OkayVal2: 129219,
|
||||
BadVal: 0.222,
|
||||
BadVal2: 1337888888,
|
||||
OtherData: level3,
|
||||
}
|
||||
|
||||
level1 := TestStructLevel1{
|
||||
OkayVal: "stuff",
|
||||
OkayVal2: 120938,
|
||||
BadVal: "CritcalBankingStuff",
|
||||
BadVal2: 1337,
|
||||
OtherData: level2,
|
||||
}
|
||||
|
||||
testVal := TestStructLevel0{
|
||||
StringVal: "somestringstuff",
|
||||
FloatVal: 3.14,
|
||||
IntVal: 1337,
|
||||
StructVal: level1,
|
||||
}
|
||||
|
||||
exclusionList, err := GetExcludedItems()
|
||||
if err != nil {
|
||||
t.Error("Test Failed - GetExcludedItems error", err)
|
||||
}
|
||||
|
||||
vals, err := CheckJSON(testVal, &exclusionList)
|
||||
if err != nil {
|
||||
t.Error("Test Failed - Check JSON error", err)
|
||||
}
|
||||
|
||||
payload, err := json.Marshal(vals)
|
||||
if err != nil {
|
||||
t.Fatal("Test Failed - json marshal error", err)
|
||||
}
|
||||
|
||||
newStruct := TestStructLevel0{}
|
||||
err = json.Unmarshal(payload, &newStruct)
|
||||
if err != nil {
|
||||
t.Fatal("Test Failed - Umarshal error", err)
|
||||
}
|
||||
|
||||
if newStruct.StructVal.BadVal != "" {
|
||||
t.Error("Value not wiped correctly")
|
||||
}
|
||||
|
||||
if newStruct.StructVal.BadVal2 != 0 {
|
||||
t.Error("Value not wiped correctly")
|
||||
}
|
||||
|
||||
if newStruct.StructVal.OtherData.BadVal != 0 {
|
||||
t.Error("Value not wiped correctly")
|
||||
}
|
||||
|
||||
if newStruct.StructVal.OtherData.BadVal2 != 0 {
|
||||
t.Error("Value not wiped correctly")
|
||||
}
|
||||
|
||||
if newStruct.StructVal.OtherData.OtherData.BadVal != 0 {
|
||||
t.Error("Value not wiped correctly")
|
||||
}
|
||||
|
||||
if newStruct.StructVal.OtherData.OtherData.BadVal2 != "" {
|
||||
t.Error("Value not wiped correctly")
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetExcludedItems(t *testing.T) {
|
||||
exclusionList, err := GetExcludedItems()
|
||||
if err != nil {
|
||||
t.Error("Test Failed - GetExcludedItems error", err)
|
||||
}
|
||||
|
||||
if len(exclusionList.Headers) == 0 {
|
||||
t.Error("Test Failed - Header exclusion list not popoulated")
|
||||
}
|
||||
|
||||
if len(exclusionList.Variables) == 0 {
|
||||
t.Error("Test Failed - Variable exclusion list not popoulated")
|
||||
}
|
||||
}
|
||||
282
exchanges/mock/server.go
Normal file
282
exchanges/mock/server.go
Normal file
@@ -0,0 +1,282 @@
|
||||
package mock
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"net/url"
|
||||
"reflect"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/thrasher-corp/gocryptotrader/common"
|
||||
)
|
||||
|
||||
// DefaultDirectory defines the main mock directory
|
||||
const DefaultDirectory = "../../testdata/http_mock/"
|
||||
|
||||
const (
|
||||
contentType = "Content-Type"
|
||||
applicationURLEncoded = "application/x-www-form-urlencoded"
|
||||
applicationJSON = "application/json"
|
||||
textPlain = "text/plain"
|
||||
)
|
||||
|
||||
// VCRMock defines the main mock JSON file and attributes
|
||||
type VCRMock struct {
|
||||
Routes map[string]map[string][]HTTPResponse `json:"routes"`
|
||||
}
|
||||
|
||||
// NewVCRServer starts a new VCR server for replaying HTTP requests for testing
|
||||
// purposes and returns the server connection details
|
||||
func NewVCRServer(path string) (string, *http.Client, error) {
|
||||
if path == "" {
|
||||
return "", nil, errors.New("no path to json mock file found")
|
||||
}
|
||||
|
||||
var mockFile VCRMock
|
||||
|
||||
contents, err := ioutil.ReadFile(path)
|
||||
if err != nil {
|
||||
pathing := common.SplitStrings(path, "/")
|
||||
dirPathing := pathing[:len(pathing)-1]
|
||||
dir := common.JoinStrings(dirPathing, "/")
|
||||
err = common.CreateDir(dir)
|
||||
if err != nil {
|
||||
return "", nil, err
|
||||
}
|
||||
|
||||
data, jErr := json.MarshalIndent(mockFile, "", " ")
|
||||
if jErr != nil {
|
||||
return "", nil, jErr
|
||||
}
|
||||
|
||||
err = common.WriteFile(path, data)
|
||||
if err != nil {
|
||||
return "", nil, err
|
||||
}
|
||||
contents = data
|
||||
}
|
||||
|
||||
if !json.Valid(contents) {
|
||||
return "",
|
||||
nil,
|
||||
fmt.Errorf("contents of file %s are not valid JSON", path)
|
||||
}
|
||||
|
||||
// Get mocking data for the specific service
|
||||
err = json.Unmarshal(contents, &mockFile)
|
||||
if err != nil {
|
||||
return "", nil, err
|
||||
}
|
||||
|
||||
newMux := http.NewServeMux()
|
||||
// Range over routes and assign responses to explicit paths and http
|
||||
// methods
|
||||
if len(mockFile.Routes) != 0 {
|
||||
for pattern, mockResponses := range mockFile.Routes {
|
||||
RegisterHandler(pattern, mockResponses, newMux)
|
||||
}
|
||||
} else {
|
||||
newMux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
|
||||
w.WriteHeader(http.StatusNotFound)
|
||||
err := json.NewEncoder(w).Encode("There is no mock data available in file please record a new HTTP response. Please follow README.md in the mock package.")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
})
|
||||
}
|
||||
tlsServer := httptest.NewTLSServer(newMux)
|
||||
|
||||
return tlsServer.URL, tlsServer.Client(), nil
|
||||
}
|
||||
|
||||
// RegisterHandler registers a generalised mock response logic for specific
|
||||
// routes
|
||||
func RegisterHandler(pattern string, mock map[string][]HTTPResponse, mux *http.ServeMux) {
|
||||
mux.HandleFunc(pattern, func(w http.ResponseWriter, r *http.Request) {
|
||||
httpResponses, ok := mock[r.Method]
|
||||
if !ok {
|
||||
log.Fatalf("Mock Test Failure - Method %s not present in mock file",
|
||||
r.Method)
|
||||
}
|
||||
|
||||
switch r.Method {
|
||||
case http.MethodGet:
|
||||
vals, err := url.ParseRequestURI(r.RequestURI)
|
||||
if err != nil {
|
||||
log.Fatal("Mock Test Failure - Parse request URI error", err)
|
||||
}
|
||||
|
||||
payload, err := MatchAndGetResponse(httpResponses, vals.Query(), true)
|
||||
if err != nil {
|
||||
log.Fatalf("Mock Test Failure - MatchAndGetResponse error %s for %s",
|
||||
err, r.RequestURI)
|
||||
}
|
||||
|
||||
MessageWriteJSON(w, http.StatusOK, payload)
|
||||
return
|
||||
|
||||
case http.MethodPost:
|
||||
switch r.Header.Get(contentType) {
|
||||
case applicationURLEncoded:
|
||||
readBody, err := ioutil.ReadAll(r.Body)
|
||||
if err != nil {
|
||||
log.Fatal("Mock Test Failure - ReadAll error", err)
|
||||
}
|
||||
|
||||
vals, err := url.ParseQuery(string(readBody))
|
||||
if err != nil {
|
||||
log.Fatal("Mock Test Failure - parse query error", err)
|
||||
}
|
||||
|
||||
payload, err := MatchAndGetResponse(httpResponses, vals, false)
|
||||
if err != nil {
|
||||
log.Fatal("Mock Test Failure - MatchAndGetResponse error ", err)
|
||||
}
|
||||
|
||||
MessageWriteJSON(w, http.StatusOK, payload)
|
||||
return
|
||||
|
||||
case "":
|
||||
payload, err := MatchAndGetResponse(httpResponses, r.URL.Query(), true)
|
||||
if err != nil {
|
||||
log.Fatal("Mock Test Failure - MatchAndGetResponse error ", err)
|
||||
}
|
||||
|
||||
MessageWriteJSON(w, http.StatusOK, payload)
|
||||
return
|
||||
|
||||
case applicationJSON:
|
||||
readBody, err := ioutil.ReadAll(r.Body)
|
||||
if err != nil {
|
||||
log.Fatalf("Mock Test Failure - %v", err)
|
||||
}
|
||||
|
||||
reqVals, err := DeriveURLValsFromJSONMap(readBody)
|
||||
if err != nil {
|
||||
log.Fatalf("Mock Test Failure - %v", err)
|
||||
}
|
||||
|
||||
payload, err := MatchAndGetResponse(httpResponses, reqVals, false)
|
||||
if err != nil {
|
||||
log.Fatal("Mock Test Failure - MatchAndGetResponse error ", err)
|
||||
}
|
||||
|
||||
MessageWriteJSON(w, http.StatusOK, payload)
|
||||
return
|
||||
|
||||
case textPlain:
|
||||
headerData, ok := r.Header["X-Gemini-Payload"]
|
||||
if !ok {
|
||||
log.Fatal("Mock Test Failure - Cannot find header in request")
|
||||
}
|
||||
|
||||
base64data := strings.Join(headerData, "")
|
||||
|
||||
jsonThings, err := common.Base64Decode(base64data)
|
||||
if err != nil {
|
||||
log.Fatal("Mock Test Failure - ", err)
|
||||
}
|
||||
|
||||
reqVals, err := DeriveURLValsFromJSONMap(jsonThings)
|
||||
if err != nil {
|
||||
log.Fatalf("Mock Test Failure - %v", err)
|
||||
}
|
||||
|
||||
payload, err := MatchAndGetResponse(httpResponses, reqVals, false)
|
||||
if err != nil {
|
||||
log.Fatal("Mock Test Failure - MatchAndGetResponse error ", err)
|
||||
}
|
||||
|
||||
MessageWriteJSON(w, http.StatusOK, payload)
|
||||
return
|
||||
|
||||
default:
|
||||
log.Fatalf("Mock Test Failure - Unhandled content type %v",
|
||||
r.Header.Get(contentType))
|
||||
}
|
||||
|
||||
case http.MethodDelete:
|
||||
payload, err := MatchAndGetResponse(httpResponses, r.URL.Query(), true)
|
||||
if err != nil {
|
||||
log.Println(r.URL.Query())
|
||||
log.Fatal("Mock Test Failure - MatchAndGetResponse error ", err)
|
||||
}
|
||||
|
||||
MessageWriteJSON(w, http.StatusOK, payload)
|
||||
return
|
||||
|
||||
default:
|
||||
log.Fatal("Mock Test Failure - Unhandled HTTP method:",
|
||||
r.Header.Get(contentType))
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// MessageWriteJSON writes JSON to a connection
|
||||
func MessageWriteJSON(w http.ResponseWriter, status int, data interface{}) {
|
||||
w.Header().Set(contentType, applicationJSON)
|
||||
w.WriteHeader(status)
|
||||
if data != nil {
|
||||
err := json.NewEncoder(w).Encode(data)
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
w.Write([]byte(err.Error()))
|
||||
log.Fatal("Mock Test Failure - JSON encode error", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// MatchAndGetResponse matches incoming request values with mockdata response
|
||||
// values and returns the payload
|
||||
func MatchAndGetResponse(mockData []HTTPResponse, requestVals url.Values, isQueryData bool) (json.RawMessage, error) {
|
||||
for i := range mockData {
|
||||
var data string
|
||||
if isQueryData {
|
||||
data = mockData[i].QueryString
|
||||
} else {
|
||||
data = mockData[i].BodyParams
|
||||
}
|
||||
|
||||
var mockVals = url.Values{}
|
||||
var err error
|
||||
if json.Valid([]byte(data)) {
|
||||
something := make(map[string]interface{})
|
||||
err = json.Unmarshal([]byte(data), &something)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for k, v := range something {
|
||||
switch val := v.(type) {
|
||||
case string:
|
||||
mockVals.Add(k, val)
|
||||
case bool:
|
||||
mockVals.Add(k, strconv.FormatBool(val))
|
||||
case float64:
|
||||
mockVals.Add(k, strconv.FormatFloat(val, 'f', -1, 64))
|
||||
case map[string]interface{}, []interface{}, nil:
|
||||
mockVals.Add(k, fmt.Sprintf("%v", val))
|
||||
default:
|
||||
log.Println(reflect.TypeOf(val))
|
||||
log.Fatal("unhandled type please add as needed")
|
||||
}
|
||||
}
|
||||
} else {
|
||||
mockVals, err = url.ParseQuery(data)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
if MatchURLVals(mockVals, requestVals) {
|
||||
return mockData[i].Data, nil
|
||||
}
|
||||
}
|
||||
return nil, errors.New("no data could be matched")
|
||||
}
|
||||
117
exchanges/mock/server_test.go
Normal file
117
exchanges/mock/server_test.go
Normal file
@@ -0,0 +1,117 @@
|
||||
package mock
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"os"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/thrasher-corp/gocryptotrader/common"
|
||||
)
|
||||
|
||||
type responsePayload struct {
|
||||
Price float64 `json:"price"`
|
||||
Amount float64 `json:"amount"`
|
||||
Currency string `json:"currency"`
|
||||
}
|
||||
|
||||
const queryString = "currency=btc&command=getprice"
|
||||
const testFile = "test.json"
|
||||
|
||||
func TestNewVCRServer(t *testing.T) {
|
||||
_, _, err := NewVCRServer("")
|
||||
if err == nil {
|
||||
t.Error("Test Failed - NewVCRServer error cannot be nil")
|
||||
}
|
||||
|
||||
// Set up mock data
|
||||
test1 := VCRMock{}
|
||||
test1.Routes = make(map[string]map[string][]HTTPResponse)
|
||||
test1.Routes["/test"] = make(map[string][]HTTPResponse)
|
||||
|
||||
rp, err := json.Marshal(responsePayload{Price: 8000.0,
|
||||
Amount: 1,
|
||||
Currency: "bitcoin"})
|
||||
if err != nil {
|
||||
t.Fatal("Test Failed - marshal error", err)
|
||||
}
|
||||
|
||||
testValue := HTTPResponse{Data: rp, QueryString: queryString, BodyParams: queryString}
|
||||
test1.Routes["/test"][http.MethodGet] = []HTTPResponse{testValue}
|
||||
|
||||
payload, err := json.Marshal(test1)
|
||||
if err != nil {
|
||||
t.Fatal("Test Failed - marshal error", err)
|
||||
}
|
||||
|
||||
err = ioutil.WriteFile(testFile, payload, os.ModePerm)
|
||||
if err != nil {
|
||||
t.Fatal("Test Failed - marshal error", err)
|
||||
}
|
||||
|
||||
deets, client, err := NewVCRServer(testFile)
|
||||
if err != nil {
|
||||
t.Error("Test Failed - NewVCRServer error", err)
|
||||
}
|
||||
|
||||
common.HTTPClient = client // Set common package global HTTP Client
|
||||
|
||||
_, err = common.SendHTTPRequest(http.MethodGet,
|
||||
"http://localhost:300/somethingElse?"+queryString,
|
||||
nil,
|
||||
bytes.NewBufferString(""))
|
||||
if err == nil {
|
||||
t.Error("Test Failed - Sending http request expected an error")
|
||||
}
|
||||
|
||||
// Expected good outcome
|
||||
r, err := common.SendHTTPRequest(http.MethodGet,
|
||||
deets,
|
||||
nil,
|
||||
bytes.NewBufferString(""))
|
||||
if err != nil {
|
||||
t.Error("Test Failed - Sending http request error", err)
|
||||
}
|
||||
|
||||
if !strings.Contains(r, "404 page not found") {
|
||||
t.Error("Test Failed - Was not expecting any value returned:", r)
|
||||
}
|
||||
|
||||
r, err = common.SendHTTPRequest(http.MethodGet,
|
||||
deets+"/test?"+queryString,
|
||||
nil,
|
||||
bytes.NewBufferString(""))
|
||||
if err != nil {
|
||||
t.Error("Test Failed - Sending http request error", err)
|
||||
}
|
||||
|
||||
var res responsePayload
|
||||
err = json.Unmarshal([]byte(r), &res)
|
||||
if err != nil {
|
||||
t.Error("Test Failed - unmarshal error", err)
|
||||
}
|
||||
|
||||
if res.Price != 8000 {
|
||||
t.Error("Test Failed - response error expected 8000 but received:",
|
||||
res.Price)
|
||||
}
|
||||
|
||||
if res.Amount != 1 {
|
||||
t.Error("Test Failed - response error expected 1 but received:",
|
||||
res.Amount)
|
||||
}
|
||||
|
||||
if res.Currency != "bitcoin" {
|
||||
t.Error("Test Failed - response error expected \"bitcoin\" but received:",
|
||||
res.Currency)
|
||||
}
|
||||
|
||||
// clean up test.json file
|
||||
err = os.Remove(testFile)
|
||||
if err != nil {
|
||||
t.Fatal("Test Failed - Remove error", err)
|
||||
}
|
||||
}
|
||||
@@ -643,7 +643,15 @@ func (o *OKGroup) SendHTTPRequest(httpMethod, requestType, requestPath string, d
|
||||
|
||||
errCap := errCapFormat{}
|
||||
errCap.Result = true
|
||||
err = o.SendPayload(strings.ToUpper(httpMethod), path, headers, bytes.NewBuffer(payload), &intermediary, authenticated, false, o.Verbose, o.HTTPDebugging)
|
||||
err = o.SendPayload(strings.ToUpper(httpMethod),
|
||||
path, headers,
|
||||
bytes.NewBuffer(payload),
|
||||
&intermediary,
|
||||
authenticated,
|
||||
false,
|
||||
o.Verbose,
|
||||
o.HTTPDebugging,
|
||||
o.HTTPRecording)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -348,8 +348,8 @@ func (p *Poloniex) GetLoanOrders(currency string) (LoanOrders, error) {
|
||||
// GetBalances returns balances for your account.
|
||||
func (p *Poloniex) GetBalances() (Balance, error) {
|
||||
var result interface{}
|
||||
err := p.SendAuthenticatedHTTPRequest(http.MethodPost, poloniexBalances, url.Values{}, &result)
|
||||
|
||||
err := p.SendAuthenticatedHTTPRequest(http.MethodPost, poloniexBalances, url.Values{}, &result)
|
||||
if err != nil {
|
||||
return Balance{}, err
|
||||
}
|
||||
@@ -368,8 +368,8 @@ func (p *Poloniex) GetBalances() (Balance, error) {
|
||||
// GetCompleteBalances returns complete balances from your account.
|
||||
func (p *Poloniex) GetCompleteBalances() (CompleteBalances, error) {
|
||||
var result interface{}
|
||||
err := p.SendAuthenticatedHTTPRequest(http.MethodPost, poloniexBalancesComplete, url.Values{}, &result)
|
||||
|
||||
err := p.SendAuthenticatedHTTPRequest(http.MethodPost, poloniexBalancesComplete, url.Values{}, &result)
|
||||
if err != nil {
|
||||
return CompleteBalances{}, err
|
||||
}
|
||||
@@ -394,14 +394,18 @@ func (p *Poloniex) GetCompleteBalances() (CompleteBalances, error) {
|
||||
func (p *Poloniex) GetDepositAddresses() (DepositAddresses, error) {
|
||||
var result interface{}
|
||||
addresses := DepositAddresses{}
|
||||
err := p.SendAuthenticatedHTTPRequest(http.MethodPost, poloniexDepositAddresses, url.Values{}, &result)
|
||||
|
||||
err := p.SendAuthenticatedHTTPRequest(http.MethodPost, poloniexDepositAddresses, url.Values{}, &result)
|
||||
if err != nil {
|
||||
return addresses, err
|
||||
}
|
||||
|
||||
addresses.Addresses = make(map[string]string)
|
||||
data := result.(map[string]interface{})
|
||||
data, ok := result.(map[string]interface{})
|
||||
if !ok {
|
||||
return addresses, errors.New("return val not map[string]interface{}")
|
||||
}
|
||||
|
||||
for x, y := range data {
|
||||
addresses.Addresses[x] = y.(string)
|
||||
}
|
||||
@@ -421,7 +425,6 @@ func (p *Poloniex) GenerateNewAddress(currency string) (string, error) {
|
||||
values.Set("currency", currency)
|
||||
|
||||
err := p.SendAuthenticatedHTTPRequest(http.MethodPost, poloniexGenerateNewAddress, values, &resp)
|
||||
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
@@ -622,7 +625,6 @@ func (p *Poloniex) Withdraw(currency, address string, amount float64) (bool, err
|
||||
values.Set("address", address)
|
||||
|
||||
err := p.SendAuthenticatedHTTPRequest(http.MethodPost, poloniexWithdraw, values, &result)
|
||||
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
@@ -649,7 +651,6 @@ func (p *Poloniex) GetTradableBalances() (map[string]map[string]float64, error)
|
||||
result := Response{}
|
||||
|
||||
err := p.SendAuthenticatedHTTPRequest(http.MethodPost, poloniexTradableBalances, url.Values{}, &result.Data)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -677,7 +678,6 @@ func (p *Poloniex) TransferBalance(currency, from, to string, amount float64) (b
|
||||
values.Set("toAccount", to)
|
||||
|
||||
err := p.SendAuthenticatedHTTPRequest(http.MethodPost, poloniexTransferBalance, values, &result)
|
||||
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
@@ -743,7 +743,6 @@ func (p *Poloniex) CloseMarginPosition(currency string) (bool, error) {
|
||||
result := GenericResponse{}
|
||||
|
||||
err := p.SendAuthenticatedHTTPRequest(http.MethodPost, poloniexMarginPositionClose, values, &result)
|
||||
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
@@ -779,7 +778,6 @@ func (p *Poloniex) CreateLoanOffer(currency string, amount, rate float64, durati
|
||||
result := Response{}
|
||||
|
||||
err := p.SendAuthenticatedHTTPRequest(http.MethodPost, poloniexCreateLoanOffer, values, &result)
|
||||
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
@@ -798,7 +796,6 @@ func (p *Poloniex) CancelLoanOffer(orderNumber int64) (bool, error) {
|
||||
values.Set("orderID", strconv.FormatInt(orderNumber, 10))
|
||||
|
||||
err := p.SendAuthenticatedHTTPRequest(http.MethodPost, poloniexCancelLoanOffer, values, &result)
|
||||
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
@@ -818,7 +815,6 @@ func (p *Poloniex) GetOpenLoanOffers() (map[string][]LoanOffer, error) {
|
||||
result := Response{}
|
||||
|
||||
err := p.SendAuthenticatedHTTPRequest(http.MethodPost, poloniexOpenLoanOffers, url.Values{}, &result.Data)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -849,15 +845,10 @@ func (p *Poloniex) GetLendingHistory(start, end string) ([]LendingHistory, error
|
||||
}
|
||||
|
||||
var resp []LendingHistory
|
||||
err := p.SendAuthenticatedHTTPRequest(http.MethodPost,
|
||||
return resp, p.SendAuthenticatedHTTPRequest(http.MethodPost,
|
||||
poloniexLendingHistory,
|
||||
vals,
|
||||
&resp)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
// ToggleAutoRenew allows for the autorenew of a contract
|
||||
@@ -870,7 +861,6 @@ func (p *Poloniex) ToggleAutoRenew(orderNumber int64) (bool, error) {
|
||||
poloniexAutoRenew,
|
||||
values,
|
||||
&result)
|
||||
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
@@ -892,7 +882,8 @@ func (p *Poloniex) SendHTTPRequest(path string, result interface{}) error {
|
||||
false,
|
||||
false,
|
||||
p.Verbose,
|
||||
p.HTTPDebugging)
|
||||
p.HTTPDebugging,
|
||||
p.HTTPRecording)
|
||||
}
|
||||
|
||||
// SendAuthenticatedHTTPRequest sends an authenticated HTTP request
|
||||
@@ -901,13 +892,11 @@ func (p *Poloniex) SendAuthenticatedHTTPRequest(method, endpoint string, values
|
||||
return fmt.Errorf(exchange.WarningAuthenticatedRequestWithoutCredentialsSet,
|
||||
p.Name)
|
||||
}
|
||||
|
||||
headers := make(map[string]string)
|
||||
headers["Content-Type"] = "application/x-www-form-urlencoded"
|
||||
headers["Key"] = p.APIKey
|
||||
|
||||
n := p.Requester.GetNonce(true).String()
|
||||
|
||||
values.Set("nonce", n)
|
||||
values.Set("nonce", p.Requester.GetNonce(true).String())
|
||||
values.Set("command", endpoint)
|
||||
|
||||
hmac := common.GetHMAC(common.HashSHA512,
|
||||
@@ -926,7 +915,8 @@ func (p *Poloniex) SendAuthenticatedHTTPRequest(method, endpoint string, values
|
||||
true,
|
||||
true,
|
||||
p.Verbose,
|
||||
p.HTTPDebugging)
|
||||
p.HTTPDebugging,
|
||||
p.HTTPRecording)
|
||||
}
|
||||
|
||||
// GetFee returns an estimate of fee based on type of transaction
|
||||
|
||||
32
exchanges/poloniex/poloniex_live_test.go
Normal file
32
exchanges/poloniex/poloniex_live_test.go
Normal file
@@ -0,0 +1,32 @@
|
||||
//+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 poloniex
|
||||
|
||||
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")
|
||||
poloniexConfig, err := cfg.GetExchangeConfig("Poloniex")
|
||||
if err != nil {
|
||||
log.Fatal("Test Failed - Poloniex Setup() init error", err)
|
||||
}
|
||||
poloniexConfig.AuthenticatedAPISupport = true
|
||||
poloniexConfig.APIKey = apiKey
|
||||
poloniexConfig.APISecret = apiSecret
|
||||
p.SetDefaults()
|
||||
p.Setup(&poloniexConfig)
|
||||
log.Printf(sharedtestvalues.LiveTesting, p.GetName(), p.APIUrl)
|
||||
os.Exit(m.Run())
|
||||
}
|
||||
44
exchanges/poloniex/poloniex_mock_test.go
Normal file
44
exchanges/poloniex/poloniex_mock_test.go
Normal file
@@ -0,0 +1,44 @@
|
||||
//+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 poloniex
|
||||
|
||||
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/poloniex/poloniex.json"
|
||||
|
||||
var mockTests = true
|
||||
|
||||
func TestMain(m *testing.M) {
|
||||
cfg := config.GetConfig()
|
||||
cfg.LoadConfig("../../testdata/configtest.json")
|
||||
poloniexConfig, err := cfg.GetExchangeConfig("Poloniex")
|
||||
if err != nil {
|
||||
log.Fatal("Test Failed - Poloniex Setup() init error", err)
|
||||
}
|
||||
poloniexConfig.AuthenticatedAPISupport = true
|
||||
poloniexConfig.APIKey = apiKey
|
||||
poloniexConfig.APISecret = apiSecret
|
||||
p.SetDefaults()
|
||||
p.Setup(&poloniexConfig)
|
||||
|
||||
serverDetails, newClient, err := mock.NewVCRServer(mockfile)
|
||||
if err != nil {
|
||||
log.Fatalf("Test Failed - Mock server error %s", err)
|
||||
}
|
||||
|
||||
p.HTTPClient = newClient
|
||||
p.APIUrl = serverDetails
|
||||
|
||||
log.Printf(sharedtestvalues.MockTesting, p.GetName(), p.APIUrl)
|
||||
os.Exit(m.Run())
|
||||
}
|
||||
@@ -7,15 +7,12 @@ import (
|
||||
|
||||
"github.com/gorilla/websocket"
|
||||
"github.com/thrasher-corp/gocryptotrader/common"
|
||||
"github.com/thrasher-corp/gocryptotrader/config"
|
||||
"github.com/thrasher-corp/gocryptotrader/currency"
|
||||
exchange "github.com/thrasher-corp/gocryptotrader/exchanges"
|
||||
"github.com/thrasher-corp/gocryptotrader/exchanges/sharedtestvalues"
|
||||
"github.com/thrasher-corp/gocryptotrader/exchanges/websocket/wshandler"
|
||||
)
|
||||
|
||||
var p Poloniex
|
||||
|
||||
// Please supply your own APIKEYS here for due diligence testing
|
||||
const (
|
||||
apiKey = ""
|
||||
@@ -23,31 +20,21 @@ const (
|
||||
canManipulateRealOrders = false
|
||||
)
|
||||
|
||||
var isSetup bool
|
||||
var p Poloniex
|
||||
|
||||
func TestSetup(t *testing.T) {
|
||||
if !isSetup {
|
||||
cfg := config.GetConfig()
|
||||
cfg.LoadConfig("../../testdata/configtest.json")
|
||||
poloniexConfig, err := cfg.GetExchangeConfig("Poloniex")
|
||||
if err != nil {
|
||||
t.Error("Test Failed - Poloniex Setup() init error")
|
||||
}
|
||||
poloniexConfig.AuthenticatedWebsocketAPISupport = true
|
||||
poloniexConfig.AuthenticatedAPISupport = true
|
||||
poloniexConfig.APIKey = apiKey
|
||||
poloniexConfig.APISecret = apiSecret
|
||||
p.SetDefaults()
|
||||
p.Setup(&poloniexConfig)
|
||||
isSetup = true
|
||||
func areTestAPIKeysSet() bool {
|
||||
if p.APIKey != "" && p.APIKey != "Key" &&
|
||||
p.APISecret != "" && p.APISecret != "Secret" {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func TestGetTicker(t *testing.T) {
|
||||
t.Parallel()
|
||||
_, err := p.GetTicker()
|
||||
if err != nil {
|
||||
t.Error("Test faild - Poloniex GetTicker() error")
|
||||
t.Error("Test Failed - Poloniex GetTicker() error", err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -115,37 +102,43 @@ func setFeeBuilder() *exchange.FeeBuilder {
|
||||
// TestGetFeeByTypeOfflineTradeFee logic test
|
||||
func TestGetFeeByTypeOfflineTradeFee(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
var feeBuilder = setFeeBuilder()
|
||||
p.GetFeeByType(feeBuilder)
|
||||
if apiKey == "" || apiSecret == "" {
|
||||
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) {
|
||||
t.Parallel()
|
||||
TestSetup(t)
|
||||
var feeBuilder = setFeeBuilder()
|
||||
|
||||
if areTestAPIKeysSet() {
|
||||
if areTestAPIKeysSet() || mockTests {
|
||||
// CryptocurrencyTradeFee Basic
|
||||
if resp, err := p.GetFee(feeBuilder); resp != float64(0.002) || err != nil {
|
||||
if resp, err := p.GetFee(feeBuilder); resp != float64(0.0025) || err != nil {
|
||||
t.Error(err)
|
||||
t.Errorf("Test Failed - GetFee() error. Expected: %f, Received: %f", float64(0.0015), resp)
|
||||
t.Errorf("Test Failed - GetFee() error. Expected: %f, Received: %f",
|
||||
float64(0.0025), resp)
|
||||
}
|
||||
|
||||
// CryptocurrencyTradeFee High quantity
|
||||
feeBuilder = setFeeBuilder()
|
||||
feeBuilder.Amount = 1000
|
||||
feeBuilder.PurchasePrice = 1000
|
||||
if resp, err := p.GetFee(feeBuilder); resp != float64(2000) || err != nil {
|
||||
t.Errorf("Test Failed - GetFee() error. Expected: %f, Received: %f", float64(2000), resp)
|
||||
if resp, err := p.GetFee(feeBuilder); resp != float64(2500) || err != nil {
|
||||
t.Errorf("Test Failed - GetFee() error. Expected: %f, Received: %f",
|
||||
float64(2500), resp)
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
@@ -153,7 +146,8 @@ func TestGetFee(t *testing.T) {
|
||||
feeBuilder = setFeeBuilder()
|
||||
feeBuilder.PurchasePrice = -1000
|
||||
if resp, err := p.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)
|
||||
}
|
||||
}
|
||||
@@ -161,7 +155,8 @@ func TestGetFee(t *testing.T) {
|
||||
feeBuilder = setFeeBuilder()
|
||||
feeBuilder.FeeType = exchange.CryptocurrencyWithdrawalFee
|
||||
if resp, err := p.GetFee(feeBuilder); resp != float64(0.001) || err != nil {
|
||||
t.Errorf("Test Failed - GetFee() error. Expected: %f, Received: %f", float64(0.001), resp)
|
||||
t.Errorf("Test Failed - GetFee() error. Expected: %f, Received: %f",
|
||||
float64(0.001), resp)
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
@@ -170,7 +165,8 @@ func TestGetFee(t *testing.T) {
|
||||
feeBuilder.Pair.Base = currency.NewCode("hello")
|
||||
feeBuilder.FeeType = exchange.CryptocurrencyWithdrawalFee
|
||||
if resp, err := p.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)
|
||||
}
|
||||
|
||||
@@ -178,7 +174,8 @@ func TestGetFee(t *testing.T) {
|
||||
feeBuilder = setFeeBuilder()
|
||||
feeBuilder.FeeType = exchange.CyptocurrencyDepositFee
|
||||
if resp, err := p.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)
|
||||
}
|
||||
|
||||
@@ -186,7 +183,8 @@ func TestGetFee(t *testing.T) {
|
||||
feeBuilder = setFeeBuilder()
|
||||
feeBuilder.FeeType = exchange.InternationalBankDepositFee
|
||||
if resp, err := p.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)
|
||||
}
|
||||
|
||||
@@ -195,70 +193,67 @@ func TestGetFee(t *testing.T) {
|
||||
feeBuilder.FeeType = exchange.InternationalBankWithdrawalFee
|
||||
feeBuilder.FiatCurrency = currency.USD
|
||||
if resp, err := p.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)
|
||||
}
|
||||
}
|
||||
|
||||
func TestFormatWithdrawPermissions(t *testing.T) {
|
||||
t.Parallel()
|
||||
TestSetup(t)
|
||||
expectedResult := exchange.AutoWithdrawCryptoWithAPIPermissionText + " & " + exchange.NoFiatWithdrawalsText
|
||||
expectedResult := exchange.AutoWithdrawCryptoWithAPIPermissionText +
|
||||
" & " +
|
||||
exchange.NoFiatWithdrawalsText
|
||||
|
||||
withdrawPermissions := p.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) {
|
||||
t.Parallel()
|
||||
TestSetup(t)
|
||||
|
||||
var getOrdersRequest = exchange.GetOrdersRequest{
|
||||
OrderType: exchange.AnyOrderType,
|
||||
}
|
||||
|
||||
_, err := p.GetActiveOrders(&getOrdersRequest)
|
||||
if areTestAPIKeysSet() && err != nil {
|
||||
t.Errorf("Could not get open orders: %s", err)
|
||||
} else if !areTestAPIKeysSet() && err == nil {
|
||||
t.Error("Expecting an error when no keys are set")
|
||||
switch {
|
||||
case areTestAPIKeysSet() && err != nil:
|
||||
t.Error("Test Failed - GetActiveOrders() error", err)
|
||||
case !areTestAPIKeysSet() && !mockTests && err == nil:
|
||||
t.Error("Test Failed - Expecting an error when no keys are set")
|
||||
case mockTests && err != nil:
|
||||
t.Error("Test Failed - Mock GetActiveOrders() err", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetOrderHistory(t *testing.T) {
|
||||
t.Parallel()
|
||||
TestSetup(t)
|
||||
|
||||
var getOrdersRequest = exchange.GetOrdersRequest{
|
||||
OrderType: exchange.AnyOrderType,
|
||||
}
|
||||
|
||||
_, err := p.GetOrderHistory(&getOrdersRequest)
|
||||
if areTestAPIKeysSet() && err != nil {
|
||||
switch {
|
||||
case areTestAPIKeysSet() && err != nil:
|
||||
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 mock 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 p.APIKey != "" && p.APIKey != "Key" &&
|
||||
p.APISecret != "" && p.APISecret != "Secret" {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func TestSubmitOrder(t *testing.T) {
|
||||
t.Parallel()
|
||||
TestSetup(t)
|
||||
|
||||
if areTestAPIKeysSet() && !canManipulateRealOrders {
|
||||
if areTestAPIKeysSet() && !canManipulateRealOrders && !mockTests {
|
||||
t.Skip("API keys set, canManipulateRealOrders false, skipping test")
|
||||
}
|
||||
|
||||
@@ -274,46 +269,43 @@ func TestSubmitOrder(t *testing.T) {
|
||||
1,
|
||||
10,
|
||||
"hi")
|
||||
|
||||
if areTestAPIKeysSet() && (err != nil || !response.IsOrderPlaced) {
|
||||
switch {
|
||||
case areTestAPIKeysSet() && (err != nil || !response.IsOrderPlaced):
|
||||
t.Errorf("Order failed to be placed: %v", err)
|
||||
} else if !areTestAPIKeysSet() && err == nil {
|
||||
case !areTestAPIKeysSet() && !mockTests && err == nil:
|
||||
t.Error("Expecting an error when no keys are set")
|
||||
case mockTests && err != nil:
|
||||
t.Error("Test Failed - Mock SubmitOrder() err", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCancelExchangeOrder(t *testing.T) {
|
||||
t.Parallel()
|
||||
TestSetup(t)
|
||||
|
||||
if areTestAPIKeysSet() && !canManipulateRealOrders {
|
||||
if areTestAPIKeysSet() && !canManipulateRealOrders && !mockTests {
|
||||
t.Skip("API keys set, canManipulateRealOrders false, skipping test")
|
||||
}
|
||||
|
||||
currencyPair := currency.NewPair(currency.LTC, currency.BTC)
|
||||
|
||||
var orderCancellation = &exchange.OrderCancellation{
|
||||
OrderID: "1",
|
||||
WalletAddress: "1F5zVDgNjorJ51oGebSvNCrSAHpwGkUdDB",
|
||||
AccountID: "1",
|
||||
CurrencyPair: currencyPair,
|
||||
CurrencyPair: currency.NewPair(currency.LTC, currency.BTC),
|
||||
}
|
||||
|
||||
err := p.CancelOrder(orderCancellation)
|
||||
|
||||
if !areTestAPIKeysSet() && err == nil {
|
||||
switch {
|
||||
case !areTestAPIKeysSet() && !mockTests && err == nil:
|
||||
t.Error("Expecting an error when no keys are set")
|
||||
}
|
||||
if areTestAPIKeysSet() && err != nil {
|
||||
case areTestAPIKeysSet() && err != nil:
|
||||
t.Errorf("Could not cancel orders: %v", err)
|
||||
case mockTests && err != nil:
|
||||
t.Error("Test Failed - Mock CancelExchangeOrder() err", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCancelAllExchangeOrders(t *testing.T) {
|
||||
t.Parallel()
|
||||
TestSetup(t)
|
||||
|
||||
if areTestAPIKeysSet() && !canManipulateRealOrders {
|
||||
if areTestAPIKeysSet() && !canManipulateRealOrders && !mockTests {
|
||||
t.Skip("API keys set, canManipulateRealOrders false, skipping test")
|
||||
}
|
||||
|
||||
@@ -327,14 +319,14 @@ func TestCancelAllExchangeOrders(t *testing.T) {
|
||||
}
|
||||
|
||||
resp, err := p.CancelAllOrders(orderCancellation)
|
||||
|
||||
if !areTestAPIKeysSet() && err == nil {
|
||||
switch {
|
||||
case !areTestAPIKeysSet() && !mockTests && err == nil:
|
||||
t.Error("Expecting an error when no keys are set")
|
||||
}
|
||||
if areTestAPIKeysSet() && err != nil {
|
||||
case areTestAPIKeysSet() && err != nil:
|
||||
t.Errorf("Could not cancel orders: %v", err)
|
||||
case mockTests && err != nil:
|
||||
t.Error("Test Failed - Mock CancelAllExchangeOrders() err", err)
|
||||
}
|
||||
|
||||
if len(resp.OrderStatus) > 0 {
|
||||
t.Errorf("%v orders failed to cancel", len(resp.OrderStatus))
|
||||
}
|
||||
@@ -342,87 +334,88 @@ func TestCancelAllExchangeOrders(t *testing.T) {
|
||||
|
||||
func TestModifyOrder(t *testing.T) {
|
||||
t.Parallel()
|
||||
if areTestAPIKeysSet() && !canManipulateRealOrders && !mockTests {
|
||||
t.Skip("API keys set, canManipulateRealOrders false, skipping test")
|
||||
}
|
||||
|
||||
_, err := p.ModifyOrder(&exchange.ModifyOrder{OrderID: "1337", Price: 1337})
|
||||
if err == nil {
|
||||
t.Error("Test Failed - ModifyOrder() error")
|
||||
switch {
|
||||
case areTestAPIKeysSet() && err != nil && mockTests:
|
||||
t.Error("Test Failed - ModifyOrder() error", err)
|
||||
case !areTestAPIKeysSet() && !mockTests && err == nil:
|
||||
t.Error("Test Failed - ModifyOrder() error cannot be nil")
|
||||
case mockTests && err != nil:
|
||||
t.Error("Test Failed - Mock ModifyOrder() err", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestWithdraw(t *testing.T) {
|
||||
t.Parallel()
|
||||
TestSetup(t)
|
||||
var withdrawCryptoRequest = exchange.WithdrawRequest{
|
||||
Amount: 100,
|
||||
Amount: 0,
|
||||
Currency: currency.LTC,
|
||||
Address: "1F5zVDgNjorJ51oGebSvNCrSAHpwGkUdDB",
|
||||
Description: "WITHDRAW IT ALL",
|
||||
}
|
||||
|
||||
if areTestAPIKeysSet() && !canManipulateRealOrders {
|
||||
if areTestAPIKeysSet() && !canManipulateRealOrders && !mockTests {
|
||||
t.Skip("API keys set, canManipulateRealOrders false, skipping test")
|
||||
}
|
||||
|
||||
_, err := p.WithdrawCryptocurrencyFunds(&withdrawCryptoRequest)
|
||||
if !areTestAPIKeysSet() && err == nil {
|
||||
t.Error("Expecting an error when no keys are set")
|
||||
}
|
||||
if areTestAPIKeysSet() && err != nil {
|
||||
switch {
|
||||
case areTestAPIKeysSet() && err != nil:
|
||||
t.Errorf("Withdraw failed to be placed: %v", err)
|
||||
case !areTestAPIKeysSet() && !mockTests && err == nil:
|
||||
t.Error("Expecting an error when no keys are set")
|
||||
case mockTests && err != nil:
|
||||
t.Error("Test Failed - Mock Withdraw() err", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestWithdrawFiat(t *testing.T) {
|
||||
t.Parallel()
|
||||
TestSetup(t)
|
||||
|
||||
if areTestAPIKeysSet() && !canManipulateRealOrders {
|
||||
if areTestAPIKeysSet() && !canManipulateRealOrders && !mockTests {
|
||||
t.Skip("API keys set, canManipulateRealOrders false, skipping test")
|
||||
}
|
||||
|
||||
var withdrawFiatRequest = exchange.WithdrawRequest{}
|
||||
|
||||
var withdrawFiatRequest exchange.WithdrawRequest
|
||||
_, err := p.WithdrawFiatFunds(&withdrawFiatRequest)
|
||||
if err != common.ErrFunctionNotSupported {
|
||||
t.Errorf("Expected '%v', received: '%v'", common.ErrFunctionNotSupported, err)
|
||||
t.Errorf("Expected '%v', received: '%v'",
|
||||
common.ErrFunctionNotSupported, err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestWithdrawInternationalBank(t *testing.T) {
|
||||
t.Parallel()
|
||||
TestSetup(t)
|
||||
|
||||
if areTestAPIKeysSet() && !canManipulateRealOrders {
|
||||
if areTestAPIKeysSet() && !canManipulateRealOrders && !mockTests {
|
||||
t.Skip("API keys set, canManipulateRealOrders false, skipping test")
|
||||
}
|
||||
|
||||
var withdrawFiatRequest = exchange.WithdrawRequest{}
|
||||
|
||||
var withdrawFiatRequest exchange.WithdrawRequest
|
||||
_, err := p.WithdrawFiatFundsToInternationalBank(&withdrawFiatRequest)
|
||||
if err != common.ErrFunctionNotSupported {
|
||||
t.Errorf("Expected '%v', received: '%v'", common.ErrFunctionNotSupported, err)
|
||||
t.Errorf("Expected '%v', received: '%v'",
|
||||
common.ErrFunctionNotSupported, err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetDepositAddress(t *testing.T) {
|
||||
t.Parallel()
|
||||
TestSetup(t)
|
||||
|
||||
if areTestAPIKeysSet() {
|
||||
_, err := p.GetDepositAddress(currency.DASH, "")
|
||||
if err != nil {
|
||||
t.Error("Test Failed - GetDepositAddress()", err)
|
||||
}
|
||||
} else {
|
||||
_, err := p.GetDepositAddress(currency.DASH, "")
|
||||
if err == nil {
|
||||
t.Error("Test Failed - GetDepositAddress()")
|
||||
}
|
||||
_, err := p.GetDepositAddress(currency.DASH, "")
|
||||
switch {
|
||||
case areTestAPIKeysSet() && err != nil:
|
||||
t.Error("Test Failed - GetDepositAddress()", err)
|
||||
case !areTestAPIKeysSet() && !mockTests && err == nil:
|
||||
t.Error("Test Failed - GetDepositAddress() cannot be nil")
|
||||
case mockTests && err != nil:
|
||||
t.Error("Test Failed - Mock GetDepositAddress() err", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestWsHandleAccountData(t *testing.T) {
|
||||
t.Parallel()
|
||||
TestSetup(t)
|
||||
p.Websocket.DataHandler = sharedtestvalues.GetWebsocketInterfaceChannelOverride()
|
||||
jsons := []string{
|
||||
`[["n",225,807230187,0,"1000.00000000","0.10000000","2018-11-07 16:42:42"],["b",267,"e","-0.10000000"]]`,
|
||||
@@ -442,7 +435,7 @@ func TestWsHandleAccountData(t *testing.T) {
|
||||
// TestWsAuth dials websocket, sends login request.
|
||||
// Will receive a message only on failure
|
||||
func TestWsAuth(t *testing.T) {
|
||||
TestSetup(t)
|
||||
t.Parallel()
|
||||
if !p.Websocket.IsEnabled() && !p.AuthenticatedWebsocketAPISupport || !areTestAPIKeysSet() {
|
||||
t.Skip(wshandler.WebsocketNotEnabled)
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/thrasher-corp/gocryptotrader/common"
|
||||
"github.com/thrasher-corp/gocryptotrader/exchanges/mock"
|
||||
"github.com/thrasher-corp/gocryptotrader/exchanges/nonce"
|
||||
log "github.com/thrasher-corp/gocryptotrader/logger"
|
||||
)
|
||||
@@ -70,6 +71,7 @@ type Job struct {
|
||||
AuthRequest bool
|
||||
Verbose bool
|
||||
HTTPDebugging bool
|
||||
Record bool
|
||||
}
|
||||
|
||||
// NewRateLimit creates a new RateLimit
|
||||
@@ -264,13 +266,18 @@ func (r *Requester) checkRequest(method, path string, body io.Reader, headers ma
|
||||
}
|
||||
|
||||
// DoRequest performs a HTTP/HTTPS request with the supplied params
|
||||
func (r *Requester) DoRequest(req *http.Request, path string, body io.Reader, result interface{}, authRequest, verbose, httpDebug bool) error {
|
||||
func (r *Requester) DoRequest(req *http.Request, path string, body io.Reader, result interface{}, authRequest, verbose, httpDebug, httpRecord bool) error {
|
||||
if verbose {
|
||||
log.Debugf("%s exchange request path: %s requires rate limiter: %v", r.Name, path, r.RequiresRateLimiter())
|
||||
log.Debugf("%s exchange request path: %s requires rate limiter: %v",
|
||||
r.Name,
|
||||
path,
|
||||
r.RequiresRateLimiter())
|
||||
|
||||
for k, d := range req.Header {
|
||||
log.Debugf("%s exchange request header [%s]: %s", r.Name, k, d)
|
||||
}
|
||||
log.Debug(body)
|
||||
log.Debugf("%s exchange request type: %s", r.Name, req.Method)
|
||||
log.Debugf("%s exchange request body: %v", r.Name, body)
|
||||
}
|
||||
|
||||
var timeoutError error
|
||||
@@ -328,6 +335,14 @@ func (r *Requester) DoRequest(req *http.Request, path string, body io.Reader, re
|
||||
return err
|
||||
}
|
||||
|
||||
if httpRecord {
|
||||
// This dumps http responses for future mocking implementations
|
||||
err = mock.HTTPRecord(resp, r.Name, contents)
|
||||
if err != nil {
|
||||
return fmt.Errorf("mock recording failure %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
if resp.StatusCode != 200 && resp.StatusCode != 201 && resp.StatusCode != 202 {
|
||||
err = fmt.Errorf("unsuccessful HTTP status code: %d", resp.StatusCode)
|
||||
if verbose {
|
||||
@@ -371,7 +386,7 @@ func (r *Requester) worker() {
|
||||
if !r.IsRateLimited(x.AuthRequest) {
|
||||
r.IncrementRequests(x.AuthRequest)
|
||||
|
||||
err := r.DoRequest(x.Request, x.Path, x.Body, x.Result, x.AuthRequest, x.Verbose, x.HTTPDebugging)
|
||||
err := r.DoRequest(x.Request, x.Path, x.Body, x.Result, x.AuthRequest, x.Verbose, x.HTTPDebugging, x.Record)
|
||||
x.JobResult <- &JobResult{
|
||||
Error: err,
|
||||
Result: x.Result,
|
||||
@@ -395,7 +410,7 @@ func (r *Requester) worker() {
|
||||
log.Debugf("%s request. No longer rate limited! Doing request", r.Name)
|
||||
}
|
||||
|
||||
err := r.DoRequest(x.Request, x.Path, x.Body, x.Result, x.AuthRequest, x.Verbose, x.HTTPDebugging)
|
||||
err := r.DoRequest(x.Request, x.Path, x.Body, x.Result, x.AuthRequest, x.Verbose, x.HTTPDebugging, x.Record)
|
||||
x.JobResult <- &JobResult{
|
||||
Error: err,
|
||||
Result: x.Result,
|
||||
@@ -408,7 +423,7 @@ func (r *Requester) worker() {
|
||||
}
|
||||
|
||||
// SendPayload handles sending HTTP/HTTPS requests
|
||||
func (r *Requester) SendPayload(method, path string, headers map[string]string, body io.Reader, result interface{}, authRequest, nonceEnabled, verbose, httpDebugging bool) error {
|
||||
func (r *Requester) SendPayload(method, path string, headers map[string]string, body io.Reader, result interface{}, authRequest, nonceEnabled, verbose, httpDebugging, record bool) error {
|
||||
if !nonceEnabled {
|
||||
r.lock()
|
||||
}
|
||||
@@ -444,7 +459,7 @@ func (r *Requester) SendPayload(method, path string, headers map[string]string,
|
||||
|
||||
if !r.RequiresRateLimiter() {
|
||||
r.unlock()
|
||||
return r.DoRequest(req, path, body, result, authRequest, verbose, httpDebugging)
|
||||
return r.DoRequest(req, path, body, result, authRequest, verbose, httpDebugging, record)
|
||||
}
|
||||
|
||||
if len(r.Jobs) == maxRequestJobs {
|
||||
@@ -473,6 +488,7 @@ func (r *Requester) SendPayload(method, path string, headers map[string]string,
|
||||
AuthRequest: authRequest,
|
||||
Verbose: verbose,
|
||||
HTTPDebugging: httpDebugging,
|
||||
Record: record,
|
||||
}
|
||||
|
||||
if verbose {
|
||||
|
||||
@@ -200,7 +200,7 @@ func TestCheckRequest(t *testing.T) {
|
||||
|
||||
func TestDoRequest(t *testing.T) {
|
||||
var test = new(Requester)
|
||||
err := test.SendPayload(http.MethodGet, "https://www.google.com", nil, nil, nil, false, false, true, false)
|
||||
err := test.SendPayload(http.MethodGet, "https://www.google.com", nil, nil, nil, false, false, true, false, false)
|
||||
if err == nil {
|
||||
t.Fatal("not iniitalised")
|
||||
}
|
||||
@@ -211,17 +211,17 @@ func TestDoRequest(t *testing.T) {
|
||||
}
|
||||
|
||||
r.Name = "bitfinex"
|
||||
err = r.SendPayload("BLAH", "https://www.google.com", nil, nil, nil, false, false, true, false)
|
||||
err = r.SendPayload("BLAH", "https://www.google.com", nil, nil, nil, false, false, true, false, false)
|
||||
if err == nil {
|
||||
t.Fatal("unexpected values")
|
||||
}
|
||||
|
||||
err = r.SendPayload(http.MethodGet, "", nil, nil, nil, false, false, true, false)
|
||||
err = r.SendPayload(http.MethodGet, "", nil, nil, nil, false, false, true, false, false)
|
||||
if err == nil {
|
||||
t.Fatal("unexpected values")
|
||||
}
|
||||
|
||||
err = r.SendPayload(http.MethodGet, "https://www.google.com", nil, nil, nil, false, false, true, false)
|
||||
err = r.SendPayload(http.MethodGet, "https://www.google.com", nil, nil, nil, false, false, true, false, false)
|
||||
if err != nil {
|
||||
t.Fatal("unexpected values")
|
||||
}
|
||||
@@ -233,7 +233,7 @@ func TestDoRequest(t *testing.T) {
|
||||
r.SetRateLimit(false, time.Second, 0)
|
||||
r.SetRateLimit(true, time.Second, 0)
|
||||
|
||||
err = r.SendPayload(http.MethodGet, "https://www.google.com", nil, nil, nil, false, false, true, false)
|
||||
err = r.SendPayload(http.MethodGet, "https://www.google.com", nil, nil, nil, false, false, true, false, false)
|
||||
if err != nil {
|
||||
t.Fatal("unexpected values")
|
||||
}
|
||||
@@ -250,7 +250,7 @@ func TestDoRequest(t *testing.T) {
|
||||
t.Fatal("unexepcted values")
|
||||
}
|
||||
|
||||
err = r.SendPayload(http.MethodGet, "https://www.google.com", nil, nil, nil, false, false, true, false)
|
||||
err = r.SendPayload(http.MethodGet, "https://www.google.com", nil, nil, nil, false, false, true, false, false)
|
||||
if err != nil {
|
||||
t.Fatal("unexpected values")
|
||||
}
|
||||
@@ -261,27 +261,27 @@ func TestDoRequest(t *testing.T) {
|
||||
t.Fatal("unexepcted values")
|
||||
}
|
||||
|
||||
err = r.SendPayload(http.MethodGet, "https://www.google.com", nil, nil, nil, true, false, true, false)
|
||||
err = r.SendPayload(http.MethodGet, "https://www.google.com", nil, nil, nil, true, false, true, false, false)
|
||||
if err != nil {
|
||||
t.Fatal("unexpected values")
|
||||
}
|
||||
|
||||
var result interface{}
|
||||
err = r.SendPayload(http.MethodGet, "https://www.google.com", nil, nil, result, false, false, true, false)
|
||||
err = r.SendPayload(http.MethodGet, "https://www.google.com", nil, nil, result, false, false, true, false, false)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
headers := make(map[string]string)
|
||||
headers["content-type"] = "content/text"
|
||||
err = r.SendPayload(http.MethodPost, "https://bitfinex.com", headers, nil, result, false, false, true, false)
|
||||
err = r.SendPayload(http.MethodPost, "https://bitfinex.com", headers, nil, result, false, false, true, false, false)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
r.StartCycle()
|
||||
r.UnauthLimit.SetRequests(100)
|
||||
err = r.SendPayload(http.MethodGet, "https://www.google.com", nil, nil, result, false, false, false, false)
|
||||
err = r.SendPayload(http.MethodGet, "https://www.google.com", nil, nil, result, false, false, false, false, false)
|
||||
if err != nil {
|
||||
t.Fatal("unexpected values")
|
||||
}
|
||||
@@ -297,7 +297,7 @@ func TestDoRequest(t *testing.T) {
|
||||
}
|
||||
|
||||
r.HTTPClient.Timeout = 1 * time.Second
|
||||
err = r.SendPayload(http.MethodPost, "https://httpstat.us/200?sleep=20000", nil, nil, nil, false, false, true, false)
|
||||
err = r.SendPayload(http.MethodPost, "https://httpstat.us/200?sleep=20000", nil, nil, nil, false, false, true, false, false)
|
||||
if err == nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -327,6 +327,6 @@ func BenchmarkRequestLockMech(b *testing.B) {
|
||||
var r = new(Requester)
|
||||
var meep interface{}
|
||||
for n := 0; n < b.N; n++ {
|
||||
r.SendPayload(http.MethodGet, "127.0.0.1", nil, nil, &meep, false, false, false, false)
|
||||
r.SendPayload(http.MethodGet, "127.0.0.1", nil, nil, &meep, false, false, false, false, false)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,6 +13,9 @@ const (
|
||||
// WebsocketChannelOverrideCapacity used in websocket testing
|
||||
// Defines channel capacity as defaults size can block tests
|
||||
WebsocketChannelOverrideCapacity = 20
|
||||
|
||||
MockTesting = "Mock testing framework in use for %s exchange @ %s on REST endpoints only"
|
||||
LiveTesting = "Mock testing bypassed; live testing of REST endpoints in use for %s exchange @ %s"
|
||||
)
|
||||
|
||||
// GetWebsocketInterfaceChannelOverride returns a new interface based channel
|
||||
|
||||
@@ -340,7 +340,8 @@ func (y *Yobit) SendHTTPRequest(path string, result interface{}) error {
|
||||
false,
|
||||
false,
|
||||
y.Verbose,
|
||||
y.HTTPDebugging)
|
||||
y.HTTPDebugging,
|
||||
y.HTTPRecording)
|
||||
}
|
||||
|
||||
// SendAuthenticatedHTTPRequest sends an authenticated HTTP request to Yobit
|
||||
@@ -384,7 +385,8 @@ func (y *Yobit) SendAuthenticatedHTTPRequest(path string, params url.Values, res
|
||||
true,
|
||||
true,
|
||||
y.Verbose,
|
||||
y.HTTPDebugging)
|
||||
y.HTTPDebugging,
|
||||
y.HTTPRecording)
|
||||
}
|
||||
|
||||
// GetFee returns an estimate of fee based on type of transaction
|
||||
|
||||
@@ -391,7 +391,16 @@ func (z *ZB) GetCryptoAddress(currency currency.Code) (UserAddress, error) {
|
||||
|
||||
// SendHTTPRequest sends an unauthenticated HTTP request
|
||||
func (z *ZB) SendHTTPRequest(path string, result interface{}) error {
|
||||
return z.SendPayload(http.MethodGet, path, nil, nil, result, false, false, z.Verbose, z.HTTPDebugging)
|
||||
return z.SendPayload(http.MethodGet,
|
||||
path,
|
||||
nil,
|
||||
nil,
|
||||
result,
|
||||
false,
|
||||
false,
|
||||
z.Verbose,
|
||||
z.HTTPDebugging,
|
||||
z.HTTPRecording)
|
||||
}
|
||||
|
||||
// SendAuthenticatedHTTPRequest sends authenticated requests to the zb API
|
||||
@@ -429,7 +438,8 @@ func (z *ZB) SendAuthenticatedHTTPRequest(httpMethod string, params url.Values,
|
||||
true,
|
||||
false,
|
||||
z.Verbose,
|
||||
z.HTTPDebugging)
|
||||
z.HTTPDebugging,
|
||||
z.HTTPRecording)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
2404
testdata/http_mock/anx/anx.json
vendored
Normal file
2404
testdata/http_mock/anx/anx.json
vendored
Normal file
File diff suppressed because it is too large
Load Diff
45467
testdata/http_mock/binance/binance.json
vendored
Normal file
45467
testdata/http_mock/binance/binance.json
vendored
Normal file
File diff suppressed because it is too large
Load Diff
42842
testdata/http_mock/bitstamp/bitstamp.json
vendored
Normal file
42842
testdata/http_mock/bitstamp/bitstamp.json
vendored
Normal file
File diff suppressed because it is too large
Load Diff
19
testdata/http_mock/exclusion.json
vendored
Executable file
19
testdata/http_mock/exclusion.json
vendored
Executable file
@@ -0,0 +1,19 @@
|
||||
{
|
||||
"headers": [
|
||||
"Key",
|
||||
"X-Mbx-Apikey",
|
||||
"Rest-Key",
|
||||
"Apiauth-Key",
|
||||
"X-Gemini-Apikey"
|
||||
],
|
||||
"variables": [
|
||||
"bsb",
|
||||
"user",
|
||||
"name",
|
||||
"real_name",
|
||||
"receiver_name",
|
||||
"account_number",
|
||||
"username",
|
||||
"login"
|
||||
]
|
||||
}
|
||||
2734
testdata/http_mock/gemini/gemini.json
vendored
Normal file
2734
testdata/http_mock/gemini/gemini.json
vendored
Normal file
File diff suppressed because it is too large
Load Diff
3400
testdata/http_mock/localbitcoins/localbitcoins.json
vendored
Normal file
3400
testdata/http_mock/localbitcoins/localbitcoins.json
vendored
Normal file
File diff suppressed because it is too large
Load Diff
9031
testdata/http_mock/poloniex/poloniex.json
vendored
Normal file
9031
testdata/http_mock/poloniex/poloniex.json
vendored
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user