mirror of
https://github.com/d0zingcat/gocryptotrader.git
synced 2026-05-13 23:16:45 +00:00
* Fix path issue for GetFills and GetOrders * Address nit and centralise test pair for user convenience
1022 lines
26 KiB
Go
1022 lines
26 KiB
Go
package coinbasepro
|
|
|
|
import (
|
|
"log"
|
|
"net/http"
|
|
"os"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/gorilla/websocket"
|
|
"github.com/thrasher-corp/gocryptotrader/common"
|
|
"github.com/thrasher-corp/gocryptotrader/common/convert"
|
|
"github.com/thrasher-corp/gocryptotrader/config"
|
|
"github.com/thrasher-corp/gocryptotrader/core"
|
|
"github.com/thrasher-corp/gocryptotrader/currency"
|
|
exchange "github.com/thrasher-corp/gocryptotrader/exchanges"
|
|
"github.com/thrasher-corp/gocryptotrader/exchanges/asset"
|
|
"github.com/thrasher-corp/gocryptotrader/exchanges/kline"
|
|
"github.com/thrasher-corp/gocryptotrader/exchanges/order"
|
|
"github.com/thrasher-corp/gocryptotrader/exchanges/sharedtestvalues"
|
|
"github.com/thrasher-corp/gocryptotrader/exchanges/stream"
|
|
"github.com/thrasher-corp/gocryptotrader/portfolio/banking"
|
|
"github.com/thrasher-corp/gocryptotrader/portfolio/withdraw"
|
|
)
|
|
|
|
var (
|
|
c CoinbasePro
|
|
testPair = currency.NewPairWithDelimiter(currency.BTC.String(), currency.USD.String(), "-")
|
|
)
|
|
|
|
// Please supply your APIKeys here for better testing
|
|
const (
|
|
apiKey = ""
|
|
apiSecret = ""
|
|
clientID = "" // passphrase you made at API CREATION
|
|
canManipulateRealOrders = false
|
|
)
|
|
|
|
func TestMain(m *testing.M) {
|
|
c.SetDefaults()
|
|
cfg := config.GetConfig()
|
|
err := cfg.LoadConfig("../../testdata/configtest.json", true)
|
|
if err != nil {
|
|
log.Fatal("coinbasepro load config error", err)
|
|
}
|
|
gdxConfig, err := cfg.GetExchangeConfig("CoinbasePro")
|
|
if err != nil {
|
|
log.Fatal("coinbasepro Setup() init error")
|
|
}
|
|
gdxConfig.API.Credentials.Key = apiKey
|
|
gdxConfig.API.Credentials.Secret = apiSecret
|
|
gdxConfig.API.Credentials.ClientID = clientID
|
|
gdxConfig.API.AuthenticatedSupport = true
|
|
gdxConfig.API.AuthenticatedWebsocketSupport = true
|
|
c.Websocket = sharedtestvalues.NewTestWebsocket()
|
|
err = c.Setup(gdxConfig)
|
|
if err != nil {
|
|
log.Fatal("CoinbasePro setup error", err)
|
|
}
|
|
os.Exit(m.Run())
|
|
}
|
|
|
|
func TestGetProducts(t *testing.T) {
|
|
_, err := c.GetProducts()
|
|
if err != nil {
|
|
t.Errorf("Coinbase, GetProducts() Error: %s", err)
|
|
}
|
|
}
|
|
|
|
func TestGetTicker(t *testing.T) {
|
|
_, err := c.GetTicker(testPair.String())
|
|
if err != nil {
|
|
t.Error("GetTicker() error", err)
|
|
}
|
|
}
|
|
|
|
func TestGetTrades(t *testing.T) {
|
|
_, err := c.GetTrades(testPair.String())
|
|
if err != nil {
|
|
t.Error("GetTrades() error", err)
|
|
}
|
|
}
|
|
|
|
func TestGetHistoricRatesGranularityCheck(t *testing.T) {
|
|
end := time.Now()
|
|
start := end.Add(-time.Hour * 2)
|
|
_, err := c.GetHistoricCandles(testPair, asset.Spot, start, end, kline.OneHour)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
}
|
|
|
|
func TestCoinbasePro_GetHistoricCandlesExtended(t *testing.T) {
|
|
start := time.Unix(1546300800, 0)
|
|
end := time.Unix(1577836799, 0)
|
|
|
|
_, err := c.GetHistoricCandlesExtended(testPair, asset.Spot, start, end, kline.OneDay)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
}
|
|
|
|
func TestGetStats(t *testing.T) {
|
|
_, err := c.GetStats(testPair.String())
|
|
if err != nil {
|
|
t.Error("GetStats() error", err)
|
|
}
|
|
}
|
|
|
|
func TestGetCurrencies(t *testing.T) {
|
|
_, err := c.GetCurrencies()
|
|
if err != nil {
|
|
t.Error("GetCurrencies() error", err)
|
|
}
|
|
}
|
|
|
|
func TestGetServerTime(t *testing.T) {
|
|
_, err := c.GetServerTime()
|
|
if err != nil {
|
|
t.Error("GetServerTime() error", err)
|
|
}
|
|
}
|
|
|
|
func TestAuthRequests(t *testing.T) {
|
|
if !areTestAPIKeysSet() {
|
|
t.Skip("API keys not set, skipping test")
|
|
}
|
|
_, err := c.GetAccounts()
|
|
if err != nil {
|
|
t.Error("GetAccounts() error", err)
|
|
}
|
|
accountResponse, err := c.GetAccount("13371337-1337-1337-1337-133713371337")
|
|
if accountResponse.ID != "" {
|
|
t.Error("Expecting no data returned")
|
|
}
|
|
if err == nil {
|
|
t.Error("Expecting error")
|
|
}
|
|
accountHistoryResponse, err := c.GetAccountHistory("13371337-1337-1337-1337-133713371337")
|
|
if len(accountHistoryResponse) > 0 {
|
|
t.Error("Expecting no data returned")
|
|
}
|
|
if err == nil {
|
|
t.Error("Expecting error")
|
|
}
|
|
getHoldsResponse, err := c.GetHolds("13371337-1337-1337-1337-133713371337")
|
|
if len(getHoldsResponse) > 0 {
|
|
t.Error("Expecting no data returned")
|
|
}
|
|
if err == nil {
|
|
t.Error("Expecting error")
|
|
}
|
|
orderResponse, err := c.PlaceLimitOrder("", 0.001, 0.001,
|
|
order.Buy.Lower(), "", "", testPair.String(), "", false)
|
|
if orderResponse != "" {
|
|
t.Error("Expecting no data returned")
|
|
}
|
|
if err == nil {
|
|
t.Error("Expecting error")
|
|
}
|
|
marketOrderResponse, err := c.PlaceMarketOrder("", 1, 0,
|
|
order.Buy.Lower(), testPair.String(), "")
|
|
if marketOrderResponse != "" {
|
|
t.Error("Expecting no data returned")
|
|
}
|
|
if err == nil {
|
|
t.Error("Expecting error")
|
|
}
|
|
fillsResponse, err := c.GetFills("1337", testPair.String())
|
|
if len(fillsResponse) > 0 {
|
|
t.Error("Expecting no data returned")
|
|
}
|
|
if err == nil {
|
|
t.Error("Expecting error")
|
|
}
|
|
_, err = c.GetFills("", "")
|
|
if err == nil {
|
|
t.Error("Expecting error")
|
|
}
|
|
marginTransferResponse, err := c.MarginTransfer(1, "withdraw", "13371337-1337-1337-1337-133713371337", "BTC")
|
|
if marginTransferResponse.ID != "" {
|
|
t.Error("Expecting no data returned")
|
|
}
|
|
if err == nil {
|
|
t.Error("Expecting error")
|
|
}
|
|
_, err = c.GetPosition()
|
|
if err == nil {
|
|
t.Error("Expecting error")
|
|
}
|
|
_, err = c.ClosePosition(false)
|
|
if err == nil {
|
|
t.Error("Expecting error")
|
|
}
|
|
_, err = c.GetPayMethods()
|
|
if err != nil {
|
|
t.Error("GetPayMethods() error", err)
|
|
}
|
|
_, err = c.GetCoinbaseAccounts()
|
|
if err != nil {
|
|
t.Error("GetCoinbaseAccounts() error", err)
|
|
}
|
|
}
|
|
|
|
func setFeeBuilder() *exchange.FeeBuilder {
|
|
return &exchange.FeeBuilder{
|
|
Amount: 1,
|
|
FeeType: exchange.CryptocurrencyTradeFee,
|
|
Pair: testPair,
|
|
PurchasePrice: 1,
|
|
}
|
|
}
|
|
|
|
// TestGetFeeByTypeOfflineTradeFee logic test
|
|
func TestGetFeeByTypeOfflineTradeFee(t *testing.T) {
|
|
var feeBuilder = setFeeBuilder()
|
|
c.GetFeeByType(feeBuilder)
|
|
if !areTestAPIKeysSet() {
|
|
if feeBuilder.FeeType != exchange.OfflineTradeFee {
|
|
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)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestGetFee(t *testing.T) {
|
|
var feeBuilder = setFeeBuilder()
|
|
|
|
if areTestAPIKeysSet() {
|
|
// CryptocurrencyTradeFee Basic
|
|
if resp, err := c.GetFee(feeBuilder); resp != float64(0.003) || err != nil {
|
|
t.Error(err)
|
|
t.Errorf("GetFee() error. Expected: %f, Received: %f", float64(0.003), resp)
|
|
}
|
|
|
|
// CryptocurrencyTradeFee High quantity
|
|
feeBuilder = setFeeBuilder()
|
|
feeBuilder.Amount = 1000
|
|
feeBuilder.PurchasePrice = 1000
|
|
if resp, err := c.GetFee(feeBuilder); resp != float64(3000) || err != nil {
|
|
t.Errorf("GetFee() error. Expected: %f, Received: %f", float64(3000), resp)
|
|
t.Error(err)
|
|
}
|
|
|
|
// CryptocurrencyTradeFee IsMaker
|
|
feeBuilder = setFeeBuilder()
|
|
feeBuilder.IsMaker = true
|
|
if resp, err := c.GetFee(feeBuilder); resp != float64(0) || err != nil {
|
|
t.Errorf("GetFee() error. Expected: %f, Received: %f", float64(0.01), resp)
|
|
t.Error(err)
|
|
}
|
|
|
|
// CryptocurrencyTradeFee Negative purchase price
|
|
feeBuilder = setFeeBuilder()
|
|
feeBuilder.PurchasePrice = -1000
|
|
if resp, err := c.GetFee(feeBuilder); resp != float64(0) || err != nil {
|
|
t.Errorf("GetFee() error. Expected: %f, Received: %f", float64(0), resp)
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
// CryptocurrencyWithdrawalFee Basic
|
|
feeBuilder = setFeeBuilder()
|
|
feeBuilder.FeeType = exchange.CryptocurrencyWithdrawalFee
|
|
if resp, err := c.GetFee(feeBuilder); resp != float64(0) || err != nil {
|
|
t.Errorf("GetFee() error. Expected: %f, Received: %f", float64(0), resp)
|
|
t.Error(err)
|
|
}
|
|
|
|
// CyptocurrencyDepositFee Basic
|
|
feeBuilder = setFeeBuilder()
|
|
feeBuilder.FeeType = exchange.CyptocurrencyDepositFee
|
|
if resp, err := c.GetFee(feeBuilder); resp != float64(0) || err != nil {
|
|
t.Errorf("GetFee() error. Expected: %f, Received: %f", float64(0), resp)
|
|
t.Error(err)
|
|
}
|
|
|
|
// InternationalBankDepositFee Basic
|
|
feeBuilder = setFeeBuilder()
|
|
feeBuilder.FeeType = exchange.InternationalBankDepositFee
|
|
feeBuilder.FiatCurrency = currency.EUR
|
|
if resp, err := c.GetFee(feeBuilder); resp != float64(0.15) || err != nil {
|
|
t.Errorf("GetFee() error. Expected: %f, Received: %f", float64(0), resp)
|
|
t.Error(err)
|
|
}
|
|
|
|
// InternationalBankWithdrawalFee Basic
|
|
feeBuilder = setFeeBuilder()
|
|
feeBuilder.FeeType = exchange.InternationalBankWithdrawalFee
|
|
feeBuilder.FiatCurrency = currency.USD
|
|
if resp, err := c.GetFee(feeBuilder); resp != float64(25) || err != nil {
|
|
t.Errorf("GetFee() error. Expected: %f, Received: %f", float64(0), resp)
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestCalculateTradingFee(t *testing.T) {
|
|
t.Parallel()
|
|
// uppercase
|
|
var volume = []Volume{
|
|
{
|
|
ProductID: "BTC_USD",
|
|
Volume: 100,
|
|
},
|
|
}
|
|
|
|
if resp := c.calculateTradingFee(volume, currency.BTC, currency.USD, "_", 1, 1, false); resp != float64(0.003) {
|
|
t.Errorf("GetFee() error. Expected: %f, Received: %f", float64(0.003), resp)
|
|
}
|
|
|
|
// lowercase
|
|
volume = []Volume{
|
|
{
|
|
ProductID: "btc_usd",
|
|
Volume: 100,
|
|
},
|
|
}
|
|
|
|
if resp := c.calculateTradingFee(volume, currency.BTC, currency.USD, "_", 1, 1, false); resp != float64(0.003) {
|
|
t.Errorf("GetFee() error. Expected: %f, Received: %f", float64(0.003), resp)
|
|
}
|
|
|
|
// mixedCase
|
|
volume = []Volume{
|
|
{
|
|
ProductID: "btc_USD",
|
|
Volume: 100,
|
|
},
|
|
}
|
|
|
|
if resp := c.calculateTradingFee(volume, currency.BTC, currency.USD, "_", 1, 1, false); resp != float64(0.003) {
|
|
t.Errorf("GetFee() error. Expected: %f, Received: %f", float64(0.003), resp)
|
|
}
|
|
|
|
// medium volume
|
|
volume = []Volume{
|
|
{
|
|
ProductID: "btc_USD",
|
|
Volume: 10000001,
|
|
},
|
|
}
|
|
|
|
if resp := c.calculateTradingFee(volume, currency.BTC, currency.USD, "_", 1, 1, false); resp != float64(0.002) {
|
|
t.Errorf("GetFee() error. Expected: %f, Received: %f", float64(0.002), resp)
|
|
}
|
|
|
|
// high volume
|
|
volume = []Volume{
|
|
{
|
|
ProductID: "btc_USD",
|
|
Volume: 100000010000,
|
|
},
|
|
}
|
|
|
|
if resp := c.calculateTradingFee(volume, currency.BTC, currency.USD, "_", 1, 1, false); resp != float64(0.001) {
|
|
t.Errorf("GetFee() error. Expected: %f, Received: %f", float64(0.001), resp)
|
|
}
|
|
|
|
// no match
|
|
volume = []Volume{
|
|
{
|
|
ProductID: "btc_beeteesee",
|
|
Volume: 100000010000,
|
|
},
|
|
}
|
|
|
|
if resp := c.calculateTradingFee(volume, currency.BTC, currency.USD, "_", 1, 1, false); resp != float64(0) {
|
|
t.Errorf("GetFee() error. Expected: %f, Received: %f", float64(0), resp)
|
|
}
|
|
|
|
// taker
|
|
volume = []Volume{
|
|
{
|
|
ProductID: "btc_USD",
|
|
Volume: 100000010000,
|
|
},
|
|
}
|
|
|
|
if resp := c.calculateTradingFee(volume, currency.BTC, currency.USD, "_", 1, 1, true); resp != float64(0) {
|
|
t.Errorf("GetFee() error. Expected: %f, Received: %f", float64(0), resp)
|
|
}
|
|
}
|
|
|
|
func TestFormatWithdrawPermissions(t *testing.T) {
|
|
expectedResult := exchange.AutoWithdrawCryptoWithAPIPermissionText + " & " + exchange.AutoWithdrawFiatWithAPIPermissionText
|
|
withdrawPermissions := c.FormatWithdrawPermissions()
|
|
if withdrawPermissions != expectedResult {
|
|
t.Errorf("Expected: %s, Received: %s", expectedResult, withdrawPermissions)
|
|
}
|
|
}
|
|
|
|
func TestGetActiveOrders(t *testing.T) {
|
|
var getOrdersRequest = order.GetOrdersRequest{
|
|
Type: order.AnyType,
|
|
AssetType: asset.Spot,
|
|
Pairs: []currency.Pair{testPair},
|
|
}
|
|
|
|
_, err := c.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")
|
|
}
|
|
}
|
|
|
|
func TestGetOrderHistory(t *testing.T) {
|
|
var getOrdersRequest = order.GetOrdersRequest{
|
|
Type: order.AnyType,
|
|
AssetType: asset.Spot,
|
|
Pairs: []currency.Pair{testPair},
|
|
}
|
|
|
|
_, err := c.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")
|
|
}
|
|
}
|
|
|
|
// Any tests below this line have the ability to impact your orders on the exchange. Enable canManipulateRealOrders to run them
|
|
// ----------------------------------------------------------------------------------------------------------------------------
|
|
func areTestAPIKeysSet() bool {
|
|
return c.ValidateAPICredentials()
|
|
}
|
|
|
|
func TestSubmitOrder(t *testing.T) {
|
|
if areTestAPIKeysSet() && !canManipulateRealOrders {
|
|
t.Skip("API keys set, canManipulateRealOrders false, skipping test")
|
|
}
|
|
|
|
var orderSubmission = &order.Submit{
|
|
Pair: currency.Pair{
|
|
Delimiter: "-",
|
|
Base: currency.BTC,
|
|
Quote: currency.USD,
|
|
},
|
|
Side: order.Buy,
|
|
Type: order.Limit,
|
|
Price: 1,
|
|
Amount: 1,
|
|
ClientID: "meowOrder",
|
|
AssetType: asset.Spot,
|
|
}
|
|
response, err := c.SubmitOrder(orderSubmission)
|
|
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")
|
|
}
|
|
}
|
|
|
|
func TestCancelExchangeOrder(t *testing.T) {
|
|
if areTestAPIKeysSet() && !canManipulateRealOrders {
|
|
t.Skip("API keys set, canManipulateRealOrders false, skipping test")
|
|
}
|
|
|
|
var orderCancellation = &order.Cancel{
|
|
ID: "1",
|
|
WalletAddress: core.BitcoinDonationAddress,
|
|
AccountID: "1",
|
|
Pair: testPair,
|
|
AssetType: asset.Spot,
|
|
}
|
|
|
|
err := c.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)
|
|
}
|
|
}
|
|
|
|
func TestCancelAllExchangeOrders(t *testing.T) {
|
|
if areTestAPIKeysSet() && !canManipulateRealOrders {
|
|
t.Skip("API keys set, canManipulateRealOrders false, skipping test")
|
|
}
|
|
|
|
var orderCancellation = &order.Cancel{
|
|
ID: "1",
|
|
WalletAddress: core.BitcoinDonationAddress,
|
|
AccountID: "1",
|
|
Pair: testPair,
|
|
AssetType: asset.Spot,
|
|
}
|
|
|
|
resp, err := c.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 orders: %v", err)
|
|
}
|
|
|
|
if len(resp.Status) > 0 {
|
|
t.Errorf("%v orders failed to cancel", len(resp.Status))
|
|
}
|
|
}
|
|
|
|
func TestModifyOrder(t *testing.T) {
|
|
if areTestAPIKeysSet() && !canManipulateRealOrders {
|
|
t.Skip("API keys set, canManipulateRealOrders false, skipping test")
|
|
}
|
|
_, err := c.ModifyOrder(&order.Modify{AssetType: asset.Spot})
|
|
if err == nil {
|
|
t.Error("ModifyOrder() Expected error")
|
|
}
|
|
}
|
|
|
|
func TestWithdraw(t *testing.T) {
|
|
withdrawCryptoRequest := withdraw.Request{
|
|
Amount: -1,
|
|
Currency: currency.BTC,
|
|
Description: "WITHDRAW IT ALL",
|
|
Crypto: withdraw.CryptoRequest{
|
|
Address: core.BitcoinDonationAddress,
|
|
},
|
|
}
|
|
|
|
if areTestAPIKeysSet() && !canManipulateRealOrders {
|
|
t.Skip("API keys set, canManipulateRealOrders false, skipping test")
|
|
}
|
|
|
|
_, err := c.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)
|
|
}
|
|
}
|
|
|
|
func TestWithdrawFiat(t *testing.T) {
|
|
if areTestAPIKeysSet() && !canManipulateRealOrders {
|
|
t.Skip("API keys set, canManipulateRealOrders false, skipping test")
|
|
}
|
|
|
|
var withdrawFiatRequest = withdraw.Request{
|
|
Amount: 100,
|
|
Currency: currency.USD,
|
|
Fiat: withdraw.FiatRequest{
|
|
Bank: banking.Account{
|
|
BankName: "Federal Reserve Bank",
|
|
},
|
|
},
|
|
}
|
|
|
|
_, err := c.WithdrawFiatFunds(&withdrawFiatRequest)
|
|
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)
|
|
}
|
|
}
|
|
|
|
func TestWithdrawInternationalBank(t *testing.T) {
|
|
if areTestAPIKeysSet() && !canManipulateRealOrders {
|
|
t.Skip("API keys set, canManipulateRealOrders false, skipping test")
|
|
}
|
|
|
|
var withdrawFiatRequest = withdraw.Request{
|
|
Amount: 100,
|
|
Currency: currency.USD,
|
|
Fiat: withdraw.FiatRequest{
|
|
Bank: banking.Account{
|
|
BankName: "Federal Reserve Bank",
|
|
},
|
|
},
|
|
}
|
|
|
|
_, err := c.WithdrawFiatFundsToInternationalBank(&withdrawFiatRequest)
|
|
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)
|
|
}
|
|
}
|
|
|
|
func TestGetDepositAddress(t *testing.T) {
|
|
_, err := c.GetDepositAddress(currency.BTC, "")
|
|
if err == nil {
|
|
t.Error("GetDepositAddress() error", err)
|
|
}
|
|
}
|
|
|
|
// TestWsAuth dials websocket, sends login request.
|
|
func TestWsAuth(t *testing.T) {
|
|
if !c.Websocket.IsEnabled() && !c.API.AuthenticatedWebsocketSupport || !areTestAPIKeysSet() {
|
|
t.Skip(stream.WebsocketNotEnabled)
|
|
}
|
|
var dialer websocket.Dialer
|
|
err := c.Websocket.Conn.Dial(&dialer, http.Header{})
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
go c.wsReadData()
|
|
|
|
err = c.Subscribe([]stream.ChannelSubscription{
|
|
{
|
|
Channel: "user",
|
|
Currency: testPair,
|
|
},
|
|
})
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
timer := time.NewTimer(sharedtestvalues.WebsocketResponseDefaultTimeout)
|
|
select {
|
|
case badResponse := <-c.Websocket.DataHandler:
|
|
t.Error(badResponse)
|
|
case <-timer.C:
|
|
}
|
|
timer.Stop()
|
|
}
|
|
|
|
func TestWsSubscribe(t *testing.T) {
|
|
pressXToJSON := []byte(`{
|
|
"type": "subscriptions",
|
|
"channels": [
|
|
{
|
|
"name": "level2",
|
|
"product_ids": [
|
|
"ETH-USD",
|
|
"ETH-EUR"
|
|
]
|
|
},
|
|
{
|
|
"name": "heartbeat",
|
|
"product_ids": [
|
|
"ETH-USD",
|
|
"ETH-EUR"
|
|
]
|
|
},
|
|
{
|
|
"name": "ticker",
|
|
"product_ids": [
|
|
"ETH-USD",
|
|
"ETH-EUR",
|
|
"ETH-BTC"
|
|
]
|
|
}
|
|
]
|
|
}`)
|
|
err := c.wsHandleData(pressXToJSON)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestWsHeartbeat(t *testing.T) {
|
|
pressXToJSON := []byte(`{
|
|
"type": "heartbeat",
|
|
"sequence": 90,
|
|
"last_trade_id": 20,
|
|
"product_id": "BTC-USD",
|
|
"time": "2014-11-07T08:19:28.464459Z"
|
|
}`)
|
|
err := c.wsHandleData(pressXToJSON)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestWsStatus(t *testing.T) {
|
|
pressXToJSON := []byte(`{
|
|
"type": "status",
|
|
"products": [
|
|
{
|
|
"id": "BTC-USD",
|
|
"base_currency": "BTC",
|
|
"quote_currency": "USD",
|
|
"base_min_size": "0.001",
|
|
"base_max_size": "70",
|
|
"base_increment": "0.00000001",
|
|
"quote_increment": "0.01",
|
|
"display_name": "BTC/USD",
|
|
"status": "online",
|
|
"status_message": null,
|
|
"min_market_funds": "10",
|
|
"max_market_funds": "1000000",
|
|
"post_only": false,
|
|
"limit_only": false,
|
|
"cancel_only": false
|
|
}
|
|
],
|
|
"currencies": [
|
|
{
|
|
"id": "USD",
|
|
"name": "United States Dollar",
|
|
"min_size": "0.01000000",
|
|
"status": "online",
|
|
"status_message": null,
|
|
"max_precision": "0.01",
|
|
"convertible_to": ["USDC"], "details": {}
|
|
},
|
|
{
|
|
"id": "USDC",
|
|
"name": "USD Coin",
|
|
"min_size": "0.00000100",
|
|
"status": "online",
|
|
"status_message": null,
|
|
"max_precision": "0.000001",
|
|
"convertible_to": ["USD"], "details": {}
|
|
},
|
|
{
|
|
"id": "BTC",
|
|
"name": "Bitcoin",
|
|
"min_size": "0.00000001",
|
|
"status": "online",
|
|
"status_message": null,
|
|
"max_precision": "0.00000001",
|
|
"convertible_to": []
|
|
}
|
|
]
|
|
}`)
|
|
err := c.wsHandleData(pressXToJSON)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestWsTicker(t *testing.T) {
|
|
pressXToJSON := []byte(`{
|
|
"type": "ticker",
|
|
"trade_id": 20153558,
|
|
"sequence": 3262786978,
|
|
"time": "2017-09-02T17:05:49.250000Z",
|
|
"product_id": "BTC-USD",
|
|
"price": "4388.01000000",
|
|
"side": "buy",
|
|
"last_size": "0.03000000",
|
|
"best_bid": "4388",
|
|
"best_ask": "4388.01"
|
|
}`)
|
|
err := c.wsHandleData(pressXToJSON)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestWsOrderbook(t *testing.T) {
|
|
pressXToJSON := []byte(`{
|
|
"type": "snapshot",
|
|
"product_id": "BTC-USD",
|
|
"bids": [["10101.10", "0.45054140"]],
|
|
"asks": [["10102.55", "0.57753524"]]
|
|
}`)
|
|
err := c.wsHandleData(pressXToJSON)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
|
|
pressXToJSON = []byte(`{
|
|
"type": "l2update",
|
|
"product_id": "BTC-USD",
|
|
"time": "2019-08-14T20:42:27.265Z",
|
|
"changes": [
|
|
[
|
|
"buy",
|
|
"10101.80000000",
|
|
"0.162567"
|
|
]
|
|
]
|
|
}`)
|
|
err = c.wsHandleData(pressXToJSON)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestWsOrders(t *testing.T) {
|
|
pressXToJSON := []byte(`{
|
|
"type": "received",
|
|
"time": "2014-11-07T08:19:27.028459Z",
|
|
"product_id": "BTC-USD",
|
|
"sequence": 10,
|
|
"order_id": "d50ec984-77a8-460a-b958-66f114b0de9b",
|
|
"size": "1.34",
|
|
"price": "502.1",
|
|
"side": "buy",
|
|
"order_type": "limit"
|
|
}`)
|
|
err := c.wsHandleData(pressXToJSON)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
|
|
pressXToJSON = []byte(`{
|
|
"type": "received",
|
|
"time": "2014-11-09T08:19:27.028459Z",
|
|
"product_id": "BTC-USD",
|
|
"sequence": 12,
|
|
"order_id": "dddec984-77a8-460a-b958-66f114b0de9b",
|
|
"funds": "3000.234",
|
|
"side": "buy",
|
|
"order_type": "market"
|
|
}`)
|
|
err = c.wsHandleData(pressXToJSON)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
|
|
pressXToJSON = []byte(`{
|
|
"type": "open",
|
|
"time": "2014-11-07T08:19:27.028459Z",
|
|
"product_id": "BTC-USD",
|
|
"sequence": 10,
|
|
"order_id": "d50ec984-77a8-460a-b958-66f114b0de9b",
|
|
"price": "200.2",
|
|
"remaining_size": "1.00",
|
|
"side": "sell"
|
|
}`)
|
|
err = c.wsHandleData(pressXToJSON)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
|
|
pressXToJSON = []byte(`{
|
|
"type": "done",
|
|
"time": "2014-11-07T08:19:27.028459Z",
|
|
"product_id": "BTC-USD",
|
|
"sequence": 10,
|
|
"price": "200.2",
|
|
"order_id": "d50ec984-77a8-460a-b958-66f114b0de9b",
|
|
"reason": "filled",
|
|
"side": "sell",
|
|
"remaining_size": "0"
|
|
}`)
|
|
err = c.wsHandleData(pressXToJSON)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
|
|
pressXToJSON = []byte(`{
|
|
"type": "match",
|
|
"trade_id": 10,
|
|
"sequence": 50,
|
|
"maker_order_id": "ac928c66-ca53-498f-9c13-a110027a60e8",
|
|
"taker_order_id": "132fb6ae-456b-4654-b4e0-d681ac05cea1",
|
|
"time": "2014-11-07T08:19:27.028459Z",
|
|
"product_id": "BTC-USD",
|
|
"size": "5.23512",
|
|
"price": "400.23",
|
|
"side": "sell"
|
|
}`)
|
|
err = c.wsHandleData(pressXToJSON)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
|
|
pressXToJSON = []byte(`{
|
|
"type": "change",
|
|
"time": "2014-11-07T08:19:27.028459Z",
|
|
"sequence": 80,
|
|
"order_id": "ac928c66-ca53-498f-9c13-a110027a60e8",
|
|
"product_id": "BTC-USD",
|
|
"new_size": "5.23512",
|
|
"old_size": "12.234412",
|
|
"price": "400.23",
|
|
"side": "sell"
|
|
}`)
|
|
err = c.wsHandleData(pressXToJSON)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
pressXToJSON = []byte(`{
|
|
"type": "change",
|
|
"time": "2014-11-07T08:19:27.028459Z",
|
|
"sequence": 80,
|
|
"order_id": "ac928c66-ca53-498f-9c13-a110027a60e8",
|
|
"product_id": "BTC-USD",
|
|
"new_funds": "5.23512",
|
|
"old_funds": "12.234412",
|
|
"price": "400.23",
|
|
"side": "sell"
|
|
}`)
|
|
err = c.wsHandleData(pressXToJSON)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
pressXToJSON = []byte(`{
|
|
"type": "activate",
|
|
"product_id": "BTC-USD",
|
|
"timestamp": "1483736448.299000",
|
|
"user_id": "12",
|
|
"profile_id": "30000727-d308-cf50-7b1c-c06deb1934fc",
|
|
"order_id": "7b52009b-64fd-0a2a-49e6-d8a939753077",
|
|
"stop_type": "entry",
|
|
"side": "buy",
|
|
"stop_price": "80",
|
|
"size": "2",
|
|
"funds": "50",
|
|
"taker_fee_rate": "0.0025",
|
|
"private": true
|
|
}`)
|
|
err = c.wsHandleData(pressXToJSON)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestStatusToStandardStatus(t *testing.T) {
|
|
type TestCases struct {
|
|
Case string
|
|
Result order.Status
|
|
}
|
|
testCases := []TestCases{
|
|
{Case: "received", Result: order.New},
|
|
{Case: "open", Result: order.Active},
|
|
{Case: "done", Result: order.Filled},
|
|
{Case: "match", Result: order.PartiallyFilled},
|
|
{Case: "change", Result: order.Active},
|
|
{Case: "activate", Result: order.Active},
|
|
{Case: "LOL", Result: order.UnknownStatus},
|
|
}
|
|
for i := range testCases {
|
|
result, _ := statusToStandardStatus(testCases[i].Case)
|
|
if result != testCases[i].Result {
|
|
t.Errorf("Exepcted: %v, received: %v", testCases[i].Result, result)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestParseTime(t *testing.T) {
|
|
// Rest examples use 2014-11-07T22:19:28.578544Z" and can be safely
|
|
// unmarhsalled into time.Time
|
|
|
|
// All events except for activate use the above, in the below test
|
|
// we'll use their API docs example
|
|
r := convert.TimeFromUnixTimestampDecimal(1483736448.299000).UTC()
|
|
if r.Year() != 2017 ||
|
|
r.Month().String() != "January" ||
|
|
r.Day() != 6 {
|
|
t.Error("unexpected result")
|
|
}
|
|
}
|
|
|
|
func TestCheckInterval(t *testing.T) {
|
|
interval := time.Minute
|
|
i, err := checkInterval(interval)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if i != 60 {
|
|
t.Fatal("incorrect return")
|
|
}
|
|
interval = time.Minute * 5
|
|
i, err = checkInterval(interval)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if i != 300 {
|
|
t.Fatal("incorrect return")
|
|
}
|
|
|
|
interval = time.Minute * 15
|
|
i, err = checkInterval(interval)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if i != 900 {
|
|
t.Fatal("incorrect return")
|
|
}
|
|
|
|
interval = time.Hour
|
|
i, err = checkInterval(interval)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if i != 3600 {
|
|
t.Fatal("incorrect return")
|
|
}
|
|
|
|
interval = time.Hour * 6
|
|
i, err = checkInterval(interval)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if i != 21600 {
|
|
t.Fatal("incorrect return")
|
|
}
|
|
|
|
interval = time.Hour * 24
|
|
i, err = checkInterval(interval)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if i != 86400 {
|
|
t.Fatal("incorrect return")
|
|
}
|
|
|
|
interval = time.Hour * 1337
|
|
_, err = checkInterval(interval)
|
|
if err == nil {
|
|
t.Fatal("error cannot be nil")
|
|
}
|
|
}
|
|
|
|
func TestGetRecentTrades(t *testing.T) {
|
|
t.Parallel()
|
|
_, err := c.GetRecentTrades(testPair, asset.Spot)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestGetHistoricTrades(t *testing.T) {
|
|
t.Parallel()
|
|
_, err := c.GetHistoricTrades(testPair, asset.Spot, time.Now().Add(-time.Minute*15), time.Now())
|
|
if err != nil && err != common.ErrFunctionNotSupported {
|
|
t.Error(err)
|
|
}
|
|
}
|