package bybit import ( "path/filepath" "testing" "github.com/stretchr/testify/require" "github.com/thrasher-corp/gocryptotrader/config" "github.com/thrasher-corp/gocryptotrader/currency" "github.com/thrasher-corp/gocryptotrader/exchange/order/limits" "github.com/thrasher-corp/gocryptotrader/exchanges/asset" "github.com/thrasher-corp/gocryptotrader/exchanges/order" "github.com/thrasher-corp/gocryptotrader/exchanges/sharedtestvalues" testutils "github.com/thrasher-corp/gocryptotrader/internal/testing/utils" ) func TestWSCreateOrder(t *testing.T) { t.Parallel() arg := &PlaceOrderRequest{} _, err := e.WSCreateOrder(t.Context(), arg) require.ErrorIs(t, err, errCategoryNotSet) arg.Category = cSpot _, err = e.WSCreateOrder(t.Context(), arg) require.ErrorIs(t, err, currency.ErrCurrencyPairEmpty) arg.Symbol = currency.NewBTCUSDT() _, err = e.WSCreateOrder(t.Context(), arg) require.ErrorIs(t, err, order.ErrSideIsInvalid) arg.Side = "Buy" _, err = e.WSCreateOrder(t.Context(), arg) require.ErrorIs(t, err, order.ErrTypeIsInvalid) arg.OrderType = "Limit" _, err = e.WSCreateOrder(t.Context(), arg) require.ErrorIs(t, err, limits.ErrAmountBelowMin) arg.OrderQuantity = 0.0001 arg.TriggerDirection = 69 _, err = e.WSCreateOrder(t.Context(), arg) require.ErrorIs(t, err, errInvalidTriggerDirection) arg.TriggerDirection = 0 arg.OrderFilter = "dodgy" _, err = e.WSCreateOrder(t.Context(), arg) require.ErrorIs(t, err, errInvalidOrderFilter) arg.OrderFilter = "Order" arg.TriggerPriceType = "dodgy" _, err = e.WSCreateOrder(t.Context(), arg) require.ErrorIs(t, err, errInvalidTriggerPriceType) sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) e := getWebsocketInstance(t) //nolint:govet // Intentional shadow got, err := e.WSCreateOrder(t.Context(), &PlaceOrderRequest{ Category: cSpot, Symbol: currency.NewBTCUSDT(), Side: "Buy", OrderType: "Limit", Price: 55000, OrderQuantity: -0.0001, // Replace with a valid quantity TimeInForce: "FOK", // Replace with GTC to submit a valid order if outside current trading price range. }) require.NoError(t, err) require.NotEmpty(t, got) } func TestWebsocketSubmitOrder(t *testing.T) { t.Parallel() // Test quote amount needs to be used due to protocol trade requirements s := &order.Submit{ Exchange: e.Name, Pair: currency.NewBTCUSDT(), AssetType: asset.Spot, Side: order.Buy, Type: order.Market, Amount: 0.0001, } _, err := e.WebsocketSubmitOrder(t.Context(), s) require.ErrorIs(t, err, order.ErrAmountMustBeSet) sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) e := getWebsocketInstance(t) //nolint:govet // Intentional shadow s.Type = order.Limit s.Price = 55000 s.Amount = -0.0001 // Replace with a valid quantity got, err := e.WebsocketSubmitOrder(t.Context(), s) require.NoError(t, err) require.NotEmpty(t, got) } func TestWSAmendOrder(t *testing.T) { t.Parallel() arg := &AmendOrderRequest{} _, err := e.WSAmendOrder(t.Context(), arg) require.ErrorIs(t, err, errCategoryNotSet) arg.Category = cSpot _, err = e.WSAmendOrder(t.Context(), arg) require.ErrorIs(t, err, currency.ErrCurrencyPairEmpty) arg.Symbol = currency.NewBTCUSDT() _, err = e.WSAmendOrder(t.Context(), arg) require.ErrorIs(t, err, errEitherOrderIDOROrderLinkIDRequired) sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) e := getWebsocketInstance(t) //nolint:govet // Intentional shadow arg.OrderID = "1793353687809485568" // Replace with a valid order ID arg.OrderQuantity = 0.0002 got, err := e.WSAmendOrder(t.Context(), arg) require.NoError(t, err) require.NotEmpty(t, got) } func TestWebsocketModifyOrder(t *testing.T) { t.Parallel() mod := &order.Modify{ Pair: currency.NewBTCUSDT(), AssetType: asset.Spot, Amount: 0.0001, OrderID: "1793388409122024192", // Replace with a valid order ID } sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) e := getWebsocketInstance(t) //nolint:govet // Intentional shadow got, err := e.WebsocketModifyOrder(t.Context(), mod) require.NoError(t, err) require.NotEmpty(t, got) } func TestWSCancelOrder(t *testing.T) { t.Parallel() arg := &CancelOrderRequest{} _, err := e.WSCancelOrder(t.Context(), arg) require.ErrorIs(t, err, errCategoryNotSet) arg.Category = cSpot _, err = e.WSCancelOrder(t.Context(), arg) require.ErrorIs(t, err, currency.ErrCurrencyPairEmpty) arg.Symbol = currency.NewBTCUSDT() _, err = e.WSCancelOrder(t.Context(), arg) require.ErrorIs(t, err, errEitherOrderIDOROrderLinkIDRequired) arg.OrderID = "1793353687809485568" // Replace with a valid order ID arg.OrderFilter = "dodgy" _, err = e.WSCancelOrder(t.Context(), arg) require.ErrorIs(t, err, errInvalidOrderFilter) arg.Category = cLinear _, err = e.WSCancelOrder(t.Context(), arg) require.ErrorIs(t, err, errInvalidCategory) arg.Category = cSpot arg.OrderFilter = "Order" sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) e := getWebsocketInstance(t) //nolint:govet // Intentional shadow got, err := e.WSCancelOrder(t.Context(), arg) require.NoError(t, err) require.NotEmpty(t, got) } func TestWebsocketCancelOrder(t *testing.T) { t.Parallel() cancel := &order.Cancel{ OrderID: "1793388409122024192", // Replace with a valid order ID Pair: currency.NewBTCUSDT(), AssetType: asset.Spot, } sharedtestvalues.SkipTestIfCredentialsUnset(t, e, canManipulateRealOrders) e := getWebsocketInstance(t) //nolint:govet // Intentional shadow err := e.WebsocketCancelOrder(t.Context(), cancel) require.NoError(t, err) } // getWebsocketInstance returns a websocket instance copy for live bi-directional testing func getWebsocketInstance(t *testing.T) *Exchange { t.Helper() cfg := &config.Config{} root, err := testutils.RootPathFromCWD() require.NoError(t, err) err = cfg.LoadConfig(filepath.Join(root, "testdata", "configtest.json"), true) require.NoError(t, err) pairs := &e.CurrencyPairs e := new(Exchange) //nolint:govet // Intentional shadow e.SetDefaults() bConf, err := cfg.GetExchangeConfig("Bybit") require.NoError(t, err) bConf.API.AuthenticatedSupport = true bConf.API.AuthenticatedWebsocketSupport = true bConf.API.Credentials.Key = apiKey bConf.API.Credentials.Secret = apiSecret require.NoError(t, e.Setup(bConf), "Setup must not error") e.CurrencyPairs.Load(pairs) require.NoError(t, e.Websocket.Connect()) return e }