From 49e2d68e9b05ad57ef8d2134b69c7eef17f276df Mon Sep 17 00:00:00 2001 From: Trivikram Kamat <16024985+trivikr@users.noreply.github.com> Date: Wed, 10 Sep 2025 16:09:23 +0000 Subject: [PATCH] test(credential-provider-node): attempt to migrate integ tests to vitest --- .../jest.config.integ.js | 4 - .../credential-provider-node/package.json | 5 +- .../credential-provider-node.integ.spec.ts | 145 ++++++++---------- 3 files changed, 70 insertions(+), 84 deletions(-) delete mode 100644 packages/credential-provider-node/jest.config.integ.js diff --git a/packages/credential-provider-node/jest.config.integ.js b/packages/credential-provider-node/jest.config.integ.js deleted file mode 100644 index d09aba7398c72..0000000000000 --- a/packages/credential-provider-node/jest.config.integ.js +++ /dev/null @@ -1,4 +0,0 @@ -module.exports = { - preset: "ts-jest", - testMatch: ["**/*.integ.spec.ts"], -}; diff --git a/packages/credential-provider-node/package.json b/packages/credential-provider-node/package.json index ef7ff13150cb0..b0c51bc0ee5d2 100644 --- a/packages/credential-provider-node/package.json +++ b/packages/credential-provider-node/package.json @@ -16,8 +16,9 @@ "build:types:downlevel": "downlevel-dts dist-types dist-types/ts3.4", "clean": "rimraf ./dist-* && rimraf *.tsbuildinfo", "test": "yarn g:vitest run", - "test:integration": "yarn g:jest -c jest.config.integ.js", - "test:watch": "yarn g:vitest watch" + "test:watch": "yarn g:vitest watch", + "test:integration": "yarn g:vitest run -c vitest.config.integ.mts", + "test:integration:watch": "yarn g:vitest watch -c vitest.config.integ.mts" }, "keywords": [ "aws", diff --git a/packages/credential-provider-node/src/credential-provider-node.integ.spec.ts b/packages/credential-provider-node/src/credential-provider-node.integ.spec.ts index 7353d322d392a..91bb8642f3f5a 100644 --- a/packages/credential-provider-node/src/credential-provider-node.integ.spec.ts +++ b/packages/credential-provider-node/src/credential-provider-node.integ.spec.ts @@ -6,61 +6,51 @@ import type { SharedConfigInit, SourceProfileInit } from "@smithy/shared-ini-fil import type { HttpRequest, NodeHttpHandlerOptions, ParsedIniData, SharedConfigFiles } from "@smithy/types"; import { AdaptiveRetryStrategy, StandardRetryStrategy } from "@smithy/util-retry"; import { PassThrough } from "stream"; +import { afterAll, afterEach, beforeAll, beforeEach, describe, expect, test as it, vi } from "vitest"; import { defaultProvider } from "./defaultProvider"; -jest.mock("fs", () => { - const actual = jest.requireActual("fs"); - return { - ...actual, - readFileSync(file: string, ...options: any[]) { - if (file === "token-filepath") { - return "token-contents"; - } - return actual.readFileSync(file, ...options); - }, - }; -}); +vi.mock("fs", async () => ({ + readFileSync: vi.fn((file: string, ...options: any[]) => { + if (file === "token-filepath") { + return "token-contents"; + } + }), +})); let iniProfileData: ParsedIniData = null as any; -jest.mock("@smithy/shared-ini-file-loader", () => { - const actual = jest.requireActual("@smithy/shared-ini-file-loader"); - return { - ...actual, - async loadSsoSessionData() { - return Object.entries(iniProfileData) - .filter(([key]) => key.startsWith("sso-session.")) - .reduce( - (acc, [key, value]) => ({ - ...acc, - [key.split("sso-session.")[1]]: value, - }), - {} - ); - }, - async parseKnownFiles(init: SourceProfileInit): Promise { - return iniProfileData; - }, - async loadSharedConfigFiles(init: SharedConfigInit): Promise { - return { - configFile: iniProfileData, - credentialsFile: iniProfileData, - }; - }, - async getSSOTokenFromFile() { - return { - accessToken: "mock_sso_token", - expiresAt: "3000-01-01T00:00:00.000Z", - }; - }, - }; -}); +vi.mock("@smithy/shared-ini-file-loader", () => ({ + loadSsoSessionData: vi.fn(async () => { + return Object.entries(iniProfileData) + .filter(([key]) => key.startsWith("sso-session.")) + .reduce( + (acc, [key, value]) => ({ + ...acc, + [key.split("sso-session.")[1]]: value, + }), + {} + ); + }), + parseKnownFiles: vi.fn(async (init: SourceProfileInit): Promise => { + return iniProfileData; + }), + loadSharedConfigFiles: vi.fn(async (init: SharedConfigInit): Promise => { + return { + configFile: iniProfileData, + credentialsFile: iniProfileData, + }; + }), + getSSOTokenFromFile: vi.fn(async () => { + return { + accessToken: "mock_sso_token", + expiresAt: "3000-01-01T00:00:00.000Z", + }; + }), +})); const assumeRoleArns: string[] = []; -jest.mock("@smithy/node-http-handler", () => { - const actual = jest.requireActual("@smithy/node-http-handler"); - +vi.mock("@smithy/node-http-handler", async () => { class MockNodeHttpHandler { static create(instanceOrOptions?: any) { if (typeof instanceOrOptions?.handle === "function") { @@ -68,7 +58,8 @@ jest.mock("@smithy/node-http-handler", () => { } return new MockNodeHttpHandler(); } - async handle(request: HttpRequest) { + + handle = vi.fn(async (request: HttpRequest) => { const body = new PassThrough({}); if (request.body?.includes("RoleArn=")) { @@ -165,38 +156,36 @@ jest.mock("@smithy/node-http-handler", () => { headers: {}, }), }; - } - updateHttpClientConfig(key: keyof NodeHttpHandlerOptions, value: NodeHttpHandlerOptions[typeof key]): void {} - httpHandlerConfigs(): NodeHttpHandlerOptions { + }); + + updateHttpClientConfig = vi.fn( + (key: keyof NodeHttpHandlerOptions, value: NodeHttpHandlerOptions[typeof key]): void => {} + ); + + httpHandlerConfigs = vi.fn((): NodeHttpHandlerOptions => { return null as any; - } + }); } return { - ...actual, NodeHttpHandler: MockNodeHttpHandler, }; }); -jest.mock("child_process", () => { - const actual = jest.requireActual("child_process"); - return { - ...actual, - exec(bin: string, cb: (err: unknown, data: any) => void, ...args: any[]) { - if (bin === "credential-process") { - return cb(null, { - stdout: JSON.stringify({ - Version: 1, - AccessKeyId: "PROCESS_ACCESS_KEY_ID", - SecretAccessKey: "PROCESS_SECRET_ACCESS_KEY", - SessionToken: "PROCESS_SESSION_TOKEN", - }), - }); - } - return actual.exec(bin, cb, ...args); - }, - }; -}); +vi.mock("child_process", () => ({ + exec: vi.fn((bin: string, cb: (err: unknown, data: any) => void, ...args: any[]) => { + if (bin === "credential-process") { + return cb(null, { + stdout: JSON.stringify({ + Version: 1, + AccessKeyId: "PROCESS_ACCESS_KEY_ID", + SecretAccessKey: "PROCESS_SECRET_ACCESS_KEY", + SessionToken: "PROCESS_SESSION_TOKEN", + }), + }); + } + }), +})); describe("credential-provider-node integration test", () => { let sts: STS = null as any; @@ -271,8 +260,8 @@ describe("credential-provider-node integration test", () => { }); afterAll(async () => { - jest.clearAllMocks(); - jest.clearAllTimers(); + vi.clearAllMocks(); + vi.clearAllTimers(); }); describe("fromEnv", () => { @@ -570,7 +559,7 @@ describe("credential-provider-node integration test", () => { iniProfileData.credential_source_profile = { credential_source: "EcsContainer", }; - const spy = jest.spyOn(credentialProviderHttp, "fromHttp"); + const spy = vi.spyOn(credentialProviderHttp, "fromHttp"); sts = new STS({ region: "us-west-2", credentials: defaultProvider({ @@ -658,7 +647,7 @@ describe("credential-provider-node integration test", () => { role_arn: "ROLE_ARN_1", }; - const spy = jest.spyOn(credentialProviderHttp, "fromHttp"); + const spy = vi.spyOn(credentialProviderHttp, "fromHttp"); sts = new STS({ region: "us-west-2", credentials: defaultProvider({ @@ -710,7 +699,7 @@ describe("credential-provider-node integration test", () => { // This scenario tests the option of having no role_arn in this step of the chain. }; - const spy = jest.spyOn(credentialProviderHttp, "fromHttp"); + const spy = vi.spyOn(credentialProviderHttp, "fromHttp"); sts = new STS({ region: "us-west-2", credentials: defaultProvider({ @@ -805,7 +794,7 @@ describe("credential-provider-node integration test", () => { }); }); - xit("should use instance metadata unless IMDS is disabled", async () => { + it.skip("should use instance metadata unless IMDS is disabled", async () => { // TODO }); });