Skip to content

Commit 15858dd

Browse files
committed
convert nock to vitest mock in imds
1 parent d915a19 commit 15858dd

File tree

2 files changed

+66
-43
lines changed

2 files changed

+66
-43
lines changed

packages/credential-provider-imds/package.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,6 @@
3737
"@types/node": "^16.18.96",
3838
"concurrently": "7.0.0",
3939
"downlevel-dts": "0.10.1",
40-
"nock": "^13.0.2",
4140
"rimraf": "3.0.2",
4241
"typedoc": "0.23.23"
4342
},
Lines changed: 66 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,91 +1,110 @@
11
import { ProviderError } from "@smithy/property-provider";
2-
import { createServer } from "http";
3-
import nock from "nock";
4-
import { afterEach, beforeAll, describe, expect, test as it, vi } from "vitest";
2+
import { afterEach, describe, expect, test as it, vi } from "vitest";
53

64
import { httpRequest } from "./httpRequest";
75

6+
vi.mock("http", async () => {
7+
const actual: any = vi.importActual("http");
8+
9+
const pkg = {
10+
...actual,
11+
request: vi.fn(),
12+
};
13+
return {
14+
...pkg,
15+
default: pkg,
16+
};
17+
});
18+
19+
import EventEmitter from "events";
20+
import { request } from "http";
21+
822
describe("httpRequest", () => {
923
let port: number;
1024
const hostname = "localhost";
1125
const path = "/";
1226

13-
const getOpenPort = async (candidatePort = 4321): Promise<number> => {
14-
try {
15-
return new Promise<number>((resolve, reject) => {
16-
const server = createServer();
17-
server.on("error", () => reject());
18-
server.listen(candidatePort);
19-
server.close(() => resolve(candidatePort));
20-
});
21-
} catch (e) {
22-
return await getOpenPort(candidatePort + 1);
23-
}
24-
};
25-
26-
beforeAll(async () => {
27-
port = await getOpenPort();
28-
});
29-
3027
afterEach(() => {
3128
vi.clearAllMocks();
3229
});
3330

31+
function mockResponse({ expectedResponse, statusCode = 200 }: any) {
32+
return vi.mocked(request).mockImplementationOnce((() => {
33+
const request = Object.assign(new EventEmitter(), {
34+
destroy: vi.fn(),
35+
end: vi.fn(),
36+
});
37+
const response = new EventEmitter() as any;
38+
response.statusCode = statusCode;
39+
setTimeout(() => {
40+
request.emit("response", response);
41+
setTimeout(() => {
42+
response.emit("data", Buffer.from(expectedResponse));
43+
response.emit("end");
44+
}, 50);
45+
}, 50);
46+
return request;
47+
}) as any);
48+
}
49+
3450
describe("returns response", () => {
3551
it("defaults to method GET", async () => {
3652
const expectedResponse = "expectedResponse";
37-
const scope = nock(`http://${hostname}:${port}`).get(path).reply(200, expectedResponse);
53+
54+
mockResponse({ expectedResponse });
3855

3956
const response = await httpRequest({ hostname, path, port });
4057
expect(response.toString()).toStrictEqual(expectedResponse);
41-
42-
scope.done();
4358
});
4459

4560
it("uses method passed in options", async () => {
4661
const method = "POST";
4762
const expectedResponse = "expectedResponse";
48-
const scope = nock(`http://${hostname}:${port}`).post(path).reply(200, expectedResponse);
63+
mockResponse({ expectedResponse });
4964

5065
const response = await httpRequest({ hostname, path, port, method });
5166
expect(response.toString()).toStrictEqual(expectedResponse);
52-
53-
scope.done();
5467
});
5568

5669
it("works with IPv6 hostname with encapsulated brackets", async () => {
5770
const expectedResponse = "expectedResponse";
5871
const encapsulatedIPv6Hostname = "[::1]";
59-
const scope = nock(`http://${encapsulatedIPv6Hostname}:${port}`).get(path).reply(200, expectedResponse);
72+
mockResponse({ expectedResponse });
6073

6174
const response = await httpRequest({ hostname: encapsulatedIPv6Hostname, path, port });
6275
expect(response.toString()).toStrictEqual(expectedResponse);
63-
64-
scope.done();
6576
});
6677
});
6778

6879
describe("throws error", () => {
6980
const errorOnStatusCode = async (statusCode: number) => {
7081
it(`statusCode: ${statusCode}`, async () => {
71-
const scope = nock(`http://${hostname}:${port}`).get(path).reply(statusCode, "continue");
82+
mockResponse({
83+
statusCode,
84+
expectedResponse: "continue",
85+
});
7286

7387
await expect(httpRequest({ hostname, path, port })).rejects.toStrictEqual(
7488
Object.assign(new ProviderError("Error response received from instance metadata service"), { statusCode })
7589
);
76-
77-
scope.done();
7890
});
7991
};
8092

8193
it("when request throws error", async () => {
82-
const scope = nock(`http://${hostname}:${port}`).get(path).replyWithError("error");
94+
vi.mocked(request).mockImplementationOnce((() => {
95+
const request = Object.assign(new EventEmitter(), {
96+
destroy: vi.fn(),
97+
end: vi.fn(),
98+
});
99+
setTimeout(() => {
100+
request.emit("error");
101+
}, 50);
102+
return request;
103+
}) as any);
83104

84105
await expect(httpRequest({ hostname, path, port })).rejects.toStrictEqual(
85106
new ProviderError("Unable to connect to instance metadata service")
86107
);
87-
88-
scope.done();
89108
});
90109

91110
describe("when request returns with statusCode < 200", () => {
@@ -99,16 +118,21 @@ describe("httpRequest", () => {
99118

100119
it("timeout", async () => {
101120
const timeout = 1000;
102-
const scope = nock(`http://${hostname}:${port}`)
103-
.get(path)
104-
.delay(timeout * 2)
105-
.reply(200, "expectedResponse");
121+
vi.mocked(request).mockImplementationOnce((() => {
122+
const request = Object.assign(new EventEmitter(), {
123+
destroy: vi.fn(),
124+
end: vi.fn(),
125+
});
126+
const response = new EventEmitter() as any;
127+
response.statusCode = 200;
128+
setTimeout(() => {
129+
request.emit("timeout");
130+
}, 50);
131+
return request;
132+
}) as any);
106133

107134
await expect(httpRequest({ hostname, path, port, timeout })).rejects.toStrictEqual(
108135
new ProviderError("TimeoutError from instance metadata service")
109136
);
110-
111-
nock.abortPendingRequests();
112-
scope.done();
113137
});
114138
});

0 commit comments

Comments
 (0)