Skip to content

Commit 99e0508

Browse files
committed
Added unit test
1 parent 6cfb7fb commit 99e0508

File tree

3 files changed

+81
-9
lines changed

3 files changed

+81
-9
lines changed

test/resources/mocks.ts

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -322,10 +322,11 @@ export interface MockHttp2Request {
322322
}
323323

324324
export interface MockHttp2Response {
325-
headers: http2.IncomingHttpHeaders & http2.IncomingHttpStatusHeader,
326-
data: Buffer,
325+
headers?: http2.IncomingHttpHeaders & http2.IncomingHttpStatusHeader,
326+
data?: Buffer,
327327
delay?: number,
328-
error?: any
328+
sessionError?: any
329+
streamError?: any,
329330
}
330331

331332
export class Http2Mocker {
@@ -340,12 +341,12 @@ export class Http2Mocker {
340341
this.connectStub = sinon.stub(http2, 'connect');
341342
this.connectStub.callsFake((_target: any, options: any) => {
342343
const session = this.originalConnect('https://www.example.com', options);
343-
session.request = this.createMockRequest()
344+
session.request = this.createMockRequest(session)
344345
return session;
345346
})
346347
}
347348

348-
private createMockRequest() {
349+
private createMockRequest(session:http2.ClientHttp2Session) {
349350
return (requestHeaders: http2.OutgoingHttpHeaders) => {
350351
// Create a mock ClientHttp2Stream to return
351352
const mockStream = new stream.Readable({
@@ -365,8 +366,11 @@ export class Http2Mocker {
365366
const mockRes = this.mockResponses.shift();
366367
if (mockRes) {
367368
this.timeouts.push(setTimeout(() => {
368-
if (mockRes.error) {
369-
mockStream.emit('error', mockRes.error)
369+
if (mockRes.sessionError) {
370+
session.emit('error', mockRes.sessionError)
371+
}
372+
if (mockRes.streamError) {
373+
mockStream.emit('error', mockRes.streamError)
370374
}
371375
else {
372376
mockStream.emit('response', mockRes.headers);

test/unit/messaging/messaging.spec.ts

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,12 @@ function mockHttp2SendRequestError(
121121
} as mocks.MockHttp2Response
122122
}
123123

124+
function mockHttp2Error(streamError?: any, sessionError?:any): mocks.MockHttp2Response {
125+
return {
126+
streamError: streamError,
127+
sessionError: sessionError
128+
} as mocks.MockHttp2Response
129+
}
124130

125131
function mockErrorResponse(
126132
path: string,
@@ -906,6 +912,29 @@ describe('Messaging', () => {
906912
});
907913
});
908914

915+
it('should throw error with BatchResponse promise on session error event using HTTP/2', () => {
916+
mockedHttp2Responses.push(mockHttp2SendRequestResponse('projects/projec_id/messages/1'))
917+
const sessionError = 'MOCK_SESSION_ERROR'
918+
mockedHttp2Responses.push(mockHttp2Error(
919+
new Error(`MOCK_STREAM_ERROR caused by ${sessionError}`),
920+
new Error(sessionError)
921+
));
922+
http2Mocker.http2Stub(mockedHttp2Responses)
923+
924+
return messaging.sendEach(
925+
[validMessage, validMessage], true
926+
).catch(async (error) => {
927+
expect(error.errorInfo.code).to.equal('app/http2-session-error')
928+
await error.pendingBatchResponse.then((response: BatchResponse) => {
929+
expect(http2Mocker.requests.length).to.equal(2);
930+
expect(response.failureCount).to.equal(1);
931+
const responses = response.responses;
932+
checkSendResponseSuccess(responses[0], 'projects/projec_id/messages/1');
933+
checkSendResponseFailure(responses[1], 'app/network-error');
934+
})
935+
});
936+
})
937+
909938
// This test was added to also verify https://github.com/firebase/firebase-admin-node/issues/1146
910939
it('should be fulfilled when called with different message types using HTTP/2', () => {
911940
const messageIds = [

test/unit/utils/api-request.spec.ts

Lines changed: 41 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -140,12 +140,14 @@ function mockHttp2SendRequestError(
140140
} as mocks.MockHttp2Response
141141
}
142142

143-
function mockHttp2Error(err: any): mocks.MockHttp2Response {
143+
function mockHttp2Error(streamError?: any, sessionError?:any): mocks.MockHttp2Response {
144144
return {
145-
error: err
145+
streamError: streamError,
146+
sessionError: sessionError
146147
} as mocks.MockHttp2Response
147148
}
148149

150+
149151
/**
150152
* Returns a new RetryConfig instance for testing. This is same as the default
151153
* RetryConfig, with the backOffFactor set to 0 to avoid delays.
@@ -2500,6 +2502,43 @@ describe('Http2Client', () => {
25002502
http2SessionHandler: http2SessionHandler
25012503
}).should.eventually.be.rejectedWith(err).and.have.property('code', 'app/network-error');
25022504
});
2505+
2506+
it('should fail on session and stream errors', async () => {
2507+
const reqData = { request: 'data' };
2508+
const streamError = 'Error while making request: test stream error. Error code: AWFUL_STREAM_ERROR';
2509+
const sessionError = 'Session error while making requests: Error: AWFUL_SESSION_ERROR'
2510+
mockedHttp2Responses.push(mockHttp2Error(
2511+
{ message: 'test stream error', code: 'AWFUL_STREAM_ERROR' },
2512+
new Error('AWFUL_SESSION_ERROR')
2513+
));
2514+
http2Mocker.http2Stub(mockedHttp2Responses);
2515+
2516+
const client = new Http2Client();
2517+
http2SessionHandler = new Http2SessionHandler(mockHostUrl)
2518+
2519+
await client.send({
2520+
method: 'POST',
2521+
url: mockUrl,
2522+
headers: {
2523+
'authorization': 'Bearer token',
2524+
'My-Custom-Header': 'CustomValue',
2525+
},
2526+
data: reqData,
2527+
http2SessionHandler: http2SessionHandler,
2528+
}).should.eventually.be.rejectedWith(streamError).and.have.property('code', 'app/network-error')
2529+
.then(() => {
2530+
expect(http2Mocker.requests.length).to.equal(1);
2531+
expect(http2Mocker.requests[0].headers[':method']).to.equal('POST');
2532+
expect(http2Mocker.requests[0].headers[':scheme']).to.equal('https:');
2533+
expect(http2Mocker.requests[0].headers[':path']).to.equal(mockPath);
2534+
expect(JSON.parse(http2Mocker.requests[0].data)).to.deep.equal(reqData);
2535+
expect(http2Mocker.requests[0].headers.authorization).to.equal('Bearer token');
2536+
expect(http2Mocker.requests[0].headers['content-type']).to.contain('application/json');
2537+
expect(http2Mocker.requests[0].headers['My-Custom-Header']).to.equal('CustomValue');
2538+
});
2539+
2540+
await http2SessionHandler.invoke().should.eventually.be.rejectedWith(sessionError)
2541+
});
25032542
});
25042543

25052544
describe('AuthorizedHttpClient', () => {

0 commit comments

Comments
 (0)