From 410755c57f7532855c1bc9070d5bb636e5c56f9f Mon Sep 17 00:00:00 2001 From: Trae Yelovich Date: Mon, 23 Dec 2024 11:08:50 -0500 Subject: [PATCH] wip: patch coverage for AuthHandler, DeferredPromise Signed-off-by: Trae Yelovich --- .../profiles/AuthHandler.unit.test.ts | 36 +++++++++++++++++++ .../utils/DeferredPromise.unit.test.ts | 13 +++++++ .../src/profiles/AuthHandler.ts | 4 +-- packages/zowe-explorer-api/src/utils/index.ts | 3 +- 4 files changed, 51 insertions(+), 5 deletions(-) diff --git a/packages/zowe-explorer-api/__tests__/__unit__/profiles/AuthHandler.unit.test.ts b/packages/zowe-explorer-api/__tests__/__unit__/profiles/AuthHandler.unit.test.ts index 5cdc83ae1..9edb81a7b 100644 --- a/packages/zowe-explorer-api/__tests__/__unit__/profiles/AuthHandler.unit.test.ts +++ b/packages/zowe-explorer-api/__tests__/__unit__/profiles/AuthHandler.unit.test.ts @@ -12,6 +12,7 @@ import { Mutex } from "async-mutex"; import { AuthHandler } from "../../../src"; import { FileManagement } from "../../../src/utils/FileManagement"; +import { ImperativeError } from "@zowe/imperative"; const TEST_PROFILE_NAME = "lpar.zosmf"; @@ -25,6 +26,10 @@ describe("AuthHandler.isProfileLocked", () => { it("returns false if the profile is not locked", async () => { expect(AuthHandler.isProfileLocked(TEST_PROFILE_NAME)).toBe(false); }); + + it("returns false if no mutex is present for the given profile", async () => { + expect(AuthHandler.isProfileLocked("unused_lpar.zosmf")).toBe(false); + }); }); describe("AuthHandler.lockProfile", () => { @@ -35,6 +40,22 @@ describe("AuthHandler.lockProfile", () => { AuthHandler.unlockProfile(TEST_PROFILE_NAME); }); + it("handle promptForAuthentication call if error and options are given", async () => { + const promptForAuthenticationMock = jest.spyOn(AuthHandler, "promptForAuthentication").mockResolvedValueOnce(true); + const impError = new ImperativeError({ msg: "Example auth error" }); + const promptOpts = { + promptCredentials: jest.fn(), + ssoLogin: jest.fn(), + }; + const releaseSpy = jest.spyOn(Mutex.prototype, "release"); + const result = await AuthHandler.lockProfile(TEST_PROFILE_NAME, impError, promptOpts); + expect(result).toBe(true); + expect(promptForAuthenticationMock).toHaveBeenCalledTimes(1); + expect(promptForAuthenticationMock).toHaveBeenCalledWith(impError, TEST_PROFILE_NAME, promptOpts); + expect(releaseSpy).toHaveBeenCalledTimes(1); + AuthHandler.unlockProfile(TEST_PROFILE_NAME); + }); + it("reuses the same Mutex for the profile if it already exists", async () => { await AuthHandler.lockProfile(TEST_PROFILE_NAME); expect((AuthHandler as any).lockedProfiles.has(TEST_PROFILE_NAME)).toBe(true); @@ -57,6 +78,21 @@ describe("AuthHandler.unlockProfile", () => { expect((AuthHandler as any).lockedProfiles.get(TEST_PROFILE_NAME)!.isLocked()).toBe(false); }); + it("does nothing if there is no mutex in the profile map", async () => { + const releaseSpy = jest.spyOn(Mutex.prototype, "release").mockClear(); + AuthHandler.unlockProfile("unused_lpar.zosmf"); + expect(releaseSpy).not.toHaveBeenCalled(); + }); + + it("does nothing if the mutex in the map is not locked", async () => { + await AuthHandler.lockProfile(TEST_PROFILE_NAME); + AuthHandler.unlockProfile(TEST_PROFILE_NAME); + + const releaseSpy = jest.spyOn(Mutex.prototype, "release").mockClear(); + AuthHandler.unlockProfile(TEST_PROFILE_NAME); + expect(releaseSpy).not.toHaveBeenCalled(); + }); + it("reuses the same Mutex for the profile if it already exists", async () => { await AuthHandler.lockProfile(TEST_PROFILE_NAME); AuthHandler.unlockProfile(TEST_PROFILE_NAME); diff --git a/packages/zowe-explorer-api/__tests__/__unit__/utils/DeferredPromise.unit.test.ts b/packages/zowe-explorer-api/__tests__/__unit__/utils/DeferredPromise.unit.test.ts index 14d056020..23f86f7da 100644 --- a/packages/zowe-explorer-api/__tests__/__unit__/utils/DeferredPromise.unit.test.ts +++ b/packages/zowe-explorer-api/__tests__/__unit__/utils/DeferredPromise.unit.test.ts @@ -31,4 +31,17 @@ describe("DeferredPromise.status", () => { deferred.resolve(null); expect(deferred.status).toBe("fulfilled"); }); + + it("returns rejected when rejected", async () => { + const deferred = new DeferredPromise(); + let errorCaught = false; + setImmediate(() => deferred.reject()); + try { + await deferred.promise; + } catch (err) { + errorCaught = true; + } + expect(deferred.status).toBe("rejected"); + expect(errorCaught).toBe(true); + }); }); diff --git a/packages/zowe-explorer-api/src/profiles/AuthHandler.ts b/packages/zowe-explorer-api/src/profiles/AuthHandler.ts index e26e29588..4b5e7e795 100644 --- a/packages/zowe-explorer-api/src/profiles/AuthHandler.ts +++ b/packages/zowe-explorer-api/src/profiles/AuthHandler.ts @@ -162,9 +162,7 @@ export class AuthHandler { // Prompt the user to re-authenticate if an error and options were provided if (imperativeError && opts) { const credsEntered = await AuthHandler.promptForAuthentication(imperativeError, profile, opts); - if (!credsEntered) { - mutex.release(); - } + mutex.release(); // Return `true` as the mutex was still locked successfully. return true; } diff --git a/packages/zowe-explorer-api/src/utils/index.ts b/packages/zowe-explorer-api/src/utils/index.ts index 26c43b3e9..af7887d5a 100644 --- a/packages/zowe-explorer-api/src/utils/index.ts +++ b/packages/zowe-explorer-api/src/utils/index.ts @@ -9,9 +9,8 @@ * */ -import { IFileSystemEntry, ZoweScheme } from "../fs"; import { IZoweTreeNode } from "../tree"; -import { window, workspace } from "vscode"; +import { workspace } from "vscode"; export * from "./DeferredPromise"; export * from "./ErrorCorrelator";