@@ -460,6 +460,17 @@ describe('WebSocket API JSON-RPC', function () {
460460 }
461461 } ) . timeout ( 35000 ) ;
462462 } ) ;
463+
464+ describe ( 'spotCloseDataStream' , function ( ) {
465+ it ( 'should reject when no user data stream connection is open' , async function ( ) {
466+ try {
467+ await binance . spotCloseDataStream ( ) ;
468+ assert . fail ( 'Should have thrown an error' ) ;
469+ } catch ( error : any ) {
470+ assert ( error . message . includes ( 'no open user data stream connection' ) , 'Should indicate the connection is missing' ) ;
471+ }
472+ } ) ;
473+ } ) ;
463474} ) ;
464475
465476describe ( 'WebSocket API Live Tests' , function ( ) {
@@ -504,6 +515,56 @@ describe('WebSocket API Live Tests', function () {
504515 ) ;
505516 } ) ;
506517
518+ it ( 'should close the user data stream with spotCloseDataStream' , function ( done ) {
519+ this . timeout ( TIMEOUT ) ;
520+
521+ binance . websockets . userData (
522+ ( data ) => {
523+ console . log ( 'User data event:' , data ) ;
524+ } ,
525+ undefined ,
526+ undefined ,
527+ async ( endpoint ) => {
528+ try {
529+ assert ( ( binance as any ) . Options . userDataSubscriptionId !== undefined , 'Should have subscription ID' ) ;
530+
531+ const result = await binance . spotCloseDataStream ( ) ;
532+ console . log ( 'Unsubscribed:' , result ) ;
533+
534+ assert ( ( binance as any ) . Options . userDataSubscriptionId === undefined , 'Subscription ID should be cleared' ) ;
535+ assert ( ( binance as any ) . wsApiConnections [ 'userData' ] === undefined , 'Connection should be removed' ) ;
536+ done ( ) ;
537+ } catch ( error : any ) {
538+ stopWsApiConnections ( ) ;
539+ done ( error ) ;
540+ }
541+ }
542+ ) ;
543+ } ) ;
544+
545+ it ( 'should manage the stream lifecycle with spotGetDataStream/spotKeepDataStream/spotCloseDataStream' , async function ( ) {
546+ this . timeout ( TIMEOUT ) ;
547+
548+ try {
549+ const subscription = await binance . spotGetDataStream ( ) ;
550+ console . log ( 'Subscribed:' , subscription ) ;
551+ assert ( subscription !== null , WARN_SHOULD_BE_NOT_NULL ) ;
552+ assert ( subscription . subscriptionId !== undefined , WARN_SHOULD_HAVE_KEY + 'subscriptionId' ) ;
553+ assert ( ( binance as any ) . Options . userDataSubscriptionId === subscription . subscriptionId , 'Subscription ID should be tracked' ) ;
554+
555+ const keepAlive = await binance . spotKeepDataStream ( ) ;
556+ assert ( keepAlive !== null , WARN_SHOULD_BE_NOT_NULL ) ;
557+
558+ const result = await binance . spotCloseDataStream ( ) ;
559+ console . log ( 'Unsubscribed:' , result ) ;
560+ assert ( ( binance as any ) . Options . userDataSubscriptionId === undefined , 'Subscription ID should be cleared' ) ;
561+ assert ( ( binance as any ) . wsApiConnections [ 'userData' ] === undefined , 'Connection should be removed' ) ;
562+ } catch ( error ) {
563+ stopWsApiConnections ( ) ;
564+ throw error ;
565+ }
566+ } ) ;
567+
507568 it ( 'should receive execution and balance events when creating a market order' , function ( done ) {
508569 this . timeout ( TIMEOUT ) ;
509570
0 commit comments