Skip to content
Merged
Prev Previous commit
Next Next commit
Added tests for Http2Client and AuthorizedHttp2Client
  • Loading branch information
jonathanedey committed May 16, 2024
commit 1427e7f3ec40d0ff825af3f474f169afcf7c236d
2 changes: 1 addition & 1 deletion src/utils/api-request.ts
Original file line number Diff line number Diff line change
Expand Up @@ -842,7 +842,7 @@ class AsyncHttp2Call extends AsyncRequestCall {
':method': this.options.method,
':scheme': this.options.protocol!,
':path': this.options.path!,
...this.http2ConfigImpl.headers
...this.options.headers
});

req.on('response', (headers: IncomingHttp2Headers) => {
Expand Down
64 changes: 46 additions & 18 deletions test/resources/mocks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -319,54 +319,82 @@ export interface MockHttp2Request {

export interface MockHttp2Response {
headers: http2.IncomingHttpHeaders & http2.IncomingHttpStatusHeader,
data: Buffer
data: Buffer,
delay?: number,
error?: any
}

export class Http2Mocker {
private connectStub: sinon.SinonStub;
private connectStub: sinon.SinonStub | null;
private originalConnect = http2.connect;
private timeouts: NodeJS.Timeout[] = [];
private mockResponses: MockHttp2Response[] = [];
public requests: MockHttp2Request[] = [];

public http2Stub(mockResponses: MockHttp2Response[]): void {
this.mockResponses = mockResponses
this.connectStub = sinon.stub(http2, 'connect');
this.connectStub.callsFake((target: any, options: any) => {
const session = this.originalConnect(target, options);
session.request = this.createMockRequest(mockResponses)
this.connectStub.callsFake((_target: any, options: any) => {
const session = this.originalConnect('https://www.example.com', options);
session.request = this.createMockRequest()
return session;
})
}

private createMockRequest(mockResponses: MockHttp2Response[]) {
private createMockRequest() {
return (requestHeaders: http2.OutgoingHttpHeaders) => {
// Create a mock ClientHttp2Stream to return
const mockStream = new stream.Readable({
// eslint-disable-next-line @typescript-eslint/no-empty-function
read() {}
}) as http2.ClientHttp2Stream;

mockStream.end = (data: any) => {
this.requests.push({ headers: requestHeaders, data: data })
return mockStream
};

mockStream.setTimeout = sinon.stub()

process.nextTick(() => {
const mockRes = mockResponses.shift()
if (mockRes) {
mockStream.emit('response', mockRes.headers);
mockStream.emit('data', mockRes.data);
mockStream.emit('end');
}
});
mockStream.setTimeout = (timeout, callback: () => void) => {
this.timeouts.push(setTimeout(callback, timeout))
}

const mockRes = this.mockResponses.shift();
if (mockRes) {
this.timeouts.push(setTimeout(() => {
if (mockRes.error) {
mockStream.emit('error', mockRes.error)
}
else {
mockStream.emit('response', mockRes.headers);
mockStream.emit('data', mockRes.data);
mockStream.emit('end');
}
}, mockRes.delay))
}
else {
throw Error('A mock request response was expected but not found.')
}
return mockStream;
}
}

public restore(): void {
public done(): void {
// Clear timeouts
this.timeouts.forEach((timeout) => {
clearTimeout(timeout)
})

// Remove stub
if (this.connectStub) {
this.connectStub.restore();
this.connectStub = null;
}

// Check if all mock requests responces were used
if (this.mockResponses.length > 0) {
throw Error('A extra mock request was provided but not used.')
}

this.requests = []
}
}
Expand Down
3 changes: 1 addition & 2 deletions test/unit/messaging/messaging.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -379,7 +379,7 @@ describe('Messaging', () => {
if (httpsRequestStub && httpsRequestStub.restore) {
httpsRequestStub.restore();
}
http2Mocker.restore()
http2Mocker.done()
mockedHttp2Responses = [];
getTokenStub.restore();
return mockApp.delete();
Expand Down Expand Up @@ -1219,7 +1219,6 @@ describe('Messaging', () => {
});
});

// TODO(jedey): copy
it('should be fulfilled with a BatchResponse given valid message', () => {
const messageIds = [
'projects/projec_id/messages/1',
Expand Down
Loading