1+ import axios from "axios" ;
2+ import { config } from "./config/env.config" ;
3+ import { fundAddress , transferEgld } from "./utils/chain.simulator.operations" ;
4+ import { io , Socket } from "socket.io-client" ;
5+
6+ const WS_SERVER_URL = `${ config . subscriptionsServiceUrl } ` ;
7+
8+ const subscriptionsResponses : Map < string , any [ ] > = new Map ( ) ;
9+
10+ const filters = {
11+ CLIENT_1 : { sender : config . aliceAddress } ,
12+ CLIENT_2 : { sender : config . bobAddress } ,
13+ CLIENT_3 : { sender : config . aliceAddress , receiver : config . bobAddress }
14+ } ;
15+
16+ const filterKeys = {
17+ CLIENT_1 : JSON . stringify ( filters . CLIENT_1 ) ,
18+ CLIENT_2 : JSON . stringify ( filters . CLIENT_2 ) ,
19+ CLIENT_3 : JSON . stringify ( filters . CLIENT_3 )
20+ }
21+
22+ const filterMap = [
23+ { key : filterKeys . CLIENT_1 , filter : filters . CLIENT_1 , clientId : "client1" } ,
24+ { key : filterKeys . CLIENT_2 , filter : filters . CLIENT_2 , clientId : "client2" } ,
25+ { key : filterKeys . CLIENT_3 , filter : filters . CLIENT_3 , clientId : "client3" }
26+ ] ;
27+
28+
29+ describe ( 'Websocket subscriptions e2e tests with chain simulator' , ( ) => {
30+ jest . setTimeout ( 100000 ) ;
31+
32+ const clients : Socket [ ] = [ ] ;
33+
34+ const connectAndSubscribe = ( filterKey : string , filter : any , clientId : string ) => {
35+ const clientLabel = clientId ;
36+ const receivedTxs : any [ ] = [ ] ;
37+
38+ subscriptionsResponses . set ( filterKey , receivedTxs ) ;
39+
40+ const client : Socket = io ( WS_SERVER_URL , {
41+ path : '/ws/subscription'
42+ } ) ;
43+ clients . push ( client ) ;
44+
45+
46+
47+ client . on ( "connect_error" , ( err ) => {
48+ throw new Error ( `${ clientLabel } connection failed: ${ err . message } ` ) ;
49+ } ) ;
50+
51+ client . on ( "error" , ( err ) => {
52+ throw new Error ( `Error for ${ clientLabel } : ${ err . message } ` ) ;
53+ } ) ;
54+
55+ client . on ( "customTransactionUpdate" , ( data : { transactions : any [ ] } ) => {
56+ console . log ( `\n💸 ${ clientLabel } received ${ data . transactions . length } txs` ) ;
57+ receivedTxs . push ( ...data . transactions ) ;
58+ } ) ;
59+
60+ client . on ( "connect" , ( ) => {
61+ console . log ( `\n ${ clientLabel } subscribing to TXs:` , JSON . stringify ( filter ) ) ;
62+
63+ client . emit ( "subscribeCustomTransactions" , filter , ( ack : any ) => {
64+ console . log ( 'ACK Response:' , ack ) ;
65+ } ) ;
66+ } ) ;
67+
68+ } ;
69+
70+ beforeAll ( async ( ) => {
71+ console . log ( "--- Executing beforeAll (Setup) ---" ) ;
72+
73+ try {
74+ // 1. Setup Chain Simulator
75+ await fundAddress ( config . chainSimulatorUrl , config . aliceAddress ) ;
76+ await fundAddress ( config . chainSimulatorUrl , config . bobAddress ) ;
77+ await axios . post ( `${ config . chainSimulatorUrl } /simulator/generate-blocks/1` ) ;
78+
79+ for ( const item of filterMap ) {
80+ connectAndSubscribe ( item . key , item . filter , item . clientId ) ;
81+ }
82+
83+ // await for clients to connect
84+ console . log ( `Awaiting for clients to connect...` )
85+ await new Promise ( resolve => setTimeout ( resolve , 5000 ) ) ;
86+
87+ console . log ( "\n--- Starting Transactions ---" ) ;
88+
89+ await transferEgld ( config . chainSimulatorUrl , config . aliceAddress , config . bobAddress , 1 ) ;
90+ await transferEgld ( config . chainSimulatorUrl , config . bobAddress , config . aliceAddress , 2 ) ;
91+
92+ console . log ( "--- Generating Block and waiting for WS responses ---" ) ;
93+ await axios . post ( `${ config . chainSimulatorUrl } /simulator/generate-blocks/10` ) ;
94+
95+ await new Promise ( resolve => setTimeout ( resolve , 15000 ) ) ;
96+
97+ console . log ( "--- Setup Complete ---" ) ;
98+
99+ } catch ( e : any ) {
100+ console . error ( "An error occured in beforeAll:" , e . message ) ;
101+
102+ throw e ;
103+ }
104+ } ) ;
105+
106+ afterAll ( ( ) => {
107+ clients . forEach ( client => client . connected && client . disconnect ( ) ) ;
108+ console . log ( "\n--- All clients disconnected ---" ) ;
109+ } ) ;
110+
111+ // --- TESTE SEPARATE (itShould...) ---
112+
113+ it ( 'should receive only the transaction sent by Alice (Tx 1: Alice -> Bob) when filtering by CLIENT_1' , ( ) => {
114+ const filterKey = filterKeys . CLIENT_1 ;
115+ const aliceTxs = subscriptionsResponses . get ( filterKey ) ;
116+ console . log ( `\nRunning test for ${ filterMap . find ( f => f . key === filterKey ) ?. clientId } ` ) ;
117+
118+ expect ( aliceTxs ?. length ) . toBe ( 1 ) ;
119+ const tx = aliceTxs ?. [ 0 ] ;
120+ expect ( tx . sender ) . toEqual ( config . aliceAddress ) ;
121+ expect ( tx . sender ) . not . toEqual ( config . bobAddress ) ;
122+ } ) ;
123+
124+ it ( 'should receive only the transaction sent by Bob (Tx 2: Bob -> Alice) when filtering by CLIENT_2' , ( ) => {
125+ const filterKey = filterKeys . CLIENT_2 ;
126+ const bobTxs = subscriptionsResponses . get ( filterKey ) ;
127+ console . log ( `\nRunning test for ${ filterMap . find ( f => f . key === filterKey ) ?. clientId } ` ) ;
128+
129+ expect ( bobTxs ?. length ) . toBe ( 1 ) ;
130+ const tx = bobTxs ?. [ 0 ] ;
131+ expect ( tx . sender ) . toEqual ( config . bobAddress ) ;
132+ expect ( tx . receiver ) . toEqual ( config . aliceAddress ) ;
133+ expect ( tx . sender ) . not . toEqual ( config . aliceAddress ) ;
134+ } ) ;
135+
136+ it ( 'should receive only the transaction sent by Alice to Bob (Tx 1) when filtering by CLIENT_3' , ( ) => {
137+ const filterKey = filterKeys . CLIENT_3 ;
138+ const aliceToBobTxs = subscriptionsResponses . get ( filterKey ) ;
139+ console . log ( `\nRunning test for ${ filterMap . find ( f => f . key === filterKey ) ?. clientId } ` ) ;
140+
141+ expect ( aliceToBobTxs ?. length ) . toBe ( 1 ) ;
142+ const tx = aliceToBobTxs ?. [ 0 ] ;
143+ expect ( tx . sender ) . toEqual ( config . aliceAddress ) ;
144+ expect ( tx . receiver ) . toEqual ( config . bobAddress ) ;
145+ } ) ;
146+ } ) ;
0 commit comments