mirror of
https://github.com/d0zingcat/gocryptotrader.git
synced 2026-05-18 23:16:49 +00:00
* OrderManager: Fix race condition in submit with ws If the ws sees the order before processSubmittedOrder then it will have assigned it an internal order id already and added it to the store. Don't treat that as an error. Instead just use the newer ws details * OrderManager: Fix error comparisson Should always use errors.Is when possible * Tests: Simplify btcusd test pair declaration * OrderManager: Improve test readability * OrderManager: Add orderstore.getByDetail test * Return a fresh pointer from orderstore.getByDetail This protects the order.Details in the store from direct access. The use-case was to allow the returned objects to be references so that future changes to them would be reflected. However we're not ready yet to allow people to touch the orders directly, because they're not protected directly by a mutex, and nothing would stop consumers contaminating the integrity of the data. We can revisit this topic later atomicly, but it's definitely tangental to the cause of action for PR #1336. * Fix GetByDetail tests to assert a new pointer * OrderManager: Avoid possible lock races This fix internalises the getByDetail because the implication of moving lock ownership out of exists/getByDetail to consumers breaks the order store struct encapsulation in a way we really don't want to. It's also more efficient * Fix spelling mistake Co-authored-by: Scott <gloriousCode@users.noreply.github.com> * OrderManager: Fix TestSubmitOrder... description * OrderManager: Improve clarity of comment * OrderManager: Capitalise error message On failure to add to orderstore, capitalise the error message Co-authored-by: Adrian Gallagher <adrian.gallagher@thrasher.io> --------- Co-authored-by: Scott <gloriousCode@users.noreply.github.com> Co-authored-by: Adrian Gallagher <adrian.gallagher@thrasher.io>
1870 lines
57 KiB
Go
1870 lines
57 KiB
Go
package bitfinex
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"log"
|
|
"net/http"
|
|
"os"
|
|
"sync"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/gorilla/websocket"
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/thrasher-corp/gocryptotrader/common"
|
|
"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/orderbook"
|
|
"github.com/thrasher-corp/gocryptotrader/exchanges/sharedtestvalues"
|
|
"github.com/thrasher-corp/gocryptotrader/exchanges/stream"
|
|
"github.com/thrasher-corp/gocryptotrader/exchanges/ticker"
|
|
"github.com/thrasher-corp/gocryptotrader/portfolio/withdraw"
|
|
)
|
|
|
|
// Please supply your own keys here to do better tests
|
|
const (
|
|
apiKey = ""
|
|
apiSecret = ""
|
|
canManipulateRealOrders = false
|
|
)
|
|
|
|
var b = &Bitfinex{}
|
|
var wsAuthExecuted bool
|
|
var btcusdPair = currency.NewPair(currency.BTC, currency.USD)
|
|
|
|
func TestMain(m *testing.M) {
|
|
b.SetDefaults()
|
|
cfg := config.GetConfig()
|
|
err := cfg.LoadConfig("../../testdata/configtest.json", true)
|
|
if err != nil {
|
|
log.Fatal("Bitfinex load config error", err)
|
|
}
|
|
bfxConfig, err := cfg.GetExchangeConfig("Bitfinex")
|
|
if err != nil {
|
|
log.Fatal("Bitfinex Setup() init error")
|
|
}
|
|
b.Websocket = sharedtestvalues.NewTestWebsocket()
|
|
err = b.Setup(bfxConfig)
|
|
if err != nil {
|
|
log.Fatal("Bitfinex setup error", err)
|
|
}
|
|
b.SetCredentials(apiKey, apiSecret, "", "", "", "")
|
|
if !b.Enabled || b.API.AuthenticatedSupport ||
|
|
b.Verbose || b.Websocket.IsEnabled() || len(b.BaseCurrencies) < 1 {
|
|
log.Fatal("Bitfinex Setup values not set correctly")
|
|
}
|
|
|
|
if sharedtestvalues.AreAPICredentialsSet(b) {
|
|
b.API.AuthenticatedSupport = true
|
|
b.API.AuthenticatedWebsocketSupport = true
|
|
}
|
|
b.WebsocketSubdChannels = make(map[int]*stream.ChannelSubscription)
|
|
|
|
os.Exit(m.Run())
|
|
}
|
|
|
|
func TestStart(t *testing.T) {
|
|
t.Parallel()
|
|
err := b.Start(context.Background(), nil)
|
|
if !errors.Is(err, common.ErrNilPointer) {
|
|
t.Fatalf("received: '%v' but expected: '%v'", err, common.ErrNilPointer)
|
|
}
|
|
var testWg sync.WaitGroup
|
|
err = b.Start(context.Background(), &testWg)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
testWg.Wait()
|
|
}
|
|
|
|
func TestGetV2MarginFunding(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, b)
|
|
_, err := b.GetV2MarginFunding(context.Background(), "fUSD", "2", 2)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestGetV2MarginInfo(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, b)
|
|
_, err := b.GetV2MarginInfo(context.Background(), "base")
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
_, err = b.GetV2MarginInfo(context.Background(), "tBTCUSD")
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
_, err = b.GetV2MarginInfo(context.Background(), "sym_all")
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestGetAccountInfoV2(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, b)
|
|
_, err := b.GetAccountInfoV2(context.Background())
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestGetV2FundingInfo(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, b)
|
|
_, err := b.GetV2FundingInfo(context.Background(), "fUST")
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestGetV2Balances(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, b)
|
|
_, err := b.GetV2Balances(context.Background())
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestGetDerivativeStatusInfo(t *testing.T) {
|
|
t.Parallel()
|
|
_, err := b.GetDerivativeStatusInfo(context.Background(), "ALL", "", "", 0, 0)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestGetPairs(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
_, err := b.GetPairs(context.Background(), asset.Binary)
|
|
if !errors.Is(err, asset.ErrNotSupported) {
|
|
t.Fatalf("received: '%v' but expected: '%v'", err, asset.ErrNotSupported)
|
|
}
|
|
|
|
assets := b.GetAssetTypes(false)
|
|
for x := range assets {
|
|
_, err := b.GetPairs(context.Background(), assets[x])
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestUpdateTradablePairs(t *testing.T) {
|
|
t.Parallel()
|
|
if err := b.UpdateTradablePairs(context.Background(), true); err != nil {
|
|
t.Error("Bitfinex UpdateTradablePairs() error", err)
|
|
}
|
|
}
|
|
|
|
func TestUpdateOrderExecutionLimits(t *testing.T) {
|
|
t.Parallel()
|
|
tests := map[asset.Item][]currency.Pair{
|
|
asset.Spot: {
|
|
currency.NewPair(currency.ETH, currency.UST),
|
|
currency.NewPair(currency.BTC, currency.UST),
|
|
},
|
|
}
|
|
for assetItem, pairs := range tests {
|
|
if err := b.UpdateOrderExecutionLimits(context.Background(), assetItem); err != nil {
|
|
t.Errorf("Error fetching %s pairs for test: %v", assetItem, err)
|
|
continue
|
|
}
|
|
for _, pair := range pairs {
|
|
limits, err := b.GetOrderExecutionLimits(assetItem, pair)
|
|
if err != nil {
|
|
t.Errorf("GetOrderExecutionLimits() error during TestExecutionLimits; Asset: %s Pair: %s Err: %v", assetItem, pair, err)
|
|
continue
|
|
}
|
|
if limits.MinimumBaseAmount == 0 {
|
|
t.Errorf("UpdateOrderExecutionLimits empty minimum base amount; Pair: %s Expected Limit: %v", pair, limits.MinimumBaseAmount)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestAppendOptionalDelimiter(t *testing.T) {
|
|
t.Parallel()
|
|
curr1, err := currency.NewPairFromString("BTCUSD")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
b.appendOptionalDelimiter(&curr1)
|
|
if curr1.Delimiter != "" {
|
|
t.Errorf("Expected no delimiter, received %v", curr1.Delimiter)
|
|
}
|
|
curr2, err := currency.NewPairFromString("DUSK:USD")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
curr2.Delimiter = ""
|
|
b.appendOptionalDelimiter(&curr2)
|
|
if curr2.Delimiter != ":" {
|
|
t.Errorf("Expected \":\" as a delimiter, received %v", curr2.Delimiter)
|
|
}
|
|
}
|
|
|
|
func TestGetPlatformStatus(t *testing.T) {
|
|
t.Parallel()
|
|
result, err := b.GetPlatformStatus(context.Background())
|
|
if err != nil {
|
|
t.Errorf("TestGetPlatformStatus error: %s", err)
|
|
}
|
|
|
|
if result != bitfinexOperativeMode && result != bitfinexMaintenanceMode {
|
|
t.Errorf("TestGetPlatformStatus unexpected response code")
|
|
}
|
|
}
|
|
|
|
func TestGetTickerBatch(t *testing.T) {
|
|
t.Parallel()
|
|
_, err := b.GetTickerBatch(context.Background())
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestGetTicker(t *testing.T) {
|
|
t.Parallel()
|
|
_, err := b.GetTicker(context.Background(), "tBTCUSD")
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
|
|
_, err = b.GetTicker(context.Background(), "fUSD")
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestGetTrades(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
_, err := b.GetTrades(context.Background(), "tBTCUSD", 5, 0, 0, false)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestGetOrderbook(t *testing.T) {
|
|
t.Parallel()
|
|
_, err := b.GetOrderbook(context.Background(), "tBTCUSD", "R0", 1)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
|
|
_, err = b.GetOrderbook(context.Background(), "fUSD", "R0", 1)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
|
|
_, err = b.GetOrderbook(context.Background(), "tBTCUSD", "P0", 1)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
|
|
_, err = b.GetOrderbook(context.Background(), "fUSD", "P0", 1)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
|
|
_, err = b.GetOrderbook(context.Background(), "tLINK:UST", "P0", 1)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestGetStats(t *testing.T) {
|
|
t.Parallel()
|
|
_, err := b.GetStats(context.Background(), "btcusd")
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestGetFundingBook(t *testing.T) {
|
|
t.Parallel()
|
|
_, err := b.GetFundingBook(context.Background(), "usd")
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestGetLends(t *testing.T) {
|
|
t.Parallel()
|
|
_, err := b.GetLends(context.Background(), "usd", nil)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestGetCandles(t *testing.T) {
|
|
t.Parallel()
|
|
e := time.Now().Add(-time.Hour * 2).Truncate(time.Hour)
|
|
s := e.Add(-time.Hour * 4)
|
|
_, err := b.GetCandles(context.Background(), "fUST", "1D", s.UnixMilli(), e.UnixMilli(), 10000, true)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
}
|
|
|
|
func TestGetLeaderboard(t *testing.T) {
|
|
t.Parallel()
|
|
// Test invalid key
|
|
_, err := b.GetLeaderboard(context.Background(), "", "", "", 0, 0, "", "")
|
|
if err == nil {
|
|
t.Error("an error should have been thrown for an invalid key")
|
|
}
|
|
// Test default
|
|
_, err = b.GetLeaderboard(context.Background(),
|
|
LeaderboardUnrealisedProfitInception,
|
|
"1M",
|
|
"tGLOBAL:USD",
|
|
0,
|
|
0,
|
|
"",
|
|
"")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
// Test params
|
|
var result []LeaderboardEntry
|
|
result, err = b.GetLeaderboard(context.Background(),
|
|
LeaderboardUnrealisedProfitInception,
|
|
"1M",
|
|
"tGLOBAL:USD",
|
|
-1,
|
|
1000,
|
|
"1582695181661",
|
|
"1583299981661")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if len(result) == 0 {
|
|
t.Error("should have retrieved leaderboard data")
|
|
}
|
|
}
|
|
|
|
func TestGetAccountFees(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, b)
|
|
|
|
_, err := b.UpdateAccountInfo(context.Background(), asset.Spot)
|
|
if err != nil {
|
|
t.Error("GetAccountInfo error", err)
|
|
}
|
|
}
|
|
|
|
func TestGetWithdrawalFee(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, b)
|
|
_, err := b.GetWithdrawalFees(context.Background())
|
|
if err != nil {
|
|
t.Error("GetAccountInfo error", err)
|
|
}
|
|
}
|
|
|
|
func TestGetAccountSummary(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, b)
|
|
_, err := b.GetAccountSummary(context.Background())
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestNewDeposit(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, b)
|
|
_, err := b.NewDeposit(context.Background(), "blabla", "testwallet", 0)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
|
|
_, err = b.NewDeposit(context.Background(), "bitcoin", "testwallet", 0)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
|
|
_, err = b.NewDeposit(context.Background(), "ripple", "", 0)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestGetKeyPermissions(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, b)
|
|
_, err := b.GetKeyPermissions(context.Background())
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestGetMarginInfo(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, b)
|
|
_, err := b.GetMarginInfo(context.Background())
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestGetAccountBalance(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, b)
|
|
_, err := b.GetAccountBalance(context.Background())
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestGetAccountInfo(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, b)
|
|
_, err := b.FetchAccountInfo(context.Background(), asset.Spot)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestWalletTransfer(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, b)
|
|
_, err := b.WalletTransfer(context.Background(), 0.01, "btc", "bla", "bla")
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestNewOrder(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, b)
|
|
_, err := b.NewOrder(context.Background(),
|
|
"BTCUSD",
|
|
order.Limit.Lower(),
|
|
-1,
|
|
2,
|
|
false,
|
|
true)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestUpdateTicker(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
if _, err := b.UpdateTicker(context.Background(), btcusdPair, asset.Spot); err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestUpdateTickers(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
err := b.UpdateTradablePairs(context.Background(), false)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
assets := b.GetAssetTypes(false)
|
|
for x := range assets {
|
|
var avail []currency.Pair
|
|
avail, err = b.GetAvailablePairs(assets[x])
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
err = b.CurrencyPairs.StorePairs(assets[x], avail, true)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
err = b.UpdateTickers(context.Background(), assets[x])
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
for y := range avail {
|
|
_, err = ticker.GetTicker(b.Name, avail[y], assets[x])
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestNewOrderMulti(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, b)
|
|
newOrder := []PlaceOrder{
|
|
{
|
|
Symbol: "BTCUSD",
|
|
Amount: 1,
|
|
Price: 1,
|
|
Exchange: "bitfinex",
|
|
Side: order.Buy.Lower(),
|
|
Type: order.Limit.Lower(),
|
|
},
|
|
}
|
|
|
|
_, err := b.NewOrderMulti(context.Background(), newOrder)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestCancelOrder(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, b)
|
|
_, err := b.CancelExistingOrder(context.Background(), 1337)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestCancelMultipleOrders(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, b)
|
|
_, err := b.CancelMultipleOrders(context.Background(), []int64{1337, 1336})
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestCancelAllOrders(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, b)
|
|
_, err := b.CancelAllExistingOrders(context.Background())
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestReplaceOrder(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, b)
|
|
_, err := b.ReplaceOrder(context.Background(), 1337, "BTCUSD",
|
|
1, 1, true, order.Limit.Lower(), false)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestGetOrderStatus(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, b)
|
|
_, err := b.GetOrderStatus(context.Background(), 1337)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestGetOpenOrders(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, b)
|
|
_, err := b.GetOpenOrders(context.Background())
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
|
|
_, err = b.GetOpenOrders(context.Background(), 1, 2, 3, 4)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestGetActivePositions(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, b)
|
|
_, err := b.GetActivePositions(context.Background())
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestClaimPosition(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, b)
|
|
_, err := b.ClaimPosition(context.Background(), 1337)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestGetBalanceHistory(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, b)
|
|
_, err := b.GetBalanceHistory(context.Background(),
|
|
"USD", time.Time{}, time.Time{}, 1, "deposit")
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestGetMovementHistory(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, b)
|
|
_, err := b.GetMovementHistory(context.Background(), "USD", "bitcoin", time.Time{}, time.Time{}, 1)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestGetTradeHistory(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, b)
|
|
_, err := b.GetTradeHistory(context.Background(),
|
|
"BTCUSD", time.Time{}, time.Time{}, 1, 0)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestNewOffer(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, b)
|
|
_, err := b.NewOffer(context.Background(), "BTC", 1, 1, 1, "loan")
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestCancelOffer(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, b)
|
|
_, err := b.CancelOffer(context.Background(), 1337)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestGetWithdrawalsHistory(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, b)
|
|
_, err := b.GetWithdrawalsHistory(context.Background(), currency.BTC, asset.Spot)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestGetOfferStatus(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, b)
|
|
_, err := b.GetOfferStatus(context.Background(), 1337)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestGetActiveCredits(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, b)
|
|
_, err := b.GetActiveCredits(context.Background())
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestGetActiveOffers(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, b)
|
|
_, err := b.GetActiveOffers(context.Background())
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestGetActiveMarginFunding(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, b)
|
|
_, err := b.GetActiveMarginFunding(context.Background())
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestGetUnusedMarginFunds(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, b)
|
|
_, err := b.GetUnusedMarginFunds(context.Background())
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestGetMarginTotalTakenFunds(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, b)
|
|
_, err := b.GetMarginTotalTakenFunds(context.Background())
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestCloseMarginFunding(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, b)
|
|
_, err := b.CloseMarginFunding(context.Background(), 1337)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func setFeeBuilder() *exchange.FeeBuilder {
|
|
return &exchange.FeeBuilder{
|
|
Amount: 1,
|
|
FeeType: exchange.CryptocurrencyTradeFee,
|
|
Pair: currency.NewPair(currency.BTC, currency.LTC),
|
|
PurchasePrice: 1,
|
|
}
|
|
}
|
|
|
|
// TestGetFeeByTypeOfflineTradeFee logic test
|
|
func TestGetFeeByTypeOfflineTradeFee(t *testing.T) {
|
|
var feeBuilder = setFeeBuilder()
|
|
_, err := b.GetFeeByType(context.Background(), feeBuilder)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if !sharedtestvalues.AreAPICredentialsSet(b) {
|
|
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()
|
|
t.Parallel()
|
|
|
|
if sharedtestvalues.AreAPICredentialsSet(b) {
|
|
// CryptocurrencyTradeFee Basic
|
|
if _, err := b.GetFee(context.Background(), feeBuilder); err != nil {
|
|
t.Error(err)
|
|
}
|
|
|
|
// CryptocurrencyTradeFee High quantity
|
|
feeBuilder = setFeeBuilder()
|
|
feeBuilder.Amount = 1000
|
|
feeBuilder.PurchasePrice = 1000
|
|
if _, err := b.GetFee(context.Background(), feeBuilder); err != nil {
|
|
t.Error(err)
|
|
}
|
|
|
|
// CryptocurrencyTradeFee IsMaker
|
|
feeBuilder = setFeeBuilder()
|
|
feeBuilder.IsMaker = true
|
|
if _, err := b.GetFee(context.Background(), feeBuilder); err != nil {
|
|
t.Error(err)
|
|
}
|
|
|
|
// CryptocurrencyTradeFee Negative purchase price
|
|
feeBuilder = setFeeBuilder()
|
|
feeBuilder.PurchasePrice = -1000
|
|
if _, err := b.GetFee(context.Background(), feeBuilder); err != nil {
|
|
t.Error(err)
|
|
}
|
|
|
|
// CryptocurrencyWithdrawalFee Basic
|
|
feeBuilder = setFeeBuilder()
|
|
feeBuilder.FeeType = exchange.CryptocurrencyWithdrawalFee
|
|
if _, err := b.GetFee(context.Background(), feeBuilder); err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
// CryptocurrencyDepositFee Basic
|
|
feeBuilder = setFeeBuilder()
|
|
feeBuilder.FeeType = exchange.CryptocurrencyDepositFee
|
|
if _, err := b.GetFee(context.Background(), feeBuilder); err != nil {
|
|
t.Error(err)
|
|
}
|
|
|
|
// InternationalBankDepositFee Basic
|
|
feeBuilder = setFeeBuilder()
|
|
feeBuilder.FeeType = exchange.InternationalBankDepositFee
|
|
feeBuilder.FiatCurrency = currency.HKD
|
|
if _, err := b.GetFee(context.Background(), feeBuilder); err != nil {
|
|
t.Error(err)
|
|
}
|
|
|
|
// InternationalBankWithdrawalFee Basic
|
|
feeBuilder = setFeeBuilder()
|
|
feeBuilder.FeeType = exchange.InternationalBankWithdrawalFee
|
|
feeBuilder.FiatCurrency = currency.HKD
|
|
if _, err := b.GetFee(context.Background(), feeBuilder); err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestFormatWithdrawPermissions(t *testing.T) {
|
|
t.Parallel()
|
|
expectedResult := exchange.AutoWithdrawCryptoWithAPIPermissionText + " & " + exchange.AutoWithdrawFiatWithAPIPermissionText
|
|
withdrawPermissions := b.FormatWithdrawPermissions()
|
|
if withdrawPermissions != expectedResult {
|
|
t.Errorf("Expected: %s, Received: %s", expectedResult, withdrawPermissions)
|
|
}
|
|
}
|
|
|
|
func TestGetActiveOrders(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, b)
|
|
var getOrdersRequest = order.MultiOrderRequest{
|
|
Type: order.AnyType,
|
|
AssetType: asset.Spot,
|
|
Side: order.AnySide,
|
|
}
|
|
|
|
_, err := b.GetActiveOrders(context.Background(), &getOrdersRequest)
|
|
if sharedtestvalues.AreAPICredentialsSet(b) && err != nil {
|
|
t.Errorf("Could not get open orders: %s", err)
|
|
} else if !sharedtestvalues.AreAPICredentialsSet(b) && err == nil {
|
|
t.Error("Expecting an error when no keys are set")
|
|
}
|
|
}
|
|
|
|
func TestGetOrderHistory(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, b)
|
|
var getOrdersRequest = order.MultiOrderRequest{
|
|
Type: order.AnyType,
|
|
AssetType: asset.Spot,
|
|
Side: order.AnySide,
|
|
}
|
|
_, err := b.GetOrderHistory(context.Background(), &getOrdersRequest)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
// Any tests below this line have the ability to impact your orders on the exchange. Enable canManipulateRealOrders to run them
|
|
// ----------------------------------------------------------------------------------------------------------------------------
|
|
|
|
func TestSubmitOrder(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCannotManipulateOrders(t, b, canManipulateRealOrders)
|
|
var orderSubmission = &order.Submit{
|
|
Exchange: b.Name,
|
|
Pair: currency.Pair{
|
|
Delimiter: "_",
|
|
Base: currency.XRP,
|
|
Quote: currency.USD,
|
|
},
|
|
AssetType: asset.Spot,
|
|
Side: order.Sell,
|
|
Type: order.Limit,
|
|
Price: 1000,
|
|
Amount: 20,
|
|
ClientID: "meowOrder",
|
|
}
|
|
response, err := b.SubmitOrder(context.Background(), orderSubmission)
|
|
|
|
if sharedtestvalues.AreAPICredentialsSet(b) && err != nil {
|
|
t.Fatalf("Could not place order: %v", err)
|
|
}
|
|
if sharedtestvalues.AreAPICredentialsSet(b) && response.Status != order.New {
|
|
t.Error("Order not placed")
|
|
}
|
|
if !sharedtestvalues.AreAPICredentialsSet(b) && err == nil {
|
|
t.Error("Expecting an error when no keys are set")
|
|
}
|
|
}
|
|
|
|
func TestCancelExchangeOrder(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCannotManipulateOrders(t, b, canManipulateRealOrders)
|
|
|
|
currencyPair := currency.NewPair(currency.LTC, currency.BTC)
|
|
var orderCancellation = &order.Cancel{
|
|
OrderID: "1",
|
|
WalletAddress: core.BitcoinDonationAddress,
|
|
AccountID: "1",
|
|
Pair: currencyPair,
|
|
AssetType: asset.Spot,
|
|
}
|
|
|
|
err := b.CancelOrder(context.Background(), orderCancellation)
|
|
if !sharedtestvalues.AreAPICredentialsSet(b) && err == nil {
|
|
t.Error("Expecting an error when no keys are set")
|
|
}
|
|
if sharedtestvalues.AreAPICredentialsSet(b) && err != nil {
|
|
t.Errorf("Could not cancel orders: %v", err)
|
|
}
|
|
}
|
|
|
|
func TestCancelAllExchangeOrdera(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCannotManipulateOrders(t, b, canManipulateRealOrders)
|
|
|
|
currencyPair := currency.NewPair(currency.LTC, currency.BTC)
|
|
var orderCancellation = &order.Cancel{
|
|
OrderID: "1",
|
|
WalletAddress: core.BitcoinDonationAddress,
|
|
AccountID: "1",
|
|
Pair: currencyPair,
|
|
AssetType: asset.Spot,
|
|
}
|
|
|
|
resp, err := b.CancelAllOrders(context.Background(), orderCancellation)
|
|
|
|
if !sharedtestvalues.AreAPICredentialsSet(b) && err == nil {
|
|
t.Error("Expecting an error when no keys are set")
|
|
}
|
|
if sharedtestvalues.AreAPICredentialsSet(b) && 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) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, b, canManipulateRealOrders)
|
|
_, err := b.ModifyOrder(
|
|
context.Background(),
|
|
&order.Modify{
|
|
OrderID: "1337",
|
|
AssetType: asset.Spot,
|
|
Pair: currency.NewPair(currency.BTC, currency.USD),
|
|
})
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestWithdraw(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCannotManipulateOrders(t, b, canManipulateRealOrders)
|
|
|
|
withdrawCryptoRequest := withdraw.Request{
|
|
Exchange: b.Name,
|
|
Amount: -1,
|
|
Currency: currency.USDT,
|
|
Description: "WITHDRAW IT ALL",
|
|
Crypto: withdraw.CryptoRequest{
|
|
Address: "0x1nv4l1d",
|
|
Chain: "tetheruse",
|
|
},
|
|
}
|
|
|
|
_, err := b.WithdrawCryptocurrencyFunds(context.Background(),
|
|
&withdrawCryptoRequest)
|
|
if !sharedtestvalues.AreAPICredentialsSet(b) && err == nil {
|
|
t.Error("Expecting an error when no keys are set")
|
|
}
|
|
if sharedtestvalues.AreAPICredentialsSet(b) && err != nil {
|
|
t.Errorf("Withdraw failed to be placed: %v", err)
|
|
}
|
|
}
|
|
|
|
func TestWithdrawFiat(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCannotManipulateOrders(t, b, canManipulateRealOrders)
|
|
|
|
var withdrawFiatRequest = withdraw.Request{
|
|
Amount: -1,
|
|
Currency: currency.USD,
|
|
Description: "WITHDRAW IT ALL",
|
|
Fiat: withdraw.FiatRequest{
|
|
WireCurrency: currency.USD.String(),
|
|
},
|
|
}
|
|
|
|
_, err := b.WithdrawFiatFunds(context.Background(), &withdrawFiatRequest)
|
|
if !sharedtestvalues.AreAPICredentialsSet(b) && err == nil {
|
|
t.Error("Expecting an error when no keys are set")
|
|
}
|
|
if sharedtestvalues.AreAPICredentialsSet(b) && err != nil {
|
|
t.Errorf("Withdraw failed to be placed: %v", err)
|
|
}
|
|
}
|
|
|
|
func TestWithdrawInternationalBank(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCannotManipulateOrders(t, b, canManipulateRealOrders)
|
|
|
|
var withdrawFiatRequest = withdraw.Request{
|
|
Amount: -1,
|
|
Currency: currency.BTC,
|
|
Description: "WITHDRAW IT ALL",
|
|
Fiat: withdraw.FiatRequest{
|
|
WireCurrency: currency.USD.String(),
|
|
RequiresIntermediaryBank: true,
|
|
IsExpressWire: false,
|
|
IntermediaryBankAccountNumber: 12345,
|
|
IntermediaryBankAddress: "123 Fake St",
|
|
IntermediaryBankCity: "Tarry Town",
|
|
IntermediaryBankCountry: "Hyrule",
|
|
IntermediaryBankName: "Federal Reserve Bank",
|
|
IntermediarySwiftCode: "Taylor",
|
|
},
|
|
}
|
|
|
|
_, err := b.WithdrawFiatFundsToInternationalBank(context.Background(),
|
|
&withdrawFiatRequest)
|
|
if !sharedtestvalues.AreAPICredentialsSet(b) && err == nil {
|
|
t.Error("Expecting an error when no keys are set")
|
|
}
|
|
if sharedtestvalues.AreAPICredentialsSet(b) && err != nil {
|
|
t.Errorf("Withdraw failed to be placed: %v", err)
|
|
}
|
|
}
|
|
|
|
func TestGetDepositAddress(t *testing.T) {
|
|
t.Parallel()
|
|
if sharedtestvalues.AreAPICredentialsSet(b) {
|
|
_, err := b.GetDepositAddress(context.Background(), currency.USDT, "", "TETHERUSE")
|
|
if err != nil {
|
|
t.Error("GetDepositAddress() error", err)
|
|
}
|
|
} else {
|
|
_, err := b.GetDepositAddress(context.Background(), currency.BTC, "deposit", "")
|
|
if err == nil {
|
|
t.Error("GetDepositAddress() error cannot be nil")
|
|
}
|
|
}
|
|
}
|
|
|
|
func setupWs() {
|
|
var dialer websocket.Dialer
|
|
err := b.Websocket.AuthConn.Dial(&dialer, http.Header{})
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
go b.wsReadData(b.Websocket.AuthConn)
|
|
go b.WsDataHandler()
|
|
}
|
|
|
|
// TestWsAuth dials websocket, sends login request.
|
|
func TestWsAuth(t *testing.T) {
|
|
if !b.Websocket.IsEnabled() && !b.API.AuthenticatedWebsocketSupport {
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, b)
|
|
}
|
|
runAuth(t)
|
|
}
|
|
|
|
//nolint:gocritic // Only used as a testing helper function in this package
|
|
func runAuth(t *testing.T) {
|
|
t.Helper()
|
|
setupWs()
|
|
if err := b.WsSendAuth(context.Background()); err != nil {
|
|
t.Error(err)
|
|
}
|
|
timer := time.NewTimer(sharedtestvalues.WebsocketResponseDefaultTimeout)
|
|
select {
|
|
case resp := <-b.Websocket.DataHandler:
|
|
if logResponse, ok := resp.(map[string]interface{}); ok {
|
|
if logResponse["event"] != "auth" && logResponse["status"] != "OK" {
|
|
t.Error("expected successful login")
|
|
}
|
|
} else {
|
|
t.Error("Unexpected response")
|
|
}
|
|
case <-timer.C:
|
|
t.Error("Have not received a response")
|
|
}
|
|
timer.Stop()
|
|
wsAuthExecuted = true
|
|
}
|
|
|
|
// TestWsPlaceOrder dials websocket, sends order request.
|
|
func TestWsPlaceOrder(t *testing.T) {
|
|
if !b.Websocket.IsEnabled() && !b.API.AuthenticatedWebsocketSupport {
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, b)
|
|
}
|
|
if !wsAuthExecuted {
|
|
runAuth(t)
|
|
}
|
|
|
|
_, err := b.WsNewOrder(&WsNewOrderRequest{
|
|
GroupID: 1,
|
|
Type: "EXCHANGE LIMIT",
|
|
Symbol: "tXRPUSD",
|
|
Amount: -20,
|
|
Price: 1000,
|
|
})
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
// TestWsCancelOrder dials websocket, sends cancel request.
|
|
func TestWsCancelOrder(t *testing.T) {
|
|
if !b.Websocket.IsEnabled() && !b.API.AuthenticatedWebsocketSupport {
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, b)
|
|
}
|
|
if !wsAuthExecuted {
|
|
runAuth(t)
|
|
}
|
|
if err := b.WsCancelOrder(1234); err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
// TestWsCancelOrder dials websocket, sends modify request.
|
|
func TestWsUpdateOrder(t *testing.T) {
|
|
if !b.Websocket.IsEnabled() && !b.API.AuthenticatedWebsocketSupport {
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, b)
|
|
}
|
|
if !wsAuthExecuted {
|
|
runAuth(t)
|
|
}
|
|
err := b.WsModifyOrder(&WsUpdateOrderRequest{
|
|
OrderID: 1234,
|
|
Price: -111,
|
|
Amount: 111,
|
|
})
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
// TestWsCancelAllOrders dials websocket, sends cancel all request.
|
|
func TestWsCancelAllOrders(t *testing.T) {
|
|
if !b.Websocket.IsEnabled() && !b.API.AuthenticatedWebsocketSupport {
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, b)
|
|
}
|
|
if !wsAuthExecuted {
|
|
runAuth(t)
|
|
}
|
|
if err := b.WsCancelAllOrders(); err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
// TestWsCancelAllOrders dials websocket, sends cancel all request.
|
|
func TestWsCancelMultiOrders(t *testing.T) {
|
|
if !b.Websocket.IsEnabled() && !b.API.AuthenticatedWebsocketSupport {
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, b)
|
|
}
|
|
if !wsAuthExecuted {
|
|
runAuth(t)
|
|
}
|
|
err := b.WsCancelMultiOrders([]int64{1, 2, 3, 4})
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
// TestWsNewOffer dials websocket, sends new offer request.
|
|
func TestWsNewOffer(t *testing.T) {
|
|
if !b.Websocket.IsEnabled() && !b.API.AuthenticatedWebsocketSupport {
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, b)
|
|
}
|
|
if !wsAuthExecuted {
|
|
runAuth(t)
|
|
}
|
|
err := b.WsNewOffer(&WsNewOfferRequest{
|
|
Type: order.Limit.String(),
|
|
Symbol: "fBTC",
|
|
Amount: -10,
|
|
Rate: 10,
|
|
Period: 30,
|
|
})
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
// TestWsCancelOffer dials websocket, sends cancel offer request.
|
|
func TestWsCancelOffer(t *testing.T) {
|
|
if !b.Websocket.IsEnabled() && !b.API.AuthenticatedWebsocketSupport {
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, b)
|
|
}
|
|
if !wsAuthExecuted {
|
|
runAuth(t)
|
|
}
|
|
if err := b.WsCancelOffer(1234); err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestWsSubscribedResponse(t *testing.T) {
|
|
b.Websocket.AddSuccessfulSubscriptions(stream.ChannelSubscription{Asset: asset.Spot, Currency: btcusdPair, Channel: wsTicker, Params: map[string]interface{}{"chanId": 224555}})
|
|
if err := b.wsHandleData([]byte(`{"event":"subscribed","channel":"ticker","chanId":224555,"symbol":"tBTCUSD","pair":"BTCUSD"}`)); err != nil {
|
|
t.Error(err)
|
|
}
|
|
|
|
// Spot Candles
|
|
b.Websocket.AddSuccessfulSubscriptions(stream.ChannelSubscription{Asset: asset.Spot, Currency: btcusdPair, Channel: wsCandles, Params: map[string]interface{}{"chanId": 224556}})
|
|
if err := b.wsHandleData([]byte(`{"event":"subscribed","channel":"candles","chanId":224556,"key":"trade:1m:tBTCUSD"}`)); err != nil {
|
|
t.Error(err)
|
|
}
|
|
|
|
pair, err := currency.NewPairFromString("BTC:CNHT")
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
b.Websocket.AddSuccessfulSubscriptions(stream.ChannelSubscription{Asset: asset.Spot, Currency: pair, Channel: wsCandles, Params: map[string]interface{}{"chanId": 224557}})
|
|
pressXToJSON := `{"event":"subscribed","channel":"candles","chanId":224557,"key":"trade:1m:tBTC:CNHT"}`
|
|
if err = b.wsHandleData([]byte(pressXToJSON)); err != nil {
|
|
t.Error(err)
|
|
}
|
|
|
|
// Margin Candles
|
|
pair, err = currency.NewPairFromString("BTC")
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
b.Websocket.AddSuccessfulSubscriptions(stream.ChannelSubscription{Asset: asset.MarginFunding, Currency: pair, Channel: wsCandles, Params: map[string]interface{}{"chanId": 224558}})
|
|
if e2 := b.wsHandleData([]byte(`{"event":"subscribed","channel":"candles","chanId":224558,"key":"trade:1m:fBTC:a30:p2:p30"}`)); e2 != nil {
|
|
t.Error(e2)
|
|
}
|
|
|
|
pair, err = currency.NewPairFromString("USD")
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
b.Websocket.AddSuccessfulSubscriptions(stream.ChannelSubscription{Asset: asset.MarginFunding, Currency: pair, Channel: wsCandles, Params: map[string]interface{}{"chanId": 224559}})
|
|
if e2 := b.wsHandleData([]byte(`{"event":"subscribed","channel":"candles","chanId":224559,"key":"trade:1m:fUSD:p30"}`)); e2 != nil {
|
|
t.Error(e2)
|
|
}
|
|
}
|
|
|
|
func TestWsTradingPairSnapshot(t *testing.T) {
|
|
b.WebsocketSubdChannels[23405] = &stream.ChannelSubscription{Asset: asset.Spot, Currency: btcusdPair, Channel: wsBook, Params: map[string]interface{}{"chanId": 23405}}
|
|
pressXToJSON := `[23405,[[38334303613,9348.8,0.53],[38334308111,9348.8,5.98979404],[38331335157,9344.1,1.28965787],[38334302803,9343.8,0.08230094],[38334279092,9343,0.8],[38334307036,9342.938663676,0.8],[38332749107,9342.9,0.2],[38332277330,9342.8,0.85],[38329406786,9342,0.1432012],[38332841570,9341.947288638,0.3],[38332163238,9341.7,0.3],[38334303384,9341.6,0.324],[38332464840,9341.4,0.5],[38331935870,9341.2,0.5],[38334312082,9340.9,0.02126899],[38334261292,9340.8,0.26763],[38334138680,9340.625455254,0.12],[38333896802,9339.8,0.85],[38331627527,9338.9,1.57863959],[38334186713,9338.9,0.26769],[38334305819,9338.8,2.999],[38334211180,9338.75285796,3.999],[38334310699,9337.8,0.10679883],[38334307414,9337.5,1],[38334179822,9337.1,0.26773],[38334306600,9336.659955102,1.79],[38334299667,9336.6,1.1],[38334306452,9336.6,0.13979771],[38325672859,9336.3,1.25],[38334311646,9336.2,1],[38334258509,9336.1,0.37],[38334310592,9336,1.79],[38334310378,9335.6,1.43],[38334132444,9335.2,0.26777],[38331367325,9335,0.07],[38334310703,9335,0.10680562],[38334298209,9334.7,0.08757301],[38334304857,9334.456899462,0.291],[38334309940,9334.088390727,0.0725],[38334310377,9333.7,1.2868],[38334297615,9333.607784,0.1108],[38334095188,9333.3,0.26785],[38334228913,9332.7,0.40861186],[38334300526,9332.363996604,0.3884],[38334310701,9332.2,0.10680562],[38334303548,9332.005382871,0.07],[38334311798,9331.8,0.41285228],[38334301012,9331.7,1.7952],[38334089877,9331.4,0.2679],[38321942150,9331.2,0.2],[38334310670,9330,1.069],[38334063096,9329.6,0.26796],[38334310700,9329.4,0.10680562],[38334310404,9329.3,1],[38334281630,9329.1,6.57150597],[38334036864,9327.7,0.26801],[38334310702,9326.6,0.10680562],[38334311799,9326.1,0.50220625],[38334164163,9326,0.219638],[38334309722,9326,1.5],[38333051682,9325.8,0.26807],[38334302027,9325.7,0.75],[38334203435,9325.366592,0.32397696],[38321967613,9325,0.05],[38334298787,9324.9,0.3],[38334301719,9324.8,3.6227592],[38331316716,9324.763454646,0.71442],[38334310698,9323.8,0.10680562],[38334035499,9323.7,0.23431017],[38334223472,9322.670551788,0.42150603],[38334163459,9322.560399006,0.143967],[38321825171,9320.8,2],[38334075805,9320.467496148,0.30772633],[38334075800,9319.916732238,0.61457592],[38333682302,9319.7,0.0011],[38331323088,9319.116771762,0.12913],[38333677480,9319,0.0199],[38334277797,9318.6,0.89],[38325235155,9318.041088,1.20249],[38334310910,9317.82382938,1.79],[38334311811,9317.2,0.61079138],[38334311812,9317.2,0.71937652],[38333298214,9317.1,50],[38334306359,9317,1.79],[38325531545,9316.382823951,0.21263],[38333727253,9316.3,0.02316372],[38333298213,9316.1,45],[38333836479,9316,2.135],[38324520465,9315.9,2.7681],[38334307411,9315.5,1],[38330313617,9315.3,0.84455],[38334077770,9315.294024,0.01248397],[38334286663,9315.294024,1],[38325533762,9315.290315394,2.40498],[38334310018,9315.2,3],[38333682617,9314.6,0.0011],[38334304794,9314.6,0.76364676],[38334304798,9314.3,0.69242113],[38332915733,9313.8,0.0199],[38334084411,9312.8,1],[38334311893,9350.1,-1.015],[38334302734,9350.3,-0.26737],[38334300732,9350.8,-5.2],[38333957619,9351,-0.90677089],[38334300521,9351,-1.6457],[38334301600,9351.012829557,-0.0523],[38334308878,9351.7,-2.5],[38334299570,9351.921544,-0.1015],[38334279367,9352.1,-0.26732],[38334299569,9352.411802928,-0.4036],[38334202773,9353.4,-0.02139404],[38333918472,9353.7,-1.96412776],[38334278782,9354,-0.26731],[38334278606,9355,-1.2785],[38334302105,9355.439221251,-0.79191542],[38313897370,9355.569409242,-0.43363],[38334292995,9355.584296,-0.0979],[38334216989,9355.8,-0.03686414],[38333894025,9355.9,-0.26721],[38334293798,9355.936691952,-0.4311],[38331159479,9356,-0.4204022],[38333918888,9356.1,-1.10885563],[38334298205,9356.4,-0.20124428],[38328427481,9356.5,-0.1],[38333343289,9356.6,-0.41034213],[38334297205,9356.6,-0.08835018],[38334277927,9356.741101161,-0.0737],[38334311645,9356.8,-0.5],[38334309002,9356.9,-5],[38334309736,9357,-0.10680107],[38334306448,9357.4,-0.18645275],[38333693302,9357.7,-0.2672],[38332815159,9357.8,-0.0011],[38331239824,9358.2,-0.02],[38334271608,9358.3,-2.999],[38334311971,9358.4,-0.55],[38333919260,9358.5,-1.9972841],[38334265365,9358.5,-1.7841],[38334277960,9359,-3],[38334274601,9359.020969848,-3],[38326848839,9359.1,-0.84],[38334291080,9359.247048,-0.16199869],[38326848844,9359.4,-1.84],[38333680200,9359.6,-0.26713],[38331326606,9359.8,-0.84454],[38334309738,9359.8,-0.10680107],[38331314707,9359.9,-0.2],[38333919803,9360.9,-1.41177599],[38323651149,9361.33417827,-0.71442],[38333656906,9361.5,-0.26705],[38334035500,9361.5,-0.40861586],[38334091886,9362.4,-6.85940815],[38334269617,9362.5,-4],[38323629409,9362.545858872,-2.40497],[38334309737,9362.7,-0.10680107],[38334312380,9362.7,-3],[38325280830,9362.8,-1.75123],[38326622800,9362.8,-1.05145],[38333175230,9363,-0.0011],[38326848745,9363.2,-0.79],[38334308960,9363.206775564,-0.12],[38333920234,9363.3,-1.25318113],[38326848843,9363.4,-1.29],[38331239823,9363.4,-0.02],[38333209613,9363.4,-0.26719],[38334299964,9364,-0.05583123],[38323470224,9364.161816648,-0.12912],[38334284711,9365,-0.21346019],[38334299594,9365,-2.6757062],[38323211816,9365.073132585,-0.21262],[38334312456,9365.1,-0.11167861],[38333209612,9365.2,-0.26719],[38327770474,9365.3,-0.0073],[38334298788,9365.3,-0.3],[38334075803,9365.409831204,-0.30772637],[38334309740,9365.5,-0.10680107],[38326608767,9365.7,-2.76809],[38333920657,9365.7,-1.25848083],[38329594226,9366.6,-0.02587],[38334311813,9366.7,-4.72290945],[38316386301,9367.39258128,-2.37581],[38334302026,9367.4,-4.5],[38334228915,9367.9,-0.81725458],[38333921381,9368.1,-1.72213641],[38333175678,9368.2,-0.0011],[38334301150,9368.2,-2.654604],[38334297208,9368.3,-0.78036466],[38334309739,9368.3,-0.10680107],[38331227515,9368.7,-0.02],[38331184470,9369,-0.003975],[38334203436,9369.319616,-0.32397695],[38334269964,9369.7,-0.5],[38328386732,9370,-4.11759935],[38332719555,9370,-0.025],[38333921935,9370.5,-1.2224398],[38334258511,9370.5,-0.35],[38326848842,9370.8,-0.34],[38333985038,9370.9,-0.8551502],[38334283018,9370.9,-1],[38326848744,9371,-1.34]],5]`
|
|
err := b.wsHandleData([]byte(pressXToJSON))
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
pressXToJSON = `[23405,[7617,52.98726298,7617.1,53.601795929999994,-550.9,-0.0674,7617,8318.92961981,8257.8,7500],6]`
|
|
err = b.wsHandleData([]byte(pressXToJSON))
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestWsTradeResponse(t *testing.T) {
|
|
b.WebsocketSubdChannels[18788] = &stream.ChannelSubscription{Asset: asset.Spot, Currency: btcusdPair, Channel: wsTrades}
|
|
pressXToJSON := `[18788,[[412685577,1580268444802,11.1998,176.3],[412685575,1580268444802,5,176.29952759],[412685574,1580268374717,1.99069999,176.41],[412685573,1580268374717,1.00930001,176.41],[412685572,1580268358760,0.9907,176.47],[412685571,1580268324362,0.5505,176.44],[412685570,1580268297270,-0.39040819,176.39],[412685568,1580268297270,-0.39780162,176.46475676],[412685567,1580268283470,-0.09,176.41],[412685566,1580268256536,-2.31310783,176.48],[412685565,1580268256536,-0.59669217,176.49],[412685564,1580268256536,-0.9902,176.49],[412685562,1580268194474,0.9902,176.55],[412685561,1580268186215,0.1,176.6],[412685560,1580268185964,-2.17096773,176.5],[412685559,1580268185964,-1.82903227,176.51],[412685558,1580268181215,2.098914,176.53],[412685557,1580268169844,16.7302,176.55],[412685556,1580268169844,3.25,176.54],[412685555,1580268155725,0.23576115,176.45],[412685553,1580268155725,3,176.44596249],[412685552,1580268155725,3.25,176.44],[412685551,1580268155725,5,176.44],[412685550,1580268155725,0.65830078,176.41],[412685549,1580268155725,0.45063807,176.41],[412685548,1580268153825,-0.67604704,176.39],[412685547,1580268145713,2.5883,176.41],[412685543,1580268087513,12.92927,176.33],[412685542,1580268087513,0.40083,176.33],[412685533,1580268005756,-0.17096773,176.32]]]`
|
|
err := b.wsHandleData([]byte(pressXToJSON))
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestWsTickerResponse(t *testing.T) {
|
|
b.WebsocketSubdChannels[11534] = &stream.ChannelSubscription{Asset: asset.Spot, Currency: btcusdPair, Channel: wsTicker}
|
|
pressXToJSON := `[11534,[61.304,2228.36155358,61.305,1323.2442970500003,0.395,0.0065,61.371,50973.3020771,62.5,57.421]]`
|
|
err := b.wsHandleData([]byte(pressXToJSON))
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
pair, err := currency.NewPairFromString("XAUTF0:USTF0")
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
b.WebsocketSubdChannels[123412] = &stream.ChannelSubscription{Asset: asset.Spot, Currency: pair, Channel: wsTicker}
|
|
pressXToJSON = `[123412,[61.304,2228.36155358,61.305,1323.2442970500003,0.395,0.0065,61.371,50973.3020771,62.5,57.421]]`
|
|
err = b.wsHandleData([]byte(pressXToJSON))
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
pair, err = currency.NewPairFromString("trade:1m:tXRPUSD")
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
b.WebsocketSubdChannels[123413] = &stream.ChannelSubscription{Asset: asset.Spot, Currency: pair, Channel: wsTicker}
|
|
pressXToJSON = `[123413,[61.304,2228.36155358,61.305,1323.2442970500003,0.395,0.0065,61.371,50973.3020771,62.5,57.421]]`
|
|
err = b.wsHandleData([]byte(pressXToJSON))
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
pair, err = currency.NewPairFromString("trade:1m:fZRX:p30")
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
b.WebsocketSubdChannels[123414] = &stream.ChannelSubscription{Asset: asset.Spot, Currency: pair, Channel: wsTicker}
|
|
pressXToJSON = `[123414,[61.304,2228.36155358,61.305,1323.2442970500003,0.395,0.0065,61.371,50973.3020771,62.5,57.421]]`
|
|
err = b.wsHandleData([]byte(pressXToJSON))
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestWsCandleResponse(t *testing.T) {
|
|
b.WebsocketSubdChannels[343351] = &stream.ChannelSubscription{Asset: asset.Spot, Currency: btcusdPair, Channel: wsCandles}
|
|
pressXToJSON := `[343351,[[1574698260000,7379.785503,7383.8,7388.3,7379.785503,1.68829482]]]`
|
|
err := b.wsHandleData([]byte(pressXToJSON))
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
pressXToJSON = `[343351,[1574698200000,7399.9,7379.7,7399.9,7371.8,41.63633658]]`
|
|
err = b.wsHandleData([]byte(pressXToJSON))
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestWsOrderSnapshot(t *testing.T) {
|
|
pressXToJSON := `[0,"os",[[34930659963,null,1574955083558,"tETHUSD",1574955083558,1574955083573,0.201104,0.201104,"EXCHANGE LIMIT",null,null,null,0,"ACTIVE",null,null,120,0,0,0,null,null,null,0,0,null,null,null,"BFX",null,null,null]]]`
|
|
err := b.wsHandleData([]byte(pressXToJSON))
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
pressXToJSON = `[0,"oc",[34930659963,null,1574955083558,"tETHUSD",1574955083558,1574955354487,0.201104,0.201104,"EXCHANGE LIMIT",null,null,null,0,"CANCELED",null,null,120,0,0,0,null,null,null,0,0,null,null,null,"BFX",null,null,null]]`
|
|
err = b.wsHandleData([]byte(pressXToJSON))
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestWsNotifications(t *testing.T) {
|
|
pressXToJSON := `[0,"n",[1575282446099,"fon-req",null,null,[41238905,null,null,null,-1000,null,null,null,null,null,null,null,null,null,0.002,2,null,null,null,null,null],null,"SUCCESS","Submitting funding bid of 1000.0 USD at 0.2000 for 2 days."]]`
|
|
err := b.wsHandleData([]byte(pressXToJSON))
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
|
|
pressXToJSON = `[0,"n",[1575287438.515,"on-req",null,null,[1185815098,null,1575287436979,"tETHUSD",1575287438515,1575287438515,-2.5,-2.5,"LIMIT",null,null,null,0,"ACTIVE",null,null,230,0,0,0,null,null,null,0,null,null,null,null,"API>BFX",null,null,null],null,"SUCCESS","Submitting limit sell order for -2.5 ETH."]]`
|
|
err = b.wsHandleData([]byte(pressXToJSON))
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestWSFundingOfferSnapshotAndUpdate(t *testing.T) {
|
|
pressXToJSON := `[0,"fos",[[41237920,"fETH",1573912039000,1573912039000,0.5,0.5,"LIMIT",null,null,0,"ACTIVE",null,null,null,0.0024,2,0,0,null,0,null]]]`
|
|
if err := b.wsHandleData([]byte(pressXToJSON)); err != nil {
|
|
t.Error(err)
|
|
}
|
|
|
|
pressXToJSON = `[0,"fon",[41238747,"fUST",1575026670000,1575026670000,5000,5000,"LIMIT",null,null,0,"ACTIVE",null,null,null,0.006000000000000001,30,0,0,null,0,null]]`
|
|
if err := b.wsHandleData([]byte(pressXToJSON)); err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestWSFundingCreditSnapshotAndUpdate(t *testing.T) {
|
|
pressXToJSON := `[0,"fcs",[[26223578,"fUST",1,1575052261000,1575296187000,350,0,"ACTIVE",null,null,null,0,30,1575052261000,1575293487000,0,0,null,0,null,0,"tBTCUST"],[26223711,"fUSD",-1,1575291961000,1575296187000,180,0,"ACTIVE",null,null,null,0.002,7,1575282446000,1575295587000,0,0,null,0,null,0,"tETHUSD"]]]`
|
|
if err := b.wsHandleData([]byte(pressXToJSON)); err != nil {
|
|
t.Error(err)
|
|
}
|
|
|
|
pressXToJSON = `[0,"fcu",[26223578,"fUST",1,1575052261000,1575296787000,350,0,"ACTIVE",null,null,null,0,30,1575052261000,1575293487000,0,0,null,0,null,0,"tBTCUST"]]`
|
|
if err := b.wsHandleData([]byte(pressXToJSON)); err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestWSFundingLoanSnapshotAndUpdate(t *testing.T) {
|
|
pressXToJSON := `[0,"fls",[[2995442,"fUSD",-1,1575291961000,1575295850000,820,0,"ACTIVE",null,null,null,0.002,7,1575282446000,1575295850000,0,0,null,0,null,0]]]`
|
|
if err := b.wsHandleData([]byte(pressXToJSON)); err != nil {
|
|
t.Error(err)
|
|
}
|
|
|
|
pressXToJSON = `[0,"fln",[2995444,"fUSD",-1,1575298742000,1575298742000,1000,0,"ACTIVE",null,null,null,0.002,7,1575298742000,1575298742000,0,0,null,0,null,0]]`
|
|
if err := b.wsHandleData([]byte(pressXToJSON)); err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestWSWalletSnapshot(t *testing.T) {
|
|
pressXToJSON := `[0,"ws",[["exchange","SAN",19.76,0,null,null,null]]]`
|
|
if err := b.wsHandleData([]byte(pressXToJSON)); err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestWSBalanceUpdate(t *testing.T) {
|
|
const pressXToJSON = `[0,"bu",[4131.85,4131.85]]`
|
|
if err := b.wsHandleData([]byte(pressXToJSON)); err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestWSMarginInfoUpdate(t *testing.T) {
|
|
const pressXToJSON = `[0,"miu",["base",[-13.014640000000007,0,49331.70267297,49318.68803297,27]]]`
|
|
if err := b.wsHandleData([]byte(pressXToJSON)); err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestWSFundingInfoUpdate(t *testing.T) {
|
|
const pressXToJSON = `[0,"fiu",["sym","tETHUSD",[149361.09689202666,149639.26293509,830.0182168075556,895.0658432466332]]]`
|
|
if err := b.wsHandleData([]byte(pressXToJSON)); err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestWSFundingTrade(t *testing.T) {
|
|
pressXToJSON := `[0,"fte",[636854,"fUSD",1575282446000,41238905,-1000,0.002,7,null]]`
|
|
if err := b.wsHandleData([]byte(pressXToJSON)); err != nil {
|
|
t.Error(err)
|
|
}
|
|
|
|
pressXToJSON = `[0,"ftu",[636854,"fUSD",1575282446000,41238905,-1000,0.002,7,null]]`
|
|
if err := b.wsHandleData([]byte(pressXToJSON)); err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestGetHistoricCandles(t *testing.T) {
|
|
startTime := time.Now().Add(-time.Hour * 24)
|
|
endTime := time.Now().Add(-time.Hour * 20)
|
|
|
|
if _, err := b.GetHistoricCandles(context.Background(), btcusdPair, asset.Spot, kline.OneHour, startTime, endTime); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
}
|
|
|
|
func TestGetHistoricCandlesExtended(t *testing.T) {
|
|
startTime := time.Now().Add(-time.Hour * 24)
|
|
endTime := time.Now().Add(-time.Hour * 20)
|
|
|
|
if _, err := b.GetHistoricCandlesExtended(context.Background(), btcusdPair, asset.Spot, kline.OneHour, startTime, endTime); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
}
|
|
|
|
func TestFixCasing(t *testing.T) {
|
|
ret, err := b.fixCasing(btcusdPair, asset.Spot)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if ret != "tBTCUSD" {
|
|
t.Errorf("unexpected result: %v", ret)
|
|
}
|
|
pair, err := currency.NewPairFromString("TBTCUSD")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
ret, err = b.fixCasing(pair, asset.Spot)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if ret != "tBTCUSD" {
|
|
t.Errorf("unexpected result: %v", ret)
|
|
}
|
|
pair, err = currency.NewPairFromString("tBTCUSD")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
ret, err = b.fixCasing(pair, asset.Spot)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if ret != "tBTCUSD" {
|
|
t.Errorf("unexpected result: %v", ret)
|
|
}
|
|
ret, err = b.fixCasing(btcusdPair, asset.Margin)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if ret != "tBTCUSD" {
|
|
t.Errorf("unexpected result: %v", ret)
|
|
}
|
|
ret, err = b.fixCasing(btcusdPair, asset.Spot)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if ret != "tBTCUSD" {
|
|
t.Errorf("unexpected result: %v", ret)
|
|
}
|
|
pair, err = currency.NewPairFromString("FUNETH")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
ret, err = b.fixCasing(pair, asset.Spot)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if ret != "tFUNETH" {
|
|
t.Errorf("unexpected result: %v", ret)
|
|
}
|
|
pair, err = currency.NewPairFromString("TNBUSD")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
ret, err = b.fixCasing(pair, asset.Spot)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if ret != "tTNBUSD" {
|
|
t.Errorf("unexpected result: %v", ret)
|
|
}
|
|
|
|
pair, err = currency.NewPairFromString("tTNBUSD")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
ret, err = b.fixCasing(pair, asset.Spot)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if ret != "tTNBUSD" {
|
|
t.Errorf("unexpected result: %v", ret)
|
|
}
|
|
pair, err = currency.NewPairFromStrings("fUSD", "")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
ret, err = b.fixCasing(pair, asset.MarginFunding)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if ret != "fUSD" {
|
|
t.Errorf("unexpected result: %v", ret)
|
|
}
|
|
pair, err = currency.NewPairFromStrings("USD", "")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
ret, err = b.fixCasing(pair, asset.MarginFunding)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if ret != "fUSD" {
|
|
t.Errorf("unexpected result: %v", ret)
|
|
}
|
|
|
|
pair, err = currency.NewPairFromStrings("FUSD", "")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
ret, err = b.fixCasing(pair, asset.MarginFunding)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if ret != "fUSD" {
|
|
t.Errorf("unexpected result: %v", ret)
|
|
}
|
|
|
|
_, err = b.fixCasing(currency.NewPair(currency.EMPTYCODE, currency.BTC), asset.MarginFunding)
|
|
if !errors.Is(err, currency.ErrCurrencyPairEmpty) {
|
|
t.Fatalf("received: '%v' but expected: '%v'", err, currency.ErrCurrencyPairEmpty)
|
|
}
|
|
|
|
_, err = b.fixCasing(currency.NewPair(currency.BTC, currency.EMPTYCODE), asset.MarginFunding)
|
|
if !errors.Is(err, nil) {
|
|
t.Fatalf("received: '%v' but expected: '%v'", err, nil)
|
|
}
|
|
|
|
_, err = b.fixCasing(currency.EMPTYPAIR, asset.MarginFunding)
|
|
if !errors.Is(err, currency.ErrCurrencyPairEmpty) {
|
|
t.Fatalf("received: '%v' but expected: '%v'", err, currency.ErrCurrencyPairEmpty)
|
|
}
|
|
}
|
|
|
|
func Test_FormatExchangeKlineInterval(t *testing.T) {
|
|
testCases := []struct {
|
|
name string
|
|
interval kline.Interval
|
|
output string
|
|
}{
|
|
{
|
|
"OneMin",
|
|
kline.OneMin,
|
|
"1m",
|
|
},
|
|
{
|
|
"OneDay",
|
|
kline.OneDay,
|
|
"1D",
|
|
},
|
|
{
|
|
"OneWeek",
|
|
kline.OneWeek,
|
|
"7D",
|
|
},
|
|
{
|
|
"TwoWeeks",
|
|
kline.OneWeek * 2,
|
|
"14D",
|
|
},
|
|
}
|
|
|
|
for x := range testCases {
|
|
test := testCases[x]
|
|
t.Run(test.name, func(t *testing.T) {
|
|
ret, err := b.FormatExchangeKlineInterval(test.interval)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
if ret != test.output {
|
|
t.Fatalf("unexpected result return expected: %v received: %v", test.output, ret)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestGetRecentTrades(t *testing.T) {
|
|
t.Parallel()
|
|
if _, err := b.GetRecentTrades(context.Background(), btcusdPair, asset.Spot); err != nil {
|
|
t.Error(err)
|
|
}
|
|
|
|
currencyPair, err := currency.NewPairFromString("USD")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
_, err = b.GetRecentTrades(context.Background(), currencyPair, asset.Margin)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestGetHistoricTrades(t *testing.T) {
|
|
t.Parallel()
|
|
if _, err := b.GetHistoricTrades(context.Background(),
|
|
btcusdPair, asset.Spot, time.Now().Add(-time.Minute*15), time.Now()); err != nil {
|
|
t.Error(err)
|
|
}
|
|
|
|
// longer term test
|
|
if _, err := b.GetHistoricTrades(context.Background(),
|
|
btcusdPair, asset.Spot,
|
|
time.Now().Add(-time.Hour*100),
|
|
time.Now().Add(-time.Hour*99)); err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
var testOb = orderbook.Base{
|
|
Asks: []orderbook.Item{
|
|
{Price: 0.05005, Amount: 0.00000500},
|
|
{Price: 0.05010, Amount: 0.00000500},
|
|
{Price: 0.05015, Amount: 0.00000500},
|
|
{Price: 0.05020, Amount: 0.00000500},
|
|
{Price: 0.05025, Amount: 0.00000500},
|
|
{Price: 0.05030, Amount: 0.00000500},
|
|
{Price: 0.05035, Amount: 0.00000500},
|
|
{Price: 0.05040, Amount: 0.00000500},
|
|
{Price: 0.05045, Amount: 0.00000500},
|
|
{Price: 0.05050, Amount: 0.00000500},
|
|
},
|
|
Bids: []orderbook.Item{
|
|
{Price: 0.05000, Amount: 0.00000500},
|
|
{Price: 0.04995, Amount: 0.00000500},
|
|
{Price: 0.04990, Amount: 0.00000500},
|
|
{Price: 0.04980, Amount: 0.00000500},
|
|
{Price: 0.04975, Amount: 0.00000500},
|
|
{Price: 0.04970, Amount: 0.00000500},
|
|
{Price: 0.04965, Amount: 0.00000500},
|
|
{Price: 0.04960, Amount: 0.00000500},
|
|
{Price: 0.04955, Amount: 0.00000500},
|
|
{Price: 0.04950, Amount: 0.00000500},
|
|
},
|
|
}
|
|
|
|
func TestChecksum(t *testing.T) {
|
|
err := validateCRC32(&testOb, 190468240)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
}
|
|
|
|
func TestReOrderbyID(t *testing.T) {
|
|
asks := []orderbook.Item{
|
|
{ID: 4, Price: 100, Amount: 0.00000500},
|
|
{ID: 3, Price: 100, Amount: 0.00000500},
|
|
{ID: 2, Price: 100, Amount: 0.00000500},
|
|
{ID: 1, Price: 100, Amount: 0.00000500},
|
|
{ID: 5, Price: 101, Amount: 0.00000500},
|
|
{ID: 6, Price: 102, Amount: 0.00000500},
|
|
{ID: 8, Price: 103, Amount: 0.00000500},
|
|
{ID: 7, Price: 103, Amount: 0.00000500},
|
|
{ID: 9, Price: 104, Amount: 0.00000500},
|
|
{ID: 10, Price: 105, Amount: 0.00000500},
|
|
}
|
|
reOrderByID(asks)
|
|
|
|
for i := range asks {
|
|
if asks[i].ID != int64(i+1) {
|
|
t.Fatal("order by ID failure")
|
|
}
|
|
}
|
|
|
|
bids := []orderbook.Item{
|
|
{ID: 4, Price: 100, Amount: 0.00000500},
|
|
{ID: 3, Price: 100, Amount: 0.00000500},
|
|
{ID: 2, Price: 100, Amount: 0.00000500},
|
|
{ID: 1, Price: 100, Amount: 0.00000500},
|
|
{ID: 5, Price: 99, Amount: 0.00000500},
|
|
{ID: 6, Price: 98, Amount: 0.00000500},
|
|
{ID: 8, Price: 97, Amount: 0.00000500},
|
|
{ID: 7, Price: 97, Amount: 0.00000500},
|
|
{ID: 9, Price: 96, Amount: 0.00000500},
|
|
{ID: 10, Price: 95, Amount: 0.00000500},
|
|
}
|
|
reOrderByID(bids)
|
|
|
|
for i := range bids {
|
|
if bids[i].ID != int64(i+1) {
|
|
t.Fatal("order by ID failure")
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestPopulateAcceptableMethods(t *testing.T) {
|
|
t.Parallel()
|
|
if acceptableMethods.loaded() {
|
|
// we may have been loaded from another test, so reset
|
|
acceptableMethods.m.Lock()
|
|
acceptableMethods.a = make(map[string][]string)
|
|
acceptableMethods.m.Unlock()
|
|
if acceptableMethods.loaded() {
|
|
t.Error("expected false")
|
|
}
|
|
}
|
|
if err := b.PopulateAcceptableMethods(context.Background()); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if !acceptableMethods.loaded() {
|
|
t.Error("acceptable method store should be loaded")
|
|
}
|
|
if methods := acceptableMethods.lookup(currency.NewCode("UST")); len(methods) == 0 {
|
|
t.Error("USDT should have many available methods")
|
|
}
|
|
if methods := acceptableMethods.lookup(currency.NewCode("ASdasdasdasd")); len(methods) != 0 {
|
|
t.Error("non-existent code should return no methods")
|
|
}
|
|
// since we're already loaded, this will return nil
|
|
if err := b.PopulateAcceptableMethods(context.Background()); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
}
|
|
|
|
func TestGetAvailableTransferChains(t *testing.T) {
|
|
t.Parallel()
|
|
r, err := b.GetAvailableTransferChains(context.Background(), currency.USDT)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if len(r) < 2 {
|
|
t.Error("there should be many available USDT transfer chains")
|
|
}
|
|
}
|
|
|
|
func TestAccetableMethodStore(t *testing.T) {
|
|
t.Parallel()
|
|
var a acceptableMethodStore
|
|
if a.loaded() {
|
|
t.Error("should be empty")
|
|
}
|
|
data := map[string][]string{
|
|
"BITCOIN": {"BTC"},
|
|
"TETHER1": {"UST"},
|
|
"TETHER2": {"UST"},
|
|
}
|
|
a.load(data)
|
|
if !a.loaded() {
|
|
t.Error("data should be loaded")
|
|
}
|
|
if name := a.lookup(currency.NewCode("BTC")); len(name) != 1 && name[1] != "BITCOIN" {
|
|
t.Error("incorrect values")
|
|
}
|
|
if name := a.lookup(currency.NewCode("UST")); (name[0] != "TETHER1" && name[1] != "TETHER2") &&
|
|
(name[0] != "TETHER2" && name[1] != "TETHER1") {
|
|
t.Errorf("incorrect values")
|
|
}
|
|
if name := a.lookup(currency.NewCode("PANDA_HORSE")); len(name) != 0 {
|
|
t.Error("incorrect values")
|
|
}
|
|
}
|
|
|
|
func TestGetSiteListConfigData(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
_, err := b.GetSiteListConfigData(context.Background(), "")
|
|
if !errors.Is(err, errSetCannotBeEmpty) {
|
|
t.Fatalf("received: %v, expected: %v", err, errSetCannotBeEmpty)
|
|
}
|
|
|
|
pairs, err := b.GetSiteListConfigData(context.Background(), bitfinexSecuritiesPairs)
|
|
if !errors.Is(err, nil) {
|
|
t.Fatalf("received: %v, expected: %v", err, nil)
|
|
}
|
|
|
|
if len(pairs) == 0 {
|
|
t.Fatal("expected pairs")
|
|
}
|
|
}
|
|
|
|
func TestGetSiteInfoConfigData(t *testing.T) {
|
|
t.Parallel()
|
|
for _, assetType := range []asset.Item{asset.Spot, asset.Futures} {
|
|
pairs, err := b.GetSiteInfoConfigData(context.Background(), assetType)
|
|
if !errors.Is(err, nil) {
|
|
t.Errorf("Error from GetSiteInfoConfigData for %s type received: %v, expected: %v", assetType, err, nil)
|
|
}
|
|
if len(pairs) == 0 {
|
|
t.Errorf("GetSiteInfoConfigData returned no pairs for %s", assetType)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestOrderUpdate(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, b, canManipulateRealOrders)
|
|
_, err := b.OrderUpdate(context.Background(), "1234", "", "", 1, 1, 1)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestGetInactiveOrders(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, b)
|
|
_, err := b.GetInactiveOrders(context.Background(), "tBTCUSD")
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
|
|
_, err = b.GetInactiveOrders(context.Background(), "tBTCUSD", 1, 2, 3, 4)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestCancelMultipleOrdersV2(t *testing.T) {
|
|
t.Parallel()
|
|
sharedtestvalues.SkipTestIfCredentialsUnset(t, b, canManipulateRealOrders)
|
|
_, err := b.CancelMultipleOrdersV2(context.Background(), 1337, 0, 0, time.Time{}, false)
|
|
if err != nil {
|
|
t.Error(err)
|
|
}
|
|
}
|
|
|
|
func TestChanForSub(t *testing.T) {
|
|
t.Parallel()
|
|
p := currency.NewPairWithDelimiter("DOGE", "XLM", "-")
|
|
s, err := b.chanForSub(wsBook, asset.Spot, p)
|
|
assert.ErrorIs(t, err, errSubNotFound, "Correct error returned when stream when sub not found")
|
|
assert.Nil(t, s, "No stream returned when sub not found")
|
|
|
|
// Add a spare sub to ensure we don't get only-answer-is-right syndrome
|
|
b.Websocket.AddSuccessfulSubscriptions(stream.ChannelSubscription{Asset: asset.Spot, Currency: btcusdPair, Channel: wsTicker})
|
|
|
|
want := stream.ChannelSubscription{Asset: asset.Spot, Currency: p, Channel: wsBook}
|
|
b.Websocket.AddSuccessfulSubscriptions(want)
|
|
s, err = b.chanForSub(wsBook, asset.Spot, p)
|
|
assert.Nil(t, err, "No error returned when sub found")
|
|
assert.EqualValues(t, want, *s, "Correct Sub found")
|
|
}
|