@@ -55,7 +55,7 @@ describe('ClientGrpcProxy', () => {
5555 const cln = { [ methodName ] : { responseStream : false } } ;
5656 const spy = sinon . spy ( client , 'createUnaryServiceMethod' ) ;
5757 client . createServiceMethod ( cln , methodName ) ;
58-
58+
5959 expect ( spy . called ) . to . be . true ;
6060 } ) ;
6161 } ) ;
@@ -71,7 +71,7 @@ describe('ClientGrpcProxy', () => {
7171 const obj = { [ methodName ] : ( ) => ( { on : ( type , fn ) => fn ( ) } ) } ;
7272
7373 let stream$ : Observable < any > ;
74-
74+
7575 beforeEach ( ( ) => {
7676 stream$ = client . createStreamServiceMethod ( obj , methodName ) ( ) ;
7777 } ) ;
@@ -83,6 +83,75 @@ describe('ClientGrpcProxy', () => {
8383 expect ( spy . called ) . to . be . true ;
8484 } ) ;
8585 } ) ;
86+
87+ describe ( 'flow-control' , ( ) => {
88+ const methodName = 'm' ;
89+ type EvtCallback = ( ...args : any [ ] ) => void ;
90+ let callMock : {
91+ on : ( type : string , fn : EvtCallback ) => void ,
92+ cancel : sinon . SinonSpy ,
93+ finished : boolean ,
94+ destroy : sinon . SinonSpy ,
95+ removeAllListeners : sinon . SinonSpy ,
96+ } ;
97+ let eventCallbacks : { [ type : string ] : EvtCallback } ;
98+ let obj ;
99+ const dataSpy = sinon . spy ( ) ;
100+ const errorSpy = sinon . spy ( ) ;
101+ const completeSpy = sinon . spy ( ) ;
102+
103+ let stream$ : Observable < any > ;
104+
105+ beforeEach ( ( ) => {
106+ dataSpy . reset ( ) ;
107+ errorSpy . reset ( ) ;
108+ completeSpy . reset ( ) ;
109+ eventCallbacks = { } ;
110+ callMock = {
111+ on : ( type , fn ) => eventCallbacks [ type ] = fn ,
112+ cancel : sinon . spy ( ) ,
113+ finished : false ,
114+ destroy : sinon . spy ( ) ,
115+ removeAllListeners : sinon . spy ( ) ,
116+ } ;
117+ obj = { [ methodName ] : ( ) => callMock } ;
118+ stream$ = client . createStreamServiceMethod ( obj , methodName ) ( ) ;
119+ } ) ;
120+
121+ it ( 'propagates server errors' , ( ) => {
122+ const err = new Error ( 'something happened' ) ;
123+ stream$ . subscribe ( dataSpy , errorSpy , completeSpy ) ;
124+ eventCallbacks . data ( 'a' ) ;
125+ eventCallbacks . data ( 'b' ) ;
126+ callMock . finished = true ;
127+ eventCallbacks . error ( err ) ;
128+ eventCallbacks . data ( 'c' ) ;
129+
130+ expect ( Object . keys ( eventCallbacks ) . length ) . to . eq ( 3 ) ;
131+ expect ( dataSpy . args ) . to . eql ( [ [ 'a' ] , [ 'b' ] ] ) ;
132+ expect ( errorSpy . args [ 0 ] [ 0 ] ) . to . eql ( err ) ;
133+ expect ( completeSpy . called ) . to . be . false ;
134+ expect ( callMock . cancel . called ) . to . be . false ;
135+ } ) ;
136+
137+ it ( 'handles client side cancel' , ( ) => {
138+ const grpcServerCancelErrMock = {
139+ details : 'Cancelled' ,
140+ } ;
141+ const subscription = stream$ . subscribe ( dataSpy , errorSpy ) ;
142+ eventCallbacks . data ( 'a' ) ;
143+ eventCallbacks . data ( 'b' ) ;
144+ subscription . unsubscribe ( ) ;
145+ eventCallbacks . error ( grpcServerCancelErrMock ) ;
146+ eventCallbacks . end ( ) ;
147+ eventCallbacks . data ( 'c' ) ;
148+
149+ expect ( callMock . cancel . called , 'should call call.cancel()' ) . to . be . true ;
150+ expect ( callMock . destroy . called , 'should call call.destroy()' ) . to . be . true ;
151+ expect ( dataSpy . args ) . to . eql ( [ [ 'a' ] , [ 'b' ] ] ) ;
152+ expect ( errorSpy . called , 'should not error if client canceled' ) . to . be . false ;
153+ } ) ;
154+ } ) ;
86155 } ) ;
87156
88157 describe ( 'createUnaryServiceMethod' , ( ) => {
@@ -95,7 +164,7 @@ describe('ClientGrpcProxy', () => {
95164 const obj = { [ methodName ] : ( callback ) => callback ( null , { } ) } ;
96165
97166 let stream$ : Observable < any > ;
98-
167+
99168 beforeEach ( ( ) => {
100169 stream$ = client . createUnaryServiceMethod ( obj , methodName ) ( ) ;
101170 } ) ;
0 commit comments