From 2a1ba188052d4257fc838c57d66c236c75441f05 Mon Sep 17 00:00:00 2001 From: Timothy Johnson Date: Mon, 2 Dec 2024 08:25:42 -0500 Subject: [PATCH 1/4] WIP Port fixes for credentials not refreshed in ds tree Signed-off-by: Timothy Johnson --- packages/zowe-explorer-api/CHANGELOG.md | 1 + .../profiles/ProfilesCache.unit.test.ts | 29 ++ .../__unit__/tree/ZoweTreeNode.unit.test.ts | 38 ++- .../vscode/ZoweVsCodeExtension.unit.test.ts | 5 + .../src/profiles/ProfilesCache.ts | 23 +- .../src/tree/ZoweTreeNode.ts | 3 +- .../src/vscode/ZoweVsCodeExtension.ts | 30 +- .../src/vscode/doc/IPromptCredentials.ts | 2 + packages/zowe-explorer/CHANGELOG.md | 2 + packages/zowe-explorer/__mocks__/vscode.ts | 25 ++ .../__unit__/Profiles.extended.unit.test.ts | 301 +++++++++--------- .../__unit__/dataset/actions.unit.test.ts | 6 +- .../__unit__/mvs/mvsNodeActions.unit.test.ts | 23 +- .../__unit__/shared/actions.unit.test.ts | 6 +- .../__unit__/uss/actions.unit.test.ts | 6 +- packages/zowe-explorer/src/Profiles.ts | 71 ++--- .../src/generators/icons/items/home.ts | 4 +- 17 files changed, 325 insertions(+), 250 deletions(-) diff --git a/packages/zowe-explorer-api/CHANGELOG.md b/packages/zowe-explorer-api/CHANGELOG.md index 048e04fcc4..1c85de938f 100644 --- a/packages/zowe-explorer-api/CHANGELOG.md +++ b/packages/zowe-explorer-api/CHANGELOG.md @@ -9,6 +9,7 @@ All notable changes to the "zowe-explorer-api" extension will be documented in t ### Bug fixes - Fixed an issue where the `responseTimeout` profile property was ignored for z/OSMF MVS and USS API calls. [#3225](https://github.com/zowe/zowe-explorer-vscode/issues/3225) +- Deprecated the method `ProfilesCache.updateProfilesArrays`. Use `ProfilesCache.updateCachedProfile` instead, which handles updating credentials cached in memory when `autoStore` is false. [#3120](https://github.com/zowe/zowe-explorer-vscode/issues/3120) ## `2.18.0` diff --git a/packages/zowe-explorer-api/__tests__/__unit__/profiles/ProfilesCache.unit.test.ts b/packages/zowe-explorer-api/__tests__/__unit__/profiles/ProfilesCache.unit.test.ts index d1155b58e9..b9023dcb17 100644 --- a/packages/zowe-explorer-api/__tests__/__unit__/profiles/ProfilesCache.unit.test.ts +++ b/packages/zowe-explorer-api/__tests__/__unit__/profiles/ProfilesCache.unit.test.ts @@ -230,6 +230,35 @@ describe("ProfilesCache", () => { expect((profCache as any).defaultProfileByType.get("zosmf").profile).toMatchObject(lpar2Profile.profile); }); + it("updateCachedProfile should refresh all profiles when autoStore is true", async () => { + const profCache = new ProfilesCache(fakeLogger as unknown as zowe.imperative.Logger); + jest.spyOn(profCache, "getProfileInfo").mockResolvedValueOnce({ + getTeamConfig: jest.fn().mockReturnValue({ properties: { autoStore: true } }), + } as unknown as zowe.imperative.ProfileInfo); + const refreshSpy = jest.spyOn(profCache, "refresh").mockImplementation(); + await profCache.updateCachedProfile({ + ...lpar1Profile, + profile: lpar2Profile.profile, + } as zowe.imperative.IProfileLoaded); + expect(refreshSpy).toHaveBeenCalledTimes(1); + }); + + it("updateCachedProfile should update cached profile when autoStore is false", async () => { + const profCache = new ProfilesCache(fakeLogger as unknown as zowe.imperative.Logger); + profCache.allProfiles = [lpar1Profile as zowe.imperative.IProfileLoaded]; + (profCache as any).defaultProfileByType = new Map([["zosmf", { ...profCache.allProfiles[0] }]]); + expect(profCache.allProfiles[0].profile).toMatchObject(lpar1Profile.profile); + jest.spyOn(profCache, "getProfileInfo").mockResolvedValueOnce({ + getTeamConfig: jest.fn().mockReturnValue({ properties: { autoStore: false } }), + } as unknown as zowe.imperative.ProfileInfo); + await profCache.updateCachedProfile({ + ...lpar1Profile, + profile: lpar2Profile.profile, + } as zowe.imperative.IProfileLoaded); + expect(profCache.allProfiles[0].profile).toMatchObject(lpar2Profile.profile); + expect((profCache as any).defaultProfileByType.get("zosmf").profile).toMatchObject(lpar2Profile.profile); + }); + it("getDefaultProfile should find default profile given type", () => { const profCache = new ProfilesCache(fakeLogger as unknown as zowe.imperative.Logger); (profCache as any).defaultProfileByType = new Map([["zosmf", lpar1Profile]]); diff --git a/packages/zowe-explorer-api/__tests__/__unit__/tree/ZoweTreeNode.unit.test.ts b/packages/zowe-explorer-api/__tests__/__unit__/tree/ZoweTreeNode.unit.test.ts index 18ae225350..b813ee53e2 100644 --- a/packages/zowe-explorer-api/__tests__/__unit__/tree/ZoweTreeNode.unit.test.ts +++ b/packages/zowe-explorer-api/__tests__/__unit__/tree/ZoweTreeNode.unit.test.ts @@ -13,7 +13,17 @@ import * as vscode from "vscode"; import { ZoweTreeNode } from "../../../src/tree/ZoweTreeNode"; import { IZoweTreeNode } from "../../../src/tree/IZoweTreeNode"; import { imperative } from "@zowe/cli"; + describe("ZoweTreeNode", () => { + const innerProfile = { user: "apple", password: "banana" }; + const fakeProfile: imperative.IProfileLoaded = { + name: "amazingProfile", + profile: innerProfile, + message: "", + type: "zosmf", + failNotFound: true, + }; + const makeNode = ( name: string, collapseState: vscode.TreeItemCollapsibleState, @@ -46,8 +56,8 @@ describe("ZoweTreeNode", () => { it("getProfile should return profile of current node", () => { const node = makeNode("test", vscode.TreeItemCollapsibleState.None, undefined); - node.setProfileToChoice("myProfile" as unknown as imperative.IProfileLoaded); - expect(node.getProfile()).toBe("myProfile"); + node.setProfileToChoice(fakeProfile); + expect(node.getProfile().name).toBe("amazingProfile"); }); it("getProfile should return profile of parent node", () => { @@ -78,4 +88,28 @@ describe("ZoweTreeNode", () => { expect(node.getProfile()).toBeUndefined(); expect(node.getProfileName()).toBeUndefined(); }); + + it("setProfileToChoice should update properties on existing profile object", () => { + const node = makeNode("test", vscode.TreeItemCollapsibleState.None, undefined, undefined, { + ...fakeProfile, + }); + node.setProfileToChoice({ ...fakeProfile, profile: { host: "example.com", port: 443 } }); + expect(node.getProfile().profile?.port).toBeDefined(); + }); + + it("setProfileToChoice should update child nodes with the new profile", () => { + const node = makeNode("test", vscode.TreeItemCollapsibleState.Expanded, undefined); + node.setProfileToChoice({ ...fakeProfile, profile: { ...fakeProfile.profile, user: "banana" } }); + const nodeChild = makeNode("child", vscode.TreeItemCollapsibleState.None, undefined); + nodeChild.setProfileToChoice(node.getProfile()); + node.children = [nodeChild as any]; + const fsEntry = { + metadata: { + profile: node.getProfile(), + }, + }; + expect(node.getProfile().profile?.user).toBe("banana"); + expect(nodeChild.getProfile().profile?.user).toBe("banana"); + expect(fsEntry.metadata.profile.profile?.user).toBe("banana"); + }); }); diff --git a/packages/zowe-explorer-api/__tests__/__unit__/vscode/ZoweVsCodeExtension.unit.test.ts b/packages/zowe-explorer-api/__tests__/__unit__/vscode/ZoweVsCodeExtension.unit.test.ts index eb07c71dc7..1eea9019b1 100644 --- a/packages/zowe-explorer-api/__tests__/__unit__/vscode/ZoweVsCodeExtension.unit.test.ts +++ b/packages/zowe-explorer-api/__tests__/__unit__/vscode/ZoweVsCodeExtension.unit.test.ts @@ -219,6 +219,7 @@ describe("ZoweVsCodeExtension", () => { mergeArgsForProfile: jest.fn().mockReturnValue({ knownArgs: [] }), }), refresh: jest.fn(), + updateCachedProfile: jest.fn(), }; beforeEach(() => { @@ -460,6 +461,7 @@ describe("ZoweVsCodeExtension", () => { updateProperty: mockUpdateProperty, }), refresh: jest.fn(), + updateCachedProfile: jest.fn(), }); const showInputBoxSpy = jest.spyOn(Gui, "showInputBox").mockResolvedValueOnce("fakeUser").mockResolvedValueOnce("fakePassword"); const saveCredentialsSpy = jest.spyOn(ZoweVsCodeExtension as any, "saveCredentials"); @@ -485,6 +487,7 @@ describe("ZoweVsCodeExtension", () => { updateProperty: mockUpdateProperty, }), refresh: jest.fn(), + updateCachedProfile: jest.fn(), }); const showInputBoxSpy = jest.spyOn(Gui, "showInputBox").mockResolvedValueOnce("fakeUser").mockResolvedValueOnce("fakePassword"); const saveCredentialsSpy = jest.spyOn(ZoweVsCodeExtension as any, "saveCredentials"); @@ -513,6 +516,7 @@ describe("ZoweVsCodeExtension", () => { updateProperty: mockUpdateProperty, }), refresh: jest.fn(), + updateCachedProfile: jest.fn(), }); const showInputBoxSpy = jest.spyOn(Gui, "showInputBox").mockResolvedValueOnce("fakeUser").mockResolvedValueOnce("fakePassword"); jest.spyOn(Gui, "showMessage").mockResolvedValueOnce("yes"); @@ -539,6 +543,7 @@ describe("ZoweVsCodeExtension", () => { updateProperty: mockUpdateProperty, }), refresh: jest.fn(), + updateCachedProfile: jest.fn(), }); const showInputBoxSpy = jest.spyOn(Gui, "showInputBox").mockResolvedValueOnce("fakeUser").mockResolvedValueOnce("fakePassword"); jest.spyOn(Gui, "showMessage").mockResolvedValueOnce(undefined); diff --git a/packages/zowe-explorer-api/src/profiles/ProfilesCache.ts b/packages/zowe-explorer-api/src/profiles/ProfilesCache.ts index ae01f01fbe..90ba3c9260 100644 --- a/packages/zowe-explorer-api/src/profiles/ProfilesCache.ts +++ b/packages/zowe-explorer-api/src/profiles/ProfilesCache.ts @@ -16,6 +16,7 @@ import { URL } from "url"; import * as zowe from "@zowe/cli"; import { ZoweExplorerApi } from "./ZoweExplorerApi"; +import { IZoweNodeType } from "../tree"; // TODO: find a home for constants export const CONTEXT_PREFIX = "_"; @@ -127,9 +128,8 @@ export class ProfilesCache { /** * Updates profile in allProfiles array and if default updates defaultProfileByType - * + * @deprecated Use `updateCachedProfile` instead * @param {string} profileLoaded - * * @returns {void} */ public updateProfilesArrays(profileLoaded: zowe.imperative.IProfileLoaded): void { @@ -145,6 +145,25 @@ export class ProfilesCache { } } + public async updateCachedProfile( + profileLoaded: zowe.imperative.IProfileLoaded, + profileNode?: IZoweNodeType, + zeRegister?: ZoweExplorerApi.IApiRegisterClient + ): Promise { + if ((await this.getProfileInfo()).getTeamConfig().properties.autoStore) { + await this.refresh(zeRegister); + } else { + // Note: When autoStore is disabled, nested profiles within this service profile may not have their credentials updated. + const profIndex = this.allProfiles.findIndex((profile) => profile.type === profileLoaded.type && profile.name === profileLoaded.name); + this.allProfiles[profIndex].profile = profileLoaded.profile; + const defaultProf = this.defaultProfileByType.get(profileLoaded.type); + if (defaultProf != null && defaultProf.name === profileLoaded.name) { + this.defaultProfileByType.set(profileLoaded.type, profileLoaded); + } + } + profileNode?.setProfileToChoice(profileLoaded); + } + /** * This returns default profile by type from defaultProfileByType * diff --git a/packages/zowe-explorer-api/src/tree/ZoweTreeNode.ts b/packages/zowe-explorer-api/src/tree/ZoweTreeNode.ts index 27ef201553..f44f8ffa92 100644 --- a/packages/zowe-explorer-api/src/tree/ZoweTreeNode.ts +++ b/packages/zowe-explorer-api/src/tree/ZoweTreeNode.ts @@ -112,7 +112,8 @@ export class ZoweTreeNode extends vscode.TreeItem { * @param {imperative.IProfileLoaded} The profile you will set the node to use */ public setProfileToChoice(aProfile: imperative.IProfileLoaded): void { - this.profile = aProfile; + // Don't reassign profile if its already defined, as we want to keep the reference valid for other nodes + this.profile = Object.assign(this.profile ?? {}, aProfile); } /** * Sets the session for this node to the one chosen in parameters. diff --git a/packages/zowe-explorer-api/src/vscode/ZoweVsCodeExtension.ts b/packages/zowe-explorer-api/src/vscode/ZoweVsCodeExtension.ts index a1cc9337e7..7e561f8b25 100644 --- a/packages/zowe-explorer-api/src/vscode/ZoweVsCodeExtension.ts +++ b/packages/zowe-explorer-api/src/vscode/ZoweVsCodeExtension.ts @@ -112,7 +112,7 @@ export class ZoweVsCodeExtension { options: IPromptCredentialsOptions, apiRegister: ZoweExplorerApi.IApiRegisterClient ): Promise { - const cache = ZoweVsCodeExtension.profilesCache; + const cache = options.zeProfiles ?? ZoweVsCodeExtension.profilesCache; const profInfo = await cache.getProfileInfo(); const setSecure = options.secure ?? profInfo.isSecured(); @@ -143,7 +143,7 @@ export class ZoweVsCodeExtension { await profInfo.updateProperty({ ...upd, property: "user", value: creds[0], setSecure }); await profInfo.updateProperty({ ...upd, property: "password", value: creds[1], setSecure }); } - await cache.refresh(apiRegister); + await cache.updateCachedProfile(loadProfile, undefined, apiRegister); return loadProfile; } @@ -228,23 +228,11 @@ export class ZoweVsCodeExtension { // If base profile already has a token type stored, then we check whether or not the connection details are the same (serviceProfile.profile.host === baseProfile.profile.host && serviceProfile.profile.port === baseProfile.profile.port); // If the connection details do not match, then we MUST forcefully store the token in the service profile - let profileToUpdate: imperative.IProfileLoaded; - if (connOk) { - profileToUpdate = baseProfile; - } else { - profileToUpdate = serviceProfile; - } + const profileToUpdate = connOk ? baseProfile : serviceProfile; await cache.updateBaseProfileFileLogin(profileToUpdate, updBaseProfile, !connOk); - const baseIndex = cache.allProfiles.findIndex((profile) => profile.name === profileToUpdate.name); - cache.allProfiles[baseIndex] = { ...profileToUpdate, profile: { ...profileToUpdate.profile, ...updBaseProfile } }; - - if (node) { - node.setProfileToChoice({ - ...node.getProfile(), - profile: { ...node.getProfile().profile, ...updBaseProfile }, - }); - } + serviceProfile.profile = { ...serviceProfile.profile, ...updBaseProfile }; + await cache.updateCachedProfile(serviceProfile, node); return true; } @@ -283,11 +271,9 @@ export class ZoweVsCodeExtension { await (zeRegister?.getCommonApi(serviceProfile).logout ?? Logout.apimlLogout)(updSession); const connOk = serviceProfile.profile.host === baseProfile.profile.host && serviceProfile.profile.port === baseProfile.profile.port; - if (connOk) { - await cache.updateBaseProfileFileLogout(baseProfile); - } else { - await cache.updateBaseProfileFileLogout(serviceProfile); - } + await cache.updateBaseProfileFileLogout(connOk ? baseProfile : serviceProfile); + serviceProfile.profile = { ...serviceProfile.profile, tokenType: undefined, tokenValue: undefined }; + await cache.updateCachedProfile(serviceProfile); } } diff --git a/packages/zowe-explorer-api/src/vscode/doc/IPromptCredentials.ts b/packages/zowe-explorer-api/src/vscode/doc/IPromptCredentials.ts index ac98b31f3d..8fbc5b7ad2 100644 --- a/packages/zowe-explorer-api/src/vscode/doc/IPromptCredentials.ts +++ b/packages/zowe-explorer-api/src/vscode/doc/IPromptCredentials.ts @@ -11,6 +11,7 @@ import { imperative } from "@zowe/cli"; import { InputBoxOptions, OpenDialogOptions } from "vscode"; +import { ProfilesCache } from "../../profiles"; export interface IPromptCredentialsCommonOptions { rePrompt?: boolean; @@ -23,6 +24,7 @@ export interface IPromptCredentialsOptions extends IPromptCredentialsCommonOptio sessionName?: string; sessionType?: string; secure?: boolean; + zeProfiles?: ProfilesCache; } export interface IPromptUserPassOptions extends IPromptCredentialsCommonOptions { diff --git a/packages/zowe-explorer/CHANGELOG.md b/packages/zowe-explorer/CHANGELOG.md index e53ea6dbf9..e2ac8d00b4 100644 --- a/packages/zowe-explorer/CHANGELOG.md +++ b/packages/zowe-explorer/CHANGELOG.md @@ -17,6 +17,8 @@ All notable changes to the "vscode-extension-for-zowe" extension will be documen - Fixed an issue where a migrated data set is unusable after it is recalled through Zowe Explorer. [#3294](https://github.com/zowe/zowe-explorer-vscode/issues/3294) - Fixed an issue where a recalled PDS is expandable after it is migrated through Zowe Explorer. [#3294](https://github.com/zowe/zowe-explorer-vscode/issues/3294) - Fixed an issue where data set nodes did not update if migrated or recalled outside of Zowe Explorer. [#3294](https://github.com/zowe/zowe-explorer-vscode/issues/3294) +- Fixed issue where Search operation did not prompt for credentials if profile contains expired token. [#2259](https://github.com/zowe/zowe-explorer-vscode/issues/2259) +- Fixed issue where inactive status was not displayed for profiles loaded from Global Config. [#3134](https://github.com/zowe/zowe-explorer-vscode/issues/3134) ## `2.18.0` diff --git a/packages/zowe-explorer/__mocks__/vscode.ts b/packages/zowe-explorer/__mocks__/vscode.ts index 992a04f39e..9f094e6e49 100644 --- a/packages/zowe-explorer/__mocks__/vscode.ts +++ b/packages/zowe-explorer/__mocks__/vscode.ts @@ -9,6 +9,31 @@ * */ +/** + * A location in the editor at which progress information can be shown. It depends on the + * location how progress is visually represented. + */ +export enum ProgressLocation { + /** + * Show progress for the source control viewlet, as overlay for the icon and as progress bar + * inside the viewlet (when visible). Neither supports cancellation nor discrete progress nor + * a label to describe the operation. + */ + SourceControl = 1, + + /** + * Show progress in the status bar of the editor. Neither supports cancellation nor discrete progress. + * Supports rendering of {@link ThemeIcon theme icons} via the `$()`-syntax in the progress label. + */ + Window = 10, + + /** + * Show progress as notification with an optional cancel button. Supports to show infinite and discrete + * progress but does not support rendering of icons. + */ + Notification = 15, +} + export enum ViewColumn { /** * A *symbolic* editor column representing the currently active column. This value diff --git a/packages/zowe-explorer/__tests__/__unit__/Profiles.extended.unit.test.ts b/packages/zowe-explorer/__tests__/__unit__/Profiles.extended.unit.test.ts index cf4cfd5252..4ed5772635 100644 --- a/packages/zowe-explorer/__tests__/__unit__/Profiles.extended.unit.test.ts +++ b/packages/zowe-explorer/__tests__/__unit__/Profiles.extended.unit.test.ts @@ -30,7 +30,7 @@ import * as vscode from "vscode"; import * as utils from "../../src/utils/ProfilesUtils"; import * as globals from "../../src/globals"; import * as zowe from "@zowe/cli"; -import { Gui, ProfilesCache, ZoweTreeNode, ZoweVsCodeExtension } from "@zowe/zowe-explorer-api"; +import { Gui, IProfileValidation, ProfilesCache, ZoweTreeNode, ZoweVsCodeExtension } from "@zowe/zowe-explorer-api"; import { Profiles } from "../../src/Profiles"; import { ZoweExplorerExtender } from "../../src/ZoweExplorerExtender"; import { ZoweExplorerApiRegister } from "../../../zowe-explorer/src/ZoweExplorerApiRegister"; @@ -46,7 +46,7 @@ jest.mock("child_process"); jest.mock("fs"); jest.mock("fs-extra"); -async function createGlobalMocks() { +function createGlobalMocks() { const newMocks = { log: zowe.imperative.Logger.getAppLogger(), mockShowInputBox: jest.fn(), @@ -73,8 +73,6 @@ async function createGlobalMocks() { Notification: 15, }; }), - withProgress: null, - mockCallback: null, mockUrlInfo: { valid: true, protocol: "https", @@ -82,14 +80,22 @@ async function createGlobalMocks() { port: 143, }, mockProfileInstance: null, - mockProfilesCache: null, mockConfigInstance: createConfigInstance(), mockConfigLoad: null, }; - newMocks.mockProfilesCache = new ProfilesCache(zowe.imperative.Logger.getAppLogger()); - newMocks.withProgress = jest.fn().mockImplementation((_progLocation, _callback) => { - return newMocks.mockCallback; + Object.defineProperty(vscode.window, "withProgress", { + value: jest.fn().mockImplementation((progLocation, callback) => { + const progress = { + report: jest.fn(), + }; + const token = { + isCancellationRequested: false, + onCancellationRequested: jest.fn(), + }; + return callback(progress, token); + }), + configurable: true, }); Object.defineProperty(vscode.window, "showInformationMessage", { @@ -128,8 +134,6 @@ async function createGlobalMocks() { value: newMocks.mockConfigurationTarget, configurable: true, }); - Object.defineProperty(vscode, "ProgressLocation", { value: newMocks.ProgressLocation, configurable: true }); - Object.defineProperty(vscode.window, "withProgress", { value: newMocks.withProgress, configurable: true }); Object.defineProperty(ZoweLogger, "error", { value: jest.fn(), configurable: true }); Object.defineProperty(ZoweLogger, "debug", { value: jest.fn(), configurable: true }); Object.defineProperty(ZoweLogger, "warn", { value: jest.fn(), configurable: true }); @@ -248,7 +252,7 @@ describe("Profiles Unit Test - Function createInstance", () => { }); it("Tests that createInstance catches error and logs it", async () => { - const globalMocks = await createGlobalMocks(); + const globalMocks = createGlobalMocks(); jest.spyOn(Profiles.prototype, "refresh").mockRejectedValueOnce(new Error("test error")); jest.spyOn(Gui, "errorMessage").mockResolvedValueOnce(""); const errorSpy = jest.spyOn(ZoweLogger, "error"); @@ -260,7 +264,7 @@ describe("Profiles Unit Test - Function createInstance", () => { }); describe("Profiles Unit Tests - Function createNewConnection for v1 Profiles", () => { - async function createBlockMocks(globalMocks) { + function createBlockMocks(globalMocks) { const newMocks = { testSchemas: newTestSchemas(), inputBox: createInputBox("input"), @@ -275,7 +279,7 @@ describe("Profiles Unit Tests - Function createNewConnection for v1 Profiles", ( }); it("Tests that createNewConnection fails if profileName is missing", async () => { - const globalMocks = await createGlobalMocks(); + const globalMocks = createGlobalMocks(); await Profiles.getInstance().createNewConnection(""); expect(globalMocks.mockShowInformationMessage.mock.calls.length).toBe(1); @@ -283,7 +287,7 @@ describe("Profiles Unit Tests - Function createNewConnection for v1 Profiles", ( }); it("Tests that createNewConnection fails if profileType is missing", async () => { - const globalMocks = await createGlobalMocks(); + const globalMocks = createGlobalMocks(); jest.spyOn(globalMocks.mockProfileInstance, "getProfileType").mockImplementation(undefined); await Profiles.getInstance().createNewConnection(globalMocks.testProfile.name, undefined); @@ -292,8 +296,8 @@ describe("Profiles Unit Tests - Function createNewConnection for v1 Profiles", ( }); it("Tests that createNewConnection fails if zOSMF URL is missing", async () => { - const globalMocks = await createGlobalMocks(); - const blockMocks = await createBlockMocks(globalMocks); + const globalMocks = createGlobalMocks(); + const blockMocks = createBlockMocks((globalMocks); jest.spyOn(globalMocks.mockProfileInstance, "getSchema").mockReturnValue(blockMocks.testSchemas); globalMocks.mockCreateInputBox.mockResolvedValue(undefined); @@ -304,8 +308,8 @@ describe("Profiles Unit Tests - Function createNewConnection for v1 Profiles", ( }); it("Tests that createNewConnection fails if user escapes create at username", async () => { - const globalMocks = await createGlobalMocks(); - const blockMocks = await createBlockMocks(globalMocks); + const globalMocks = createGlobalMocks(); + const blockMocks = createBlockMocks((globalMocks); jest.spyOn(globalMocks.mockProfileInstance, "getSchema").mockReturnValue(blockMocks.testSchemas); jest.spyOn(globalMocks.mockProfileInstance, "urlInfo").mockReturnValue(globalMocks.mockUrlInfo); @@ -316,8 +320,8 @@ describe("Profiles Unit Tests - Function createNewConnection for v1 Profiles", ( }); it("Tests that createNewConnection fails if user escapes create at password", async () => { - const globalMocks = await createGlobalMocks(); - const blockMocks = await createBlockMocks(globalMocks); + const globalMocks = createGlobalMocks(); + const blockMocks = createBlockMocks((globalMocks); jest.spyOn(globalMocks.mockProfileInstance, "getSchema").mockReturnValue(blockMocks.testSchemas); jest.spyOn(globalMocks.mockProfileInstance, "urlInfo").mockReturnValue(globalMocks.mockUrlInfo); @@ -329,8 +333,8 @@ describe("Profiles Unit Tests - Function createNewConnection for v1 Profiles", ( }); it("Tests that createNewConnection fails if user escapes create at rejectUnauthorized", async () => { - const globalMocks = await createGlobalMocks(); - const blockMocks = await createBlockMocks(globalMocks); + const globalMocks = createGlobalMocks(); + const blockMocks = createBlockMocks((globalMocks); jest.spyOn(globalMocks.mockProfileInstance, "getSchema").mockReturnValue(blockMocks.testSchemas); jest.spyOn(globalMocks.mockProfileInstance, "urlInfo").mockReturnValue(globalMocks.mockUrlInfo); @@ -343,8 +347,8 @@ describe("Profiles Unit Tests - Function createNewConnection for v1 Profiles", ( }); it("Tests that createNewConnection fails if profileName is a duplicate", async () => { - const globalMocks = await createGlobalMocks(); - const blockMocks = await createBlockMocks(globalMocks); + const globalMocks = createGlobalMocks(); + const blockMocks = createBlockMocks((globalMocks); jest.spyOn(globalMocks.mockProfileInstance, "getSchema").mockReturnValue(blockMocks.testSchemas); jest.spyOn(globalMocks.mockProfileInstance, "urlInfo").mockReturnValue(globalMocks.mockUrlInfo); @@ -357,8 +361,8 @@ describe("Profiles Unit Tests - Function createNewConnection for v1 Profiles", ( }); it("Tests that createNewConnection creates a new profile", async () => { - const globalMocks = await createGlobalMocks(); - const blockMocks = await createBlockMocks(globalMocks); + const globalMocks = createGlobalMocks(); + const blockMocks = createBlockMocks((globalMocks); jest.spyOn(utils.ProfilesUtils, "getCredentialManagerOverride").mockReturnValueOnce("@zowe/cli"); @@ -373,8 +377,8 @@ describe("Profiles Unit Tests - Function createNewConnection for v1 Profiles", ( }); it("Tests that createNewConnection throws an exception and shows a config error", async () => { - const globalMocks = await createGlobalMocks(); - const blockMocks = await createBlockMocks(globalMocks); + const globalMocks = createGlobalMocks(); + const blockMocks = createBlockMocks((globalMocks); const testError = new Error("saveProfile error"); const mockSaveProfile = jest.spyOn(ProfilesCache.prototype as any, "saveProfile").mockImplementationOnce(async (_values, _name, _type) => { @@ -397,8 +401,8 @@ describe("Profiles Unit Tests - Function createNewConnection for v1 Profiles", ( }); it("Tests that createNewConnection returns 'fake' if the port is undefined and portInfo() returns correct port", async () => { - const globalMocks = await createGlobalMocks(); - const blockMocks = await createBlockMocks(globalMocks); + const globalMocks = createGlobalMocks(); + const blockMocks = createBlockMocks((globalMocks); jest.spyOn(utils.ProfilesUtils, "getCredentialManagerOverride").mockReturnValueOnce("@zowe/cli"); const customURLInfo = { valid: true, @@ -421,8 +425,8 @@ describe("Profiles Unit Tests - Function createNewConnection for v1 Profiles", ( }); it("Tests that createNewConnection returns undefined if the port is undefined and portInfo() returns NaN", async () => { - const globalMocks = await createGlobalMocks(); - const blockMocks = await createBlockMocks(globalMocks); + const globalMocks = createGlobalMocks(); + const blockMocks = createBlockMocks((globalMocks); const customURLInfo = { valid: true, protocol: "https", @@ -444,8 +448,8 @@ describe("Profiles Unit Tests - Function createNewConnection for v1 Profiles", ( }); it("Tests that createNewConnection enters default case when encoding is present in schema and value is the number 0", async () => { - const globalMocks = await createGlobalMocks(); - const blockMocks = await createBlockMocks(globalMocks); + const globalMocks = createGlobalMocks(); + const blockMocks = createBlockMocks((globalMocks); jest.spyOn(utils.ProfilesUtils, "getCredentialManagerOverride").mockReturnValueOnce("@zowe/cli"); jest.spyOn(globalMocks.mockProfileInstance, "getSchema").mockReturnValueOnce(blockMocks.testSchemas); @@ -468,8 +472,8 @@ describe("Profiles Unit Tests - Function createNewConnection for v1 Profiles", ( }); it("Tests that createNewConnection enters default case when encoding is present in schema and value is NaN", async () => { - const globalMocks = await createGlobalMocks(); - const blockMocks = await createBlockMocks(globalMocks); + const globalMocks = createGlobalMocks(); + const blockMocks = createBlockMocks((globalMocks); jest.spyOn(utils.ProfilesUtils, "getCredentialManagerOverride").mockReturnValueOnce("@zowe/cli"); jest.spyOn(globalMocks.mockProfileInstance, "getSchema").mockReturnValueOnce(blockMocks.testSchemas); @@ -493,8 +497,8 @@ describe("Profiles Unit Tests - Function createNewConnection for v1 Profiles", ( }); it("Tests that createNewConnection enters default case when boolean is present in schema and returns undefined", async () => { - const globalMocks = await createGlobalMocks(); - const blockMocks = await createBlockMocks(globalMocks); + const globalMocks = createGlobalMocks(); + const blockMocks = createBlockMocks((globalMocks); jest.spyOn(globalMocks.mockProfileInstance, "getSchema").mockReturnValueOnce(blockMocks.testSchemas); jest.spyOn(globalMocks.mockProfileInstance, "urlInfo").mockReturnValueOnce(globalMocks.mockUrlInfo); @@ -521,8 +525,8 @@ describe("Profiles Unit Tests - Function createNewConnection for v1 Profiles", ( }); it("Tests that createNewConnection enters default case when string is present in schema and returns 'fake'", async () => { - const globalMocks = await createGlobalMocks(); - const blockMocks = await createBlockMocks(globalMocks); + const globalMocks = createGlobalMocks(); + const blockMocks = createBlockMocks((globalMocks); jest.spyOn(utils.ProfilesUtils, "getCredentialManagerOverride").mockReturnValueOnce("@zowe/cli"); jest.spyOn(globalMocks.mockProfileInstance, "getSchema").mockReturnValueOnce(blockMocks.testSchemas); @@ -551,7 +555,7 @@ describe("Profiles Unit Tests - Function createNewConnection for v1 Profiles", ( }); describe("Profiles Unit Tests - Function createZoweSession", () => { - async function createBlockMocks(globalMocks) { + function createBlockMocks(globalMocks) { const newMocks = { session: createISessionWithoutCredentials(), treeView: createTreeView(), @@ -566,8 +570,8 @@ describe("Profiles Unit Tests - Function createZoweSession", () => { return newMocks; } it("Tests that createZoweSession presents correct message when escaping selection of quickpick", async () => { - const globalMocks = await createGlobalMocks(); - const blockMocks = await createBlockMocks(globalMocks); + const globalMocks = createGlobalMocks(); + const blockMocks = createBlockMocks((globalMocks); const spy = jest.spyOn(Gui, "createQuickPick"); const spyDebug = jest.spyOn(ZoweLogger, "debug"); jest.spyOn(Gui, "resolveQuickPick").mockResolvedValueOnce(undefined); @@ -580,7 +584,7 @@ describe("Profiles Unit Tests - Function createZoweSession", () => { }); it("Tests that createZoweSession runs successfully", async () => { - const globalMocks = await createGlobalMocks(); + const globalMocks = createGlobalMocks(); const spyInfo = jest.spyOn(ZoweLogger, "info"); jest.spyOn(Gui, "createQuickPick").mockReturnValue({ show: jest.fn(), @@ -611,7 +615,7 @@ describe("Profiles Unit Tests - Function createZoweSession", () => { }); it("Tests that createZoweSession runs successfully and uses the chosenProfile", async () => { - const globalMocks = await createGlobalMocks(); + const globalMocks = createGlobalMocks(); jest.spyOn(Gui, "createQuickPick").mockReturnValue({ show: jest.fn(), hide: jest.fn(), @@ -626,7 +630,7 @@ describe("Profiles Unit Tests - Function createZoweSession", () => { }); it("Tests that createZoweSession catches error and logs it", async () => { - const globalMocks = await createGlobalMocks(); + const globalMocks = createGlobalMocks(); jest.spyOn(Gui, "createQuickPick").mockReturnValue({ show: jest.fn(), hide: jest.fn(), @@ -645,7 +649,7 @@ describe("Profiles Unit Tests - Function createZoweSession", () => { describe("Profiles Unit Tests - Function editZoweConfigFile", () => { it("Tests that editZoweConfigFile presents correct message when escaping selection of quickpick", async () => { - const globalMocks = await createGlobalMocks(); + const globalMocks = createGlobalMocks(); const spy = jest.spyOn(Gui, "showQuickPick"); spy.mockResolvedValueOnce(undefined); @@ -655,7 +659,7 @@ describe("Profiles Unit Tests - Function editZoweConfigFile", () => { spy.mockClear(); }); it("Tests that editZoweConfigFile opens correct file when Global is selected", async () => { - const globalMocks = await createGlobalMocks(); + const globalMocks = createGlobalMocks(); const spyQuickPick = jest.spyOn(Gui, "showQuickPick"); spyQuickPick.mockResolvedValueOnce("Global: in the Zowe home directory" as any); @@ -667,7 +671,7 @@ describe("Profiles Unit Tests - Function editZoweConfigFile", () => { spyOpenFile.mockClear(); }); it("Tests that editZoweConfigFile opens correct file when only Global config available", async () => { - const globalMocks = await createGlobalMocks(); + const globalMocks = createGlobalMocks(); globalMocks.mockConfigLoad.load.mockResolvedValueOnce({ layers: [ { @@ -685,7 +689,7 @@ describe("Profiles Unit Tests - Function editZoweConfigFile", () => { spyOpenFile.mockClear(); }); it("Tests that editZoweConfigFile opens correct file when Project is selected", async () => { - const globalMocks = await createGlobalMocks(); + const globalMocks = createGlobalMocks(); const spyQuickPick = jest.spyOn(Gui, "showQuickPick"); spyQuickPick.mockResolvedValueOnce("Project: in the current working directory" as any); @@ -697,7 +701,7 @@ describe("Profiles Unit Tests - Function editZoweConfigFile", () => { spyOpenFile.mockClear(); }); it("Tests that editZoweConfigFile opens correct file when only Project config available", async () => { - const globalMocks = await createGlobalMocks(); + const globalMocks = createGlobalMocks(); globalMocks.mockConfigLoad.load.mockResolvedValueOnce({ layers: [ { @@ -717,7 +721,7 @@ describe("Profiles Unit Tests - Function editZoweConfigFile", () => { }); describe("Profiles Unit Tests - Function createZoweSchema", () => { - async function createBlockMocks(globalMocks) { + function createBlockMocks(globalMocks) { const newMocks = { session: createISessionWithoutCredentials(), treeView: createTreeView(), @@ -741,8 +745,8 @@ describe("Profiles Unit Tests - Function createZoweSchema", () => { return newMocks; } it("Tests that createZoweSchema presents correct message when escaping selection of config location prompt", async () => { - const globalMocks = await createGlobalMocks(); - const blockMocks = await createBlockMocks(globalMocks); + const globalMocks = createGlobalMocks(); + const blockMocks = createBlockMocks((globalMocks); const spy = jest.spyOn(Gui, "showQuickPick"); spy.mockResolvedValueOnce(undefined); @@ -752,8 +756,8 @@ describe("Profiles Unit Tests - Function createZoweSchema", () => { spy.mockClear(); }); it("Tests that createZoweSchema will open correct config file when cancelling creation in location with existing config file", async () => { - const globalMocks = await createGlobalMocks(); - const blockMocks = await createBlockMocks(globalMocks); + const globalMocks = createGlobalMocks(); + const blockMocks = createBlockMocks((globalMocks); const spyQuickPick = jest.spyOn(Gui, "showQuickPick"); globalMocks.mockShowQuickPick.mockResolvedValueOnce("Global: in the Zowe home directory"); @@ -774,8 +778,8 @@ describe("Profiles Unit Tests - Function createZoweSchema", () => { spyOpenFile.mockClear(); }); it("Test that createZoweSchema will open config on error if error deals with parsing file", async () => { - const globalMocks = await createGlobalMocks(); - const blockMocks = await createBlockMocks(globalMocks); + const globalMocks = createGlobalMocks(); + const blockMocks = createBlockMocks((globalMocks); const spyQuickPick = jest.spyOn(Gui, "showQuickPick"); globalMocks.mockShowQuickPick.mockResolvedValueOnce("Global: in the Zowe home directory"); @@ -792,8 +796,8 @@ describe("Profiles Unit Tests - Function createZoweSchema", () => { spyZoweConfigError.mockClear(); }); it("Test that createZoweSchema will auto create global if VSC not in project and config doesn't exist", async () => { - const globalMocks = await createGlobalMocks(); - const blockMocks = await createBlockMocks(globalMocks); + const globalMocks = createGlobalMocks(); + const blockMocks = createBlockMocks((globalMocks); Object.defineProperty(vscode.workspace, "workspaceFolders", { value: undefined, configurable: true, @@ -820,8 +824,8 @@ describe("Profiles Unit Tests - Function createZoweSchema", () => { }); it("Tests that createZoweSchema will return the config file path", async () => { - const globalMocks = await createGlobalMocks(); - const blockMocks = await createBlockMocks(globalMocks); + const globalMocks = createGlobalMocks(); + const blockMocks = createBlockMocks((globalMocks); Object.defineProperty(globals, "ISTHEIA", { value: true, configurable: true }); Object.defineProperty(vscode.workspace, "workspaceFolders", { @@ -1102,15 +1106,14 @@ describe("Profiles Unit Tests - function promptCredentials", () => { profile: { user: "test", password: "12345", - base64EncodedAuth: "encodedAuth", } as zowe.imperative.IProfile, } as zowe.imperative.IProfileLoaded); jest.spyOn(Profiles.getInstance(), "updateProfilesArrays").mockImplementation(); - await expect(Profiles.getInstance().promptCredentials("secure_config_props")).resolves.toEqual(["test", "12345", "encodedAuth"]); + await expect(Profiles.getInstance().promptCredentials("secure_config_props")).resolves.toEqual(["test", "12345"]); }); it("Tests that promptCredentials catches error and logs it", async () => { - const globalMocks = await createGlobalMocks(); + const globalMocks = createGlobalMocks(); jest.spyOn(Profiles.getInstance(), "getProfileInfo").mockRejectedValueOnce(new Error("test error")); jest.spyOn(Gui, "errorMessage").mockResolvedValueOnce(""); const errorSpy = jest.spyOn(ZoweLogger, "error"); @@ -1196,23 +1199,30 @@ describe("Profiles Unit Tests - function getDeleteProfile", () => { }); describe("Profiles Unit Tests - function validateProfile", () => { - it("should return an object with profile validation status if validated profiles exist", async () => { + function createBlockMocks() { + createGlobalMocks(); + const newMocks = { + profilesForValidation: [] as IProfileValidation[], + getStatusSpy: jest.fn(), + }; + Object.defineProperty(Profiles.getInstance(), "profilesForValidation", { - value: [ - { - name: "test1", - message: "", - type: "", - status: "active", - failNotFound: false, - }, - ], + get: () => newMocks.profilesForValidation, configurable: true, }); - jest.spyOn(Gui, "withProgress").mockResolvedValue(undefined); - jest.spyOn(ZoweExplorerApiRegister.getInstance(), "getCommonApi").mockResolvedValueOnce({ - getStatus: () => "active", + jest.spyOn(ZoweExplorerApiRegister.getInstance(), "getCommonApi").mockReturnValueOnce({ + getStatus: newMocks.getStatusSpy, } as never); + + return newMocks; + } + + it("should return an object with profile validation status if validated profiles exist", async () => { + const blockMocks = createBlockMocks(); + blockMocks.profilesForValidation.push({ + name: "test1", + status: "active", + }); await expect( Profiles.getInstance().validateProfiles({ name: "test1", @@ -1224,16 +1234,11 @@ describe("Profiles Unit Tests - function validateProfile", () => { name: "test1", status: "active", }); + expect(blockMocks.getStatusSpy).not.toHaveBeenCalled(); }); it("should return an object with profile validation status of 'active' from session status if validated profiles does not exist", async () => { - Object.defineProperty(Profiles.getInstance(), "profilesForValidation", { - value: [], - configurable: true, - }); - jest.spyOn(Gui, "withProgress").mockResolvedValue("active"); - jest.spyOn(ZoweExplorerApiRegister.getInstance(), "getCommonApi").mockResolvedValueOnce({ - getStatus: () => "active", - } as never); + const blockMocks = createBlockMocks(); + blockMocks.getStatusSpy.mockResolvedValue("active"); await expect( Profiles.getInstance().validateProfiles({ name: "test1", @@ -1245,16 +1250,11 @@ describe("Profiles Unit Tests - function validateProfile", () => { name: "test1", status: "active", }); + expect(blockMocks.getStatusSpy).toHaveBeenCalledTimes(1); }); it("should return an object with profile validation status of 'inactive' from session status if validated profiles does not exist", async () => { - Object.defineProperty(Profiles.getInstance(), "profilesForValidation", { - value: [], - configurable: true, - }); - jest.spyOn(Gui, "withProgress").mockResolvedValue("inactive"); - jest.spyOn(ZoweExplorerApiRegister.getInstance(), "getCommonApi").mockResolvedValueOnce({ - getStatus: () => "inactive", - } as never); + const blockMocks = createBlockMocks(); + blockMocks.getStatusSpy.mockResolvedValue("inactive"); await expect( Profiles.getInstance().validateProfiles({ name: "test1", @@ -1266,36 +1266,25 @@ describe("Profiles Unit Tests - function validateProfile", () => { name: "test1", status: "inactive", }); + expect(blockMocks.getStatusSpy).toHaveBeenCalledTimes(1); }); it("should handle the error if call to getStatus fails", async () => { - Object.defineProperty(Profiles.getInstance(), "profilesForValidation", { - value: [], - configurable: true, - }); - const errorHandlingSpy = jest.spyOn(utils, "errorHandling"); + const blockMocks = createBlockMocks(); const testError = new Error("failed to validate profile"); - jest.spyOn(Gui, "withProgress").mockImplementation(() => { + blockMocks.getStatusSpy.mockImplementation(() => { throw testError; }); - jest.spyOn(ZoweExplorerApiRegister.getInstance(), "getCommonApi").mockResolvedValueOnce({ - getStatus: () => "inactive", - } as never); + const errorHandlingSpy = jest.spyOn(utils, "errorHandling"); await Profiles.getInstance().validateProfiles({ name: "test1", message: "", type: "", failNotFound: false, }); - expect(errorHandlingSpy).toBeCalledWith(testError, "test1"); + expect(errorHandlingSpy).toHaveBeenCalledWith(testError, "test1"); }); it("should return an object with profile validation status of 'unverified' from session status if validated profiles doesn't exist", async () => { - Object.defineProperty(Profiles.getInstance(), "profilesForValidation", { - value: [], - configurable: true, - }); - jest.spyOn(ZoweExplorerApiRegister.getInstance(), "getCommonApi").mockResolvedValueOnce({ - getStatus: undefined, - } as never); + createBlockMocks(); await expect( Profiles.getInstance().validateProfiles({ name: "test1", @@ -1312,7 +1301,7 @@ describe("Profiles Unit Tests - function validateProfile", () => { describe("Profiles Unit Tests - function deleteProfile", () => { it("should delete profile", async () => { - const globalMocks = await createGlobalMocks(); + const globalMocks = createGlobalMocks(); const datasetSessionNode = createDatasetSessionNode(globalMocks.testSession, globalMocks.testProfile); const datasetTree = createDatasetTree(datasetSessionNode, globalMocks.testProfile); @@ -1364,7 +1353,7 @@ describe("Profiles Unit Tests - function deleteProfile", () => { }); it("Tests that deleteProfile catches error and logs it", async () => { - const globalMocks = await createGlobalMocks(); + const globalMocks = createGlobalMocks(); const datasetSessionNode = createDatasetSessionNode(globalMocks.testSession, globalMocks.testProfile); const datasetTree = createDatasetTree(datasetSessionNode, globalMocks.testProfile); const ussSessionNode = [createUSSSessionNode(globalMocks.testSession, globalMocks.testProfile)]; @@ -1433,35 +1422,57 @@ describe("Profiles Unit Tests - function checkCurrentProfile", () => { jest.spyOn(Profiles.getInstance(), "getSecurePropsForProfile").mockResolvedValue([]); }; - it("should show as active in status of profile", async () => { - const globalMocks = await createGlobalMocks(); + it("should show as active in status of profile using basic auth", async () => { + const globalMocks = createGlobalMocks(); environmentSetup(globalMocks); setupProfilesCheck(globalMocks); - jest.spyOn(Profiles.getInstance(), "validateProfiles").mockReturnValue({ status: "active", name: "sestest" } as any); - jest.spyOn(Profiles.getInstance(), "promptCredentials").mockResolvedValue(["sestest", "12345", "base64Auth"]); + jest.spyOn(Profiles.getInstance(), "validateProfiles").mockResolvedValue({ status: "active", name: "sestest" }); + const promptCredentialsSpy = jest.spyOn(Profiles.getInstance(), "promptCredentials").mockResolvedValueOnce(["sestest", "12345"]); await expect(Profiles.getInstance().checkCurrentProfile(globalMocks.testProfile)).resolves.toEqual({ name: "sestest", status: "active" }); + expect(promptCredentialsSpy).toHaveBeenCalledTimes(1); }); - it("should show as unverified in status of profile", async () => { - const globalMocks = await createGlobalMocks(); + it("should show as active in status of profile using token auth", async () => { + const globalMocks = createGlobalMocks(); + jest.spyOn(utils.ProfilesUtils, "isUsingTokenAuth").mockResolvedValueOnce(true); environmentSetup(globalMocks); setupProfilesCheck(globalMocks); - jest.spyOn(Profiles.getInstance(), "promptCredentials").mockResolvedValue(undefined); + const ssoLoginSpy = jest.spyOn(Profiles.getInstance(), "ssoLogin").mockResolvedValueOnce(); + jest.spyOn(Profiles.getInstance(), "loadNamedProfile").mockReturnValueOnce(globalMocks.testProfile); + await expect(Profiles.getInstance().checkCurrentProfile(globalMocks.testProfile)).resolves.toEqual({ name: "sestest", status: "active" }); + expect(ssoLoginSpy).toHaveBeenCalledTimes(1); + }); + it("should show as unverified in status of profile", async () => { + const globalMocks = createGlobalMocks(); + setupProfilesCheck(globalMocks); + jest.spyOn(Profiles.getInstance(), "validateProfiles").mockResolvedValue({ status: "unverified", name: "sestest" }); await expect(Profiles.getInstance().checkCurrentProfile(globalMocks.testProfile)).resolves.toEqual({ name: "sestest", status: "unverified" }); }); it("should show as inactive in status of profile", async () => { - const globalMocks = await createGlobalMocks(); + const globalMocks = createGlobalMocks(); setupProfilesCheck(globalMocks); + jest.spyOn(Profiles.getInstance(), "validateProfiles").mockResolvedValue({ status: "inactive", name: "sestest" }); await expect(Profiles.getInstance().checkCurrentProfile(globalMocks.testProfile)).resolves.toEqual({ name: "sestest", status: "inactive" }); }); + it("should show as unverified if using basic auth and has expired password", async () => { + const globalMocks = createGlobalMocks(); + environmentSetup(globalMocks); + setupProfilesCheck(globalMocks); + const errorHandlingSpy = jest.spyOn(utils, "errorHandling").mockImplementation(); + jest.spyOn(Profiles.getInstance(), "promptCredentials").mockRejectedValueOnce(new Error("Failed to login")); + await expect(Profiles.getInstance().checkCurrentProfile(globalMocks.testProfile)).resolves.toEqual({ name: "sestest", status: "unverified" }); + expect(errorHandlingSpy).toHaveBeenCalledTimes(1); + }); it("should show as unverified if using token auth and is logged out or has expired token", async () => { - const globalMocks = await createGlobalMocks(); - jest.spyOn(utils, "errorHandling").mockImplementation(); - jest.spyOn(utils.ProfilesUtils, "isUsingTokenAuth").mockResolvedValueOnce(true); + const globalMocks = createGlobalMocks(); + environmentSetup(globalMocks); setupProfilesCheck(globalMocks); + const errorHandlingSpy = jest.spyOn(utils, "errorHandling").mockImplementation(); + jest.spyOn(utils.ProfilesUtils, "isUsingTokenAuth").mockResolvedValueOnce(true); await expect(Profiles.getInstance().checkCurrentProfile(globalMocks.testProfile)).resolves.toEqual({ name: "sestest", status: "unverified" }); + expect(errorHandlingSpy).toHaveBeenCalledTimes(1); }); it("should show as unverified if profiles fail to load", async () => { - const globalMocks = await createGlobalMocks(); + const globalMocks = createGlobalMocks(); jest.spyOn(Profiles.getInstance(), "getProfileInfo").mockRejectedValueOnce(new Error("test error")); jest.spyOn(Gui, "errorMessage").mockResolvedValueOnce(""); const errorSpy = jest.spyOn(ZoweLogger, "error"); @@ -1474,7 +1485,7 @@ describe("Profiles Unit Tests - function checkCurrentProfile", () => { describe("Profiles Unit Tests - function editSession", () => { it("should successfully return the edited session", async () => { - const globalMocks = await createGlobalMocks(); + const globalMocks = createGlobalMocks(); const testSchema = newTestSchemas(); testSchema["encoding"] = { type: "string", @@ -1541,7 +1552,7 @@ describe("Profiles Unit Tests - function editSession", () => { }); it("Tests that editSession catches error and logs it", async () => { - const globalMocks = await createGlobalMocks(); + const globalMocks = createGlobalMocks(); jest.spyOn(Profiles.getInstance(), "getProfileInfo").mockRejectedValueOnce(new Error("test error")); jest.spyOn(Gui, "errorMessage").mockResolvedValueOnce(""); const errorSpy = jest.spyOn(ZoweLogger, "error"); @@ -1554,7 +1565,7 @@ describe("Profiles Unit Tests - function editSession", () => { describe("Profiles Unit Tests - function getProfileSetting", () => { it("should retrive the profile with a status of unverified", async () => { - const globalMocks = await createGlobalMocks(); + const globalMocks = createGlobalMocks(); Object.defineProperty(Profiles.getInstance(), "profilesValidationSetting", { value: [ { @@ -1597,7 +1608,7 @@ describe("Profiles Unit Tests - function getProfileSetting", () => { describe("Profiles Unit Tests - function disableValidationContext", () => { it("should disable validation context and return updated node", async () => { - const globalMocks = await createGlobalMocks(); + const globalMocks = createGlobalMocks(); const spy = jest.spyOn(ZoweLogger, "trace"); const testNode = new (ZoweTreeNode as any)( "test", @@ -1624,7 +1635,7 @@ describe("Profiles Unit Tests - function disableValidationContext", () => { describe("Profiles Unit Tests - function enableValidationContext", () => { it("should enable validation context and return updated node", async () => { - const globalMocks = await createGlobalMocks(); + const globalMocks = createGlobalMocks(); const spy = jest.spyOn(ZoweLogger, "trace"); const testNode = new (ZoweTreeNode as any)( "test", @@ -1652,7 +1663,7 @@ describe("Profiles Unit Tests - function ssoLogin", () => { let testNode; let globalMocks; beforeEach(async () => { - globalMocks = await createGlobalMocks(); + globalMocks = createGlobalMocks(); testNode = new (ZoweTreeNode as any)( "fake", vscode.TreeItemCollapsibleState.None, @@ -1728,7 +1739,7 @@ describe("Profiles Unit Tests - function handleSwitchAuthentication", () => { }); beforeEach(async () => { - globalMocks = await createGlobalMocks(); + globalMocks = createGlobalMocks(); testNode = new (ZoweTreeNode as any)( "test", vscode.TreeItemCollapsibleState.None, @@ -2293,7 +2304,7 @@ describe("Profiles Unit Tests - function ssoLogout", () => { let testNode; let globalMocks; beforeEach(async () => { - globalMocks = await createGlobalMocks(); + globalMocks = createGlobalMocks(); testNode = new (ZoweTreeNode as any)( "fake", vscode.TreeItemCollapsibleState.None, @@ -2341,7 +2352,7 @@ describe("Profiles Unit Tests - function ssoLogout", () => { describe("Profiles Unit Tests - function updateBaseProfileFileLogin", () => { it("should update the property of mProfileInfo", async () => { const privateProfile = Profiles.getInstance() as any; - const globalMocks = await createGlobalMocks(); + const globalMocks = createGlobalMocks(); const updatePropertyMock = jest.fn(); jest.spyOn(privateProfile, "getProfileInfo").mockReturnValue({ isSecured: () => true, @@ -2355,7 +2366,7 @@ describe("Profiles Unit Tests - function updateBaseProfileFileLogin", () => { describe("Profiles Unit Tests - function updateBaseProfileFileLogout", () => { it("should update the property of mProfileInfo", async () => { const privateProfile = Profiles.getInstance() as any; - const globalMocks = await createGlobalMocks(); + const globalMocks = createGlobalMocks(); const updateKnownPropertyMock = jest.fn(); jest.spyOn(privateProfile, "getProfileInfo").mockReturnValue({ isSecured: () => true, @@ -2374,7 +2385,7 @@ describe("Profiles Unit Tests - function updateBaseProfileFileLogout", () => { describe("Profiles Unit Tests - function createNonSecureProfile", () => { it("should create an unsecured profile by removing secure arrays and setting autoStore to false", async () => { - const globalMocks = await createGlobalMocks(); + const globalMocks = createGlobalMocks(); const privateProfile = Profiles.getInstance() as any; jest.spyOn(SettingsConfig, "getDirectValue").mockReturnValueOnce(false); expect(privateProfile.createNonSecureProfile(globalMocks.testTeamConfigProfile)).toEqual(undefined); @@ -2384,7 +2395,7 @@ describe("Profiles Unit Tests - function createNonSecureProfile", () => { describe("Profiles Unit Tests - function updateProfile", () => { it("should throw an error when getting the CliManager", async () => { - const globalMocks = await createGlobalMocks(); + const globalMocks = createGlobalMocks(); const privateProfile = Profiles.getInstance() as any; jest.spyOn(Profiles.getInstance(), "getCliProfileManager").mockReturnValue({ load: () => globalMocks.testProfile, @@ -2408,7 +2419,7 @@ describe("Profiles Unit Tests - function updateProfile", () => { describe("Profiles Unit Tests - function validationArraySetup", () => { it("should setup the validation array", async () => { - const globalMocks = await createGlobalMocks(); + const globalMocks = createGlobalMocks(); Object.defineProperty(Profiles.getInstance(), "profilesValidationSetting", { value: [ { @@ -2464,7 +2475,7 @@ describe("Profiles Unit Tests - function getSecurePropsForProfile", () => { jest.resetAllMocks(); }); it("should retrieve the secure properties of a profile", async () => { - const globalMocks = await createGlobalMocks(); + const globalMocks = createGlobalMocks(); jest.spyOn(Profiles.getInstance(), "getProfileInfo").mockResolvedValue({ mergeArgsForProfile: () => ({ knownArgs: [ @@ -2489,7 +2500,7 @@ describe("Profiles Unit Tests - function clearFilterFromAllTrees", () => { }); it("should fail to clear filter if no session nodes are available", async () => { - const globalMocks = await createGlobalMocks(); + const globalMocks = createGlobalMocks(); const testNode = new (ZoweTreeNode as any)( "fake", vscode.TreeItemCollapsibleState.None, @@ -2516,7 +2527,7 @@ describe("Profiles Unit Tests - function clearFilterFromAllTrees", () => { }); it("should fail to clear filters if the session node is not listed in the tree", async () => { - const globalMocks = await createGlobalMocks(); + const globalMocks = createGlobalMocks(); const testNode = new (ZoweTreeNode as any)( "fake", vscode.TreeItemCollapsibleState.None, @@ -2553,7 +2564,7 @@ describe("Profiles Unit Tests - function disableValidation", () => { }); it("should disable validation for the profile on all trees", async () => { - const globalMocks = await createGlobalMocks(); + const globalMocks = createGlobalMocks(); jest.spyOn(TreeProviders, "getSessionForAllTrees").mockReturnValue([globalMocks.testNode]); expect(globalMocks.testNode.contextValue).toEqual(globals.DS_SESSION_CONTEXT); expect(Profiles.getInstance().disableValidation(globalMocks.testNode)).toEqual(globalMocks.testNode); @@ -2561,7 +2572,7 @@ describe("Profiles Unit Tests - function disableValidation", () => { }); it("should disable validation for the profile on the current tree", async () => { - const globalMocks = await createGlobalMocks(); + const globalMocks = createGlobalMocks(); jest.spyOn(TreeProviders, "getSessionForAllTrees").mockReturnValue([globalMocks.testNode]); const disableValidationContextSpy = jest.spyOn(Profiles.getInstance(), "disableValidationContext"); expect(globalMocks.testNode.contextValue).toEqual(globals.DS_SESSION_CONTEXT); @@ -2579,7 +2590,7 @@ describe("Profiles Unit Tests - function enableValidation", () => { }); it("should enable validation for the profile on all trees", async () => { - const globalMocks = await createGlobalMocks(); + const globalMocks = createGlobalMocks(); jest.spyOn(TreeProviders, "getSessionForAllTrees").mockReturnValue([ createMockNode("test2", globals.DS_SESSION_CONTEXT), globalMocks.testNode, @@ -2590,7 +2601,7 @@ describe("Profiles Unit Tests - function enableValidation", () => { }); it("should enable validation for the profile on the current tree", async () => { - const globalMocks = await createGlobalMocks(); + const globalMocks = createGlobalMocks(); const enableValidationContextSpy = jest.spyOn(Profiles.getInstance(), "enableValidationContext"); jest.spyOn(TreeProviders, "getSessionForAllTrees").mockReturnValue([globalMocks.testNode]); expect(globalMocks.testNode.contextValue).toEqual(globals.DS_SESSION_CONTEXT); diff --git a/packages/zowe-explorer/__tests__/__unit__/dataset/actions.unit.test.ts b/packages/zowe-explorer/__tests__/__unit__/dataset/actions.unit.test.ts index 638f417153..b187f67682 100644 --- a/packages/zowe-explorer/__tests__/__unit__/dataset/actions.unit.test.ts +++ b/packages/zowe-explorer/__tests__/__unit__/dataset/actions.unit.test.ts @@ -521,13 +521,11 @@ describe("Dataset Actions Unit Tests - Function deleteDatasetPrompt", () => { mocked(vscode.window.withProgress).mockImplementation((progLocation, callback) => { const progress = { - report: (message) => { - return; - }, + report: jest.fn(), }; const token = { isCancellationRequested: false, - onCancellationRequested: undefined, + onCancellationRequested: jest.fn(), }; return callback(progress, token); }); diff --git a/packages/zowe-explorer/__tests__/__unit__/mvs/mvsNodeActions.unit.test.ts b/packages/zowe-explorer/__tests__/__unit__/mvs/mvsNodeActions.unit.test.ts index ca1176cf84..4afb2b1286 100644 --- a/packages/zowe-explorer/__tests__/__unit__/mvs/mvsNodeActions.unit.test.ts +++ b/packages/zowe-explorer/__tests__/__unit__/mvs/mvsNodeActions.unit.test.ts @@ -43,17 +43,14 @@ async function createGlobalMocks() { Object.defineProperty(vscode.window, "showInformationMessage", { value: newMocks.showInformationMessage, configurable: true }); Object.defineProperty(vscode.workspace, "openTextDocument", { value: newMocks.openTextDocument, configurable: true }); Object.defineProperty(vscode, "ProgressLocation", { value: jest.fn(), configurable: true }); - Object.defineProperty(vscode.window, "withProgress", { value: jest.fn(), configurable: true }); Object.defineProperty(vscode.window, "withProgress", { value: jest.fn().mockImplementation((progLocation, callback) => { const progress = { - report: (message) => { - return; - }, + report: jest.fn(), }; const token = { isCancellationRequested: false, - onCancellationRequested: undefined, + onCancellationRequested: jest.fn(), }; return callback(progress, token); }), @@ -186,22 +183,6 @@ describe("mvsNodeActions", () => { testTree.getTreeView.mockReturnValueOnce(createTreeView()); const fileUri = { fsPath: "/tmp/foo" }; globalMocks.showOpenDialog.mockReturnValueOnce([fileUri]); - Object.defineProperty(vscode.window, "withProgress", { - value: jest.fn().mockImplementation((progLocation, callback) => { - const progress = { - report: (message) => { - return; - }, - }; - const token = { - isCancellationRequested: true, - onCancellationRequested: undefined, - }; - return callback(progress, token); - }), - configurable: true, - }); - await dsActions.uploadDialog(node, testTree); expect(globalMocks.showOpenDialog).toBeCalled(); diff --git a/packages/zowe-explorer/__tests__/__unit__/shared/actions.unit.test.ts b/packages/zowe-explorer/__tests__/__unit__/shared/actions.unit.test.ts index 7ca4692be8..9d8ef68e8d 100644 --- a/packages/zowe-explorer/__tests__/__unit__/shared/actions.unit.test.ts +++ b/packages/zowe-explorer/__tests__/__unit__/shared/actions.unit.test.ts @@ -50,13 +50,11 @@ async function createGlobalMocks() { Object.defineProperty(vscode.window, "withProgress", { value: jest.fn().mockImplementation((progLocation, callback) => { const progress = { - report: (message) => { - return; - }, + report: jest.fn(), }; const token = { isCancellationRequested: false, - onCancellationRequested: undefined, + onCancellationRequested: jest.fn(), }; return callback(progress, token); }), diff --git a/packages/zowe-explorer/__tests__/__unit__/uss/actions.unit.test.ts b/packages/zowe-explorer/__tests__/__unit__/uss/actions.unit.test.ts index 4501c269f2..3a43dd80af 100644 --- a/packages/zowe-explorer/__tests__/__unit__/uss/actions.unit.test.ts +++ b/packages/zowe-explorer/__tests__/__unit__/uss/actions.unit.test.ts @@ -595,13 +595,11 @@ describe("USS Action Unit Tests - Functions uploadDialog & uploadFile", () => { Object.defineProperty(vscode.window, "withProgress", { value: jest.fn().mockImplementation((progLocation, callback) => { const progress = { - report: (message) => { - return; - }, + report: jest.fn(), }; const token = { isCancellationRequested: false, - onCancellationRequested: undefined, + onCancellationRequested: jest.fn(), }; return callback(progress, token); }), diff --git a/packages/zowe-explorer/src/Profiles.ts b/packages/zowe-explorer/src/Profiles.ts index 1b3058c31b..b1a1307ead 100644 --- a/packages/zowe-explorer/src/Profiles.ts +++ b/packages/zowe-explorer/src/Profiles.ts @@ -103,34 +103,34 @@ export class Profiles extends ProfilesCache { public async checkCurrentProfile(theProfile: zowe.imperative.IProfileLoaded): Promise { ZoweLogger.trace("Profiles.checkCurrentProfile called."); - let profileStatus: IProfileValidation; + let profileStatus: IProfileValidation = { name: theProfile.name, status: "unverified" }; let usingTokenAuth: boolean; try { usingTokenAuth = await ProfilesUtils.isUsingTokenAuth(theProfile.name); } catch (err) { ZoweLogger.error(err); ZoweExplorerExtender.showZoweConfigError(err.message); - return { name: theProfile.name, status: "unverified" }; - } - - if (usingTokenAuth && !theProfile.profile.tokenType) { - const error = new zowe.imperative.ImperativeError({ - msg: localize("checkCurrentProfile.tokenAuthError.msg", "Token auth error"), - additionalDetails: localize( - "checkCurrentProfile.tokenAuthError.additionalDetails", - "Profile was found using token auth, please log in to continue." - ), - errorCode: `${zowe.imperative.RestConstants.HTTP_STATUS_401}`, - }); - await errorHandling(error, theProfile.name, error.message); - profileStatus = { name: theProfile.name, status: "unverified" }; return profileStatus; } - if (!usingTokenAuth && (!theProfile.profile.user || !theProfile.profile.password)) { + if (usingTokenAuth && !theProfile.profile.tokenValue) { + ZoweLogger.debug(`Profile ${theProfile.name} is using token auth, prompting for missing credentials`); // The profile will need to be reactivated, so remove it from profilesForValidation this.profilesForValidation = this.profilesForValidation.filter( - (profile) => profile.status === "unverified" && profile.name !== theProfile.name + (profile) => !(profile.name === theProfile.name && profile.status !== "unverified") + ); + try { + await Profiles.getInstance().ssoLogin(null, theProfile.name); + theProfile = Profiles.getInstance().loadNamedProfile(theProfile.name); + } catch (error) { + await errorHandling(error, theProfile.name, error.message); + return profileStatus; + } + } else if (!usingTokenAuth && (!theProfile.profile.user || !theProfile.profile.password)) { + ZoweLogger.debug(`Profile ${theProfile.name} is using basic auth, prompting for missing credentials`); + // The profile will need to be reactivated, so remove it from profilesForValidation + this.profilesForValidation = this.profilesForValidation.filter( + (profile) => !(profile.name === theProfile.name && profile.status !== "unverified") ); let values: string[]; try { @@ -142,17 +142,12 @@ export class Profiles extends ProfilesCache { if (values) { theProfile.profile.user = values[0]; theProfile.profile.password = values[1]; - theProfile.profile.base64EncodedAuth = values[2]; - - // Validate profile - profileStatus = await this.getProfileSetting(theProfile); - } else { - profileStatus = { name: theProfile.name, status: "unverified" }; } - } else { - // Profile should have enough information to allow validation - profileStatus = await this.getProfileSetting(theProfile); } + + // Profile should have enough information to allow validation + profileStatus = await this.getProfileSetting(theProfile); + switch (profileStatus.status) { case "unverified": this.validProfile = ValidProfileEnum.UNVERIFIED; @@ -966,6 +961,7 @@ export class Profiles extends ProfilesCache { secure: mProfileInfo.isSecured(), userInputBoxOptions, passwordInputBoxOptions, + zeProfiles: this, }, ZoweExplorerApiRegister.getInstance() ); @@ -974,8 +970,7 @@ export class Profiles extends ProfilesCache { return; // See https://github.com/zowe/zowe-explorer-vscode/issues/1827 } - const returnValue: string[] = [promptInfo.profile.user, promptInfo.profile.password, promptInfo.profile.base64EncodedAuth]; - this.updateProfilesArrays(promptInfo); + const returnValue: string[] = [promptInfo.profile.user, promptInfo.profile.password]; return returnValue; } @@ -1163,7 +1158,7 @@ export class Profiles extends ProfilesCache { ZoweLogger.trace("Profiles.validateProfiles called."); let filteredProfile: IProfileValidation; let profileStatus; - const getSessStatus = await ZoweExplorerApiRegister.getInstance().getCommonApi(theProfile); + const getSessStatus = ZoweExplorerApiRegister.getInstance().getCommonApi(theProfile); // Check if the profile is already validated as active const desiredProfile = this.profilesForValidation.find((profile) => profile.name === theProfile.name && profile.status === "active"); @@ -1254,7 +1249,7 @@ export class Profiles extends ProfilesCache { const zeInstance = ZoweExplorerApiRegister.getInstance(); try { - loginTokenType = await zeInstance.getCommonApi(serviceProfile).getTokenTypeName(); + loginTokenType = zeInstance.getCommonApi(serviceProfile).getTokenTypeName(); } catch (error) { ZoweLogger.warn(error); Gui.showMessage(localize("ssoLogin.tokenType.error", "Error getting supported tokenType value for profile {0}", serviceProfile.name)); @@ -1269,7 +1264,6 @@ export class Profiles extends ProfilesCache { } if (loginOk) { Gui.showMessage(localize("ssoLogin.successful", "Login to authentication service was successful.")); - await Profiles.getInstance().refresh(zeInstance); } else { Gui.showMessage(this.profilesOpCancelled); } @@ -1508,14 +1502,12 @@ export class Profiles extends ProfilesCache { serviceProfile.profile != null && !serviceProfile.profile.tokenType?.startsWith(zowe.imperative.SessConstants.TOKEN_TYPE_APIML) ) { - await ZoweExplorerApiRegister.getInstance() - .getCommonApi(serviceProfile) - .logout(await node.getSession()); + await ZoweExplorerApiRegister.getInstance().getCommonApi(serviceProfile).logout(node.getSession()); + await Profiles.getInstance().updateCachedProfile(serviceProfile, node); } else { await ZoweVsCodeExtension.logoutWithBaseProfile(serviceProfile, ZoweExplorerApiRegister.getInstance(), this); } Gui.showMessage(localize("ssoLogout.successful", "Logout from authentication service was successful for {0}.", serviceProfile.name)); - await Profiles.getInstance().refresh(ZoweExplorerApiRegister.getInstance()); } catch (error) { const message = localize("ssoLogout.error", "Unable to log out with {0}. {1}", serviceProfile.name, error?.message); ZoweLogger.error(message); @@ -1566,14 +1558,7 @@ export class Profiles extends ProfilesCache { session.ISession.user = creds[0]; session.ISession.password = creds[1]; await ZoweExplorerApiRegister.getInstance().getCommonApi(serviceProfile).login(session); - const profIndex = this.allProfiles.findIndex((profile) => profile.name === serviceProfile.name); - this.allProfiles[profIndex] = { ...serviceProfile, profile: { ...serviceProfile, ...session } }; - if (node) { - node.setProfileToChoice({ - ...node.getProfile(), - profile: { ...node.getProfile().profile, ...session }, - }); - } + await Profiles.getInstance().updateCachedProfile(serviceProfile, node); return true; } diff --git a/packages/zowe-explorer/src/generators/icons/items/home.ts b/packages/zowe-explorer/src/generators/icons/items/home.ts index 0eb8a3aa27..5a0ec34f4c 100644 --- a/packages/zowe-explorer/src/generators/icons/items/home.ts +++ b/packages/zowe-explorer/src/generators/icons/items/home.ts @@ -11,13 +11,13 @@ import { IconHierarchyType, IconId, IIconItem } from "../index"; import { getIconPathInResources } from "../../../shared/utils"; -import { isHomeProfile } from "../../../shared/context"; +import { isHomeProfile, isSessionInactive } from "../../../shared/context"; const icon: IIconItem = { id: IconId.home, type: IconHierarchyType.base, path: getIconPathInResources("home.svg"), - check: (node) => isHomeProfile(node), + check: (node) => isHomeProfile(node) && !isSessionInactive(node), }; export default icon; From 1e601100e8821a903a36f7ab5fc15a577b3b25c9 Mon Sep 17 00:00:00 2001 From: Timothy Johnson Date: Fri, 6 Dec 2024 12:14:24 -0500 Subject: [PATCH 2/4] Fix API unit tests and lint errors Signed-off-by: Timothy Johnson --- .../vscode/ZoweVsCodeExtension.unit.test.ts | 2 +- .../src/vscode/ZoweVsCodeExtension.ts | 4 +- .../__unit__/Profiles.extended.unit.test.ts | 38 +++++++++---------- 3 files changed, 22 insertions(+), 22 deletions(-) diff --git a/packages/zowe-explorer-api/__tests__/__unit__/vscode/ZoweVsCodeExtension.unit.test.ts b/packages/zowe-explorer-api/__tests__/__unit__/vscode/ZoweVsCodeExtension.unit.test.ts index 1eea9019b1..ffc3b79e77 100644 --- a/packages/zowe-explorer-api/__tests__/__unit__/vscode/ZoweVsCodeExtension.unit.test.ts +++ b/packages/zowe-explorer-api/__tests__/__unit__/vscode/ZoweVsCodeExtension.unit.test.ts @@ -376,7 +376,7 @@ describe("ZoweVsCodeExtension", () => { expect(loginSpy).not.toHaveBeenCalled(); expect(testSpy).not.toHaveBeenCalled(); expect(testCache.updateBaseProfileFileLogin).toHaveBeenCalledWith(baseProfile, updProfile, false); - expect(testNode.setProfileToChoice).toHaveBeenCalled(); + expect(testCache.updateCachedProfile).toHaveBeenCalledWith(serviceProfile, testNode, testRegister); quickPickMock.mockRestore(); }); }); diff --git a/packages/zowe-explorer-api/src/vscode/ZoweVsCodeExtension.ts b/packages/zowe-explorer-api/src/vscode/ZoweVsCodeExtension.ts index 7e561f8b25..53397307e9 100644 --- a/packages/zowe-explorer-api/src/vscode/ZoweVsCodeExtension.ts +++ b/packages/zowe-explorer-api/src/vscode/ZoweVsCodeExtension.ts @@ -232,7 +232,7 @@ export class ZoweVsCodeExtension { await cache.updateBaseProfileFileLogin(profileToUpdate, updBaseProfile, !connOk); serviceProfile.profile = { ...serviceProfile.profile, ...updBaseProfile }; - await cache.updateCachedProfile(serviceProfile, node); + await cache.updateCachedProfile(serviceProfile, node, zeRegister); return true; } @@ -273,7 +273,7 @@ export class ZoweVsCodeExtension { const connOk = serviceProfile.profile.host === baseProfile.profile.host && serviceProfile.profile.port === baseProfile.profile.port; await cache.updateBaseProfileFileLogout(connOk ? baseProfile : serviceProfile); serviceProfile.profile = { ...serviceProfile.profile, tokenType: undefined, tokenValue: undefined }; - await cache.updateCachedProfile(serviceProfile); + await cache.updateCachedProfile(serviceProfile, undefined, zeRegister); } } diff --git a/packages/zowe-explorer/__tests__/__unit__/Profiles.extended.unit.test.ts b/packages/zowe-explorer/__tests__/__unit__/Profiles.extended.unit.test.ts index 4ed5772635..0f2cf6ac6e 100644 --- a/packages/zowe-explorer/__tests__/__unit__/Profiles.extended.unit.test.ts +++ b/packages/zowe-explorer/__tests__/__unit__/Profiles.extended.unit.test.ts @@ -297,7 +297,7 @@ describe("Profiles Unit Tests - Function createNewConnection for v1 Profiles", ( it("Tests that createNewConnection fails if zOSMF URL is missing", async () => { const globalMocks = createGlobalMocks(); - const blockMocks = createBlockMocks((globalMocks); + const blockMocks = createBlockMocks(globalMocks); jest.spyOn(globalMocks.mockProfileInstance, "getSchema").mockReturnValue(blockMocks.testSchemas); globalMocks.mockCreateInputBox.mockResolvedValue(undefined); @@ -309,7 +309,7 @@ describe("Profiles Unit Tests - Function createNewConnection for v1 Profiles", ( it("Tests that createNewConnection fails if user escapes create at username", async () => { const globalMocks = createGlobalMocks(); - const blockMocks = createBlockMocks((globalMocks); + const blockMocks = createBlockMocks(globalMocks); jest.spyOn(globalMocks.mockProfileInstance, "getSchema").mockReturnValue(blockMocks.testSchemas); jest.spyOn(globalMocks.mockProfileInstance, "urlInfo").mockReturnValue(globalMocks.mockUrlInfo); @@ -321,7 +321,7 @@ describe("Profiles Unit Tests - Function createNewConnection for v1 Profiles", ( it("Tests that createNewConnection fails if user escapes create at password", async () => { const globalMocks = createGlobalMocks(); - const blockMocks = createBlockMocks((globalMocks); + const blockMocks = createBlockMocks(globalMocks); jest.spyOn(globalMocks.mockProfileInstance, "getSchema").mockReturnValue(blockMocks.testSchemas); jest.spyOn(globalMocks.mockProfileInstance, "urlInfo").mockReturnValue(globalMocks.mockUrlInfo); @@ -334,7 +334,7 @@ describe("Profiles Unit Tests - Function createNewConnection for v1 Profiles", ( it("Tests that createNewConnection fails if user escapes create at rejectUnauthorized", async () => { const globalMocks = createGlobalMocks(); - const blockMocks = createBlockMocks((globalMocks); + const blockMocks = createBlockMocks(globalMocks); jest.spyOn(globalMocks.mockProfileInstance, "getSchema").mockReturnValue(blockMocks.testSchemas); jest.spyOn(globalMocks.mockProfileInstance, "urlInfo").mockReturnValue(globalMocks.mockUrlInfo); @@ -348,7 +348,7 @@ describe("Profiles Unit Tests - Function createNewConnection for v1 Profiles", ( it("Tests that createNewConnection fails if profileName is a duplicate", async () => { const globalMocks = createGlobalMocks(); - const blockMocks = createBlockMocks((globalMocks); + const blockMocks = createBlockMocks(globalMocks); jest.spyOn(globalMocks.mockProfileInstance, "getSchema").mockReturnValue(blockMocks.testSchemas); jest.spyOn(globalMocks.mockProfileInstance, "urlInfo").mockReturnValue(globalMocks.mockUrlInfo); @@ -362,7 +362,7 @@ describe("Profiles Unit Tests - Function createNewConnection for v1 Profiles", ( it("Tests that createNewConnection creates a new profile", async () => { const globalMocks = createGlobalMocks(); - const blockMocks = createBlockMocks((globalMocks); + const blockMocks = createBlockMocks(globalMocks); jest.spyOn(utils.ProfilesUtils, "getCredentialManagerOverride").mockReturnValueOnce("@zowe/cli"); @@ -378,7 +378,7 @@ describe("Profiles Unit Tests - Function createNewConnection for v1 Profiles", ( it("Tests that createNewConnection throws an exception and shows a config error", async () => { const globalMocks = createGlobalMocks(); - const blockMocks = createBlockMocks((globalMocks); + const blockMocks = createBlockMocks(globalMocks); const testError = new Error("saveProfile error"); const mockSaveProfile = jest.spyOn(ProfilesCache.prototype as any, "saveProfile").mockImplementationOnce(async (_values, _name, _type) => { @@ -402,7 +402,7 @@ describe("Profiles Unit Tests - Function createNewConnection for v1 Profiles", ( it("Tests that createNewConnection returns 'fake' if the port is undefined and portInfo() returns correct port", async () => { const globalMocks = createGlobalMocks(); - const blockMocks = createBlockMocks((globalMocks); + const blockMocks = createBlockMocks(globalMocks); jest.spyOn(utils.ProfilesUtils, "getCredentialManagerOverride").mockReturnValueOnce("@zowe/cli"); const customURLInfo = { valid: true, @@ -426,7 +426,7 @@ describe("Profiles Unit Tests - Function createNewConnection for v1 Profiles", ( it("Tests that createNewConnection returns undefined if the port is undefined and portInfo() returns NaN", async () => { const globalMocks = createGlobalMocks(); - const blockMocks = createBlockMocks((globalMocks); + const blockMocks = createBlockMocks(globalMocks); const customURLInfo = { valid: true, protocol: "https", @@ -449,7 +449,7 @@ describe("Profiles Unit Tests - Function createNewConnection for v1 Profiles", ( it("Tests that createNewConnection enters default case when encoding is present in schema and value is the number 0", async () => { const globalMocks = createGlobalMocks(); - const blockMocks = createBlockMocks((globalMocks); + const blockMocks = createBlockMocks(globalMocks); jest.spyOn(utils.ProfilesUtils, "getCredentialManagerOverride").mockReturnValueOnce("@zowe/cli"); jest.spyOn(globalMocks.mockProfileInstance, "getSchema").mockReturnValueOnce(blockMocks.testSchemas); @@ -473,7 +473,7 @@ describe("Profiles Unit Tests - Function createNewConnection for v1 Profiles", ( it("Tests that createNewConnection enters default case when encoding is present in schema and value is NaN", async () => { const globalMocks = createGlobalMocks(); - const blockMocks = createBlockMocks((globalMocks); + const blockMocks = createBlockMocks(globalMocks); jest.spyOn(utils.ProfilesUtils, "getCredentialManagerOverride").mockReturnValueOnce("@zowe/cli"); jest.spyOn(globalMocks.mockProfileInstance, "getSchema").mockReturnValueOnce(blockMocks.testSchemas); @@ -498,7 +498,7 @@ describe("Profiles Unit Tests - Function createNewConnection for v1 Profiles", ( it("Tests that createNewConnection enters default case when boolean is present in schema and returns undefined", async () => { const globalMocks = createGlobalMocks(); - const blockMocks = createBlockMocks((globalMocks); + const blockMocks = createBlockMocks(globalMocks); jest.spyOn(globalMocks.mockProfileInstance, "getSchema").mockReturnValueOnce(blockMocks.testSchemas); jest.spyOn(globalMocks.mockProfileInstance, "urlInfo").mockReturnValueOnce(globalMocks.mockUrlInfo); @@ -526,7 +526,7 @@ describe("Profiles Unit Tests - Function createNewConnection for v1 Profiles", ( it("Tests that createNewConnection enters default case when string is present in schema and returns 'fake'", async () => { const globalMocks = createGlobalMocks(); - const blockMocks = createBlockMocks((globalMocks); + const blockMocks = createBlockMocks(globalMocks); jest.spyOn(utils.ProfilesUtils, "getCredentialManagerOverride").mockReturnValueOnce("@zowe/cli"); jest.spyOn(globalMocks.mockProfileInstance, "getSchema").mockReturnValueOnce(blockMocks.testSchemas); @@ -571,7 +571,7 @@ describe("Profiles Unit Tests - Function createZoweSession", () => { } it("Tests that createZoweSession presents correct message when escaping selection of quickpick", async () => { const globalMocks = createGlobalMocks(); - const blockMocks = createBlockMocks((globalMocks); + const blockMocks = createBlockMocks(globalMocks); const spy = jest.spyOn(Gui, "createQuickPick"); const spyDebug = jest.spyOn(ZoweLogger, "debug"); jest.spyOn(Gui, "resolveQuickPick").mockResolvedValueOnce(undefined); @@ -746,7 +746,7 @@ describe("Profiles Unit Tests - Function createZoweSchema", () => { } it("Tests that createZoweSchema presents correct message when escaping selection of config location prompt", async () => { const globalMocks = createGlobalMocks(); - const blockMocks = createBlockMocks((globalMocks); + const blockMocks = createBlockMocks(globalMocks); const spy = jest.spyOn(Gui, "showQuickPick"); spy.mockResolvedValueOnce(undefined); @@ -757,7 +757,7 @@ describe("Profiles Unit Tests - Function createZoweSchema", () => { }); it("Tests that createZoweSchema will open correct config file when cancelling creation in location with existing config file", async () => { const globalMocks = createGlobalMocks(); - const blockMocks = createBlockMocks((globalMocks); + const blockMocks = createBlockMocks(globalMocks); const spyQuickPick = jest.spyOn(Gui, "showQuickPick"); globalMocks.mockShowQuickPick.mockResolvedValueOnce("Global: in the Zowe home directory"); @@ -779,7 +779,7 @@ describe("Profiles Unit Tests - Function createZoweSchema", () => { }); it("Test that createZoweSchema will open config on error if error deals with parsing file", async () => { const globalMocks = createGlobalMocks(); - const blockMocks = createBlockMocks((globalMocks); + const blockMocks = createBlockMocks(globalMocks); const spyQuickPick = jest.spyOn(Gui, "showQuickPick"); globalMocks.mockShowQuickPick.mockResolvedValueOnce("Global: in the Zowe home directory"); @@ -797,7 +797,7 @@ describe("Profiles Unit Tests - Function createZoweSchema", () => { }); it("Test that createZoweSchema will auto create global if VSC not in project and config doesn't exist", async () => { const globalMocks = createGlobalMocks(); - const blockMocks = createBlockMocks((globalMocks); + const blockMocks = createBlockMocks(globalMocks); Object.defineProperty(vscode.workspace, "workspaceFolders", { value: undefined, configurable: true, @@ -825,7 +825,7 @@ describe("Profiles Unit Tests - Function createZoweSchema", () => { it("Tests that createZoweSchema will return the config file path", async () => { const globalMocks = createGlobalMocks(); - const blockMocks = createBlockMocks((globalMocks); + const blockMocks = createBlockMocks(globalMocks); Object.defineProperty(globals, "ISTHEIA", { value: true, configurable: true }); Object.defineProperty(vscode.workspace, "workspaceFolders", { From 16a26a5fc65d0e7cefd63666764f63ca3c5f7c97 Mon Sep 17 00:00:00 2001 From: Timothy Johnson Date: Thu, 26 Dec 2024 14:52:21 -0500 Subject: [PATCH 3/4] Revert deprecation of updateProfilesArrays method Signed-off-by: Timothy Johnson --- packages/zowe-explorer-api/CHANGELOG.md | 1 - .../profiles/ProfilesCache.unit.test.ts | 29 ------------------- .../vscode/ZoweVsCodeExtension.unit.test.ts | 8 ++--- .../src/profiles/ProfilesCache.ts | 22 ++------------ .../src/vscode/ZoweVsCodeExtension.ts | 6 ++-- packages/zowe-explorer/src/Profiles.ts | 8 +++-- 6 files changed, 12 insertions(+), 62 deletions(-) diff --git a/packages/zowe-explorer-api/CHANGELOG.md b/packages/zowe-explorer-api/CHANGELOG.md index 4157d5312d..41812f88a0 100644 --- a/packages/zowe-explorer-api/CHANGELOG.md +++ b/packages/zowe-explorer-api/CHANGELOG.md @@ -9,7 +9,6 @@ All notable changes to the "zowe-explorer-api" extension will be documented in t ### Bug fixes - Fixed an issue where the `responseTimeout` profile property was ignored for z/OSMF MVS and USS API calls. [#3225](https://github.com/zowe/zowe-explorer-vscode/issues/3225) -- Deprecated the method `ProfilesCache.updateProfilesArrays`. Use `ProfilesCache.updateCachedProfile` instead, which handles updating credentials cached in memory when `autoStore` is false. [#3120](https://github.com/zowe/zowe-explorer-vscode/issues/3120) - Updated the `@zowe/cli` dependency to v7.29.7 for technical currency. [#3342](https://github.com/zowe/zowe-explorer-vscode/pull/3342) ## `2.18.0` diff --git a/packages/zowe-explorer-api/__tests__/__unit__/profiles/ProfilesCache.unit.test.ts b/packages/zowe-explorer-api/__tests__/__unit__/profiles/ProfilesCache.unit.test.ts index b9023dcb17..d1155b58e9 100644 --- a/packages/zowe-explorer-api/__tests__/__unit__/profiles/ProfilesCache.unit.test.ts +++ b/packages/zowe-explorer-api/__tests__/__unit__/profiles/ProfilesCache.unit.test.ts @@ -230,35 +230,6 @@ describe("ProfilesCache", () => { expect((profCache as any).defaultProfileByType.get("zosmf").profile).toMatchObject(lpar2Profile.profile); }); - it("updateCachedProfile should refresh all profiles when autoStore is true", async () => { - const profCache = new ProfilesCache(fakeLogger as unknown as zowe.imperative.Logger); - jest.spyOn(profCache, "getProfileInfo").mockResolvedValueOnce({ - getTeamConfig: jest.fn().mockReturnValue({ properties: { autoStore: true } }), - } as unknown as zowe.imperative.ProfileInfo); - const refreshSpy = jest.spyOn(profCache, "refresh").mockImplementation(); - await profCache.updateCachedProfile({ - ...lpar1Profile, - profile: lpar2Profile.profile, - } as zowe.imperative.IProfileLoaded); - expect(refreshSpy).toHaveBeenCalledTimes(1); - }); - - it("updateCachedProfile should update cached profile when autoStore is false", async () => { - const profCache = new ProfilesCache(fakeLogger as unknown as zowe.imperative.Logger); - profCache.allProfiles = [lpar1Profile as zowe.imperative.IProfileLoaded]; - (profCache as any).defaultProfileByType = new Map([["zosmf", { ...profCache.allProfiles[0] }]]); - expect(profCache.allProfiles[0].profile).toMatchObject(lpar1Profile.profile); - jest.spyOn(profCache, "getProfileInfo").mockResolvedValueOnce({ - getTeamConfig: jest.fn().mockReturnValue({ properties: { autoStore: false } }), - } as unknown as zowe.imperative.ProfileInfo); - await profCache.updateCachedProfile({ - ...lpar1Profile, - profile: lpar2Profile.profile, - } as zowe.imperative.IProfileLoaded); - expect(profCache.allProfiles[0].profile).toMatchObject(lpar2Profile.profile); - expect((profCache as any).defaultProfileByType.get("zosmf").profile).toMatchObject(lpar2Profile.profile); - }); - it("getDefaultProfile should find default profile given type", () => { const profCache = new ProfilesCache(fakeLogger as unknown as zowe.imperative.Logger); (profCache as any).defaultProfileByType = new Map([["zosmf", lpar1Profile]]); diff --git a/packages/zowe-explorer-api/__tests__/__unit__/vscode/ZoweVsCodeExtension.unit.test.ts b/packages/zowe-explorer-api/__tests__/__unit__/vscode/ZoweVsCodeExtension.unit.test.ts index ffc3b79e77..4889a4927f 100644 --- a/packages/zowe-explorer-api/__tests__/__unit__/vscode/ZoweVsCodeExtension.unit.test.ts +++ b/packages/zowe-explorer-api/__tests__/__unit__/vscode/ZoweVsCodeExtension.unit.test.ts @@ -219,7 +219,7 @@ describe("ZoweVsCodeExtension", () => { mergeArgsForProfile: jest.fn().mockReturnValue({ knownArgs: [] }), }), refresh: jest.fn(), - updateCachedProfile: jest.fn(), + updateProfilesArrays: jest.fn(), }; beforeEach(() => { @@ -376,7 +376,7 @@ describe("ZoweVsCodeExtension", () => { expect(loginSpy).not.toHaveBeenCalled(); expect(testSpy).not.toHaveBeenCalled(); expect(testCache.updateBaseProfileFileLogin).toHaveBeenCalledWith(baseProfile, updProfile, false); - expect(testCache.updateCachedProfile).toHaveBeenCalledWith(serviceProfile, testNode, testRegister); + expect(testCache.updateProfilesArrays).toHaveBeenCalledWith(serviceProfile, testNode); quickPickMock.mockRestore(); }); }); @@ -461,7 +461,6 @@ describe("ZoweVsCodeExtension", () => { updateProperty: mockUpdateProperty, }), refresh: jest.fn(), - updateCachedProfile: jest.fn(), }); const showInputBoxSpy = jest.spyOn(Gui, "showInputBox").mockResolvedValueOnce("fakeUser").mockResolvedValueOnce("fakePassword"); const saveCredentialsSpy = jest.spyOn(ZoweVsCodeExtension as any, "saveCredentials"); @@ -487,7 +486,6 @@ describe("ZoweVsCodeExtension", () => { updateProperty: mockUpdateProperty, }), refresh: jest.fn(), - updateCachedProfile: jest.fn(), }); const showInputBoxSpy = jest.spyOn(Gui, "showInputBox").mockResolvedValueOnce("fakeUser").mockResolvedValueOnce("fakePassword"); const saveCredentialsSpy = jest.spyOn(ZoweVsCodeExtension as any, "saveCredentials"); @@ -516,7 +514,6 @@ describe("ZoweVsCodeExtension", () => { updateProperty: mockUpdateProperty, }), refresh: jest.fn(), - updateCachedProfile: jest.fn(), }); const showInputBoxSpy = jest.spyOn(Gui, "showInputBox").mockResolvedValueOnce("fakeUser").mockResolvedValueOnce("fakePassword"); jest.spyOn(Gui, "showMessage").mockResolvedValueOnce("yes"); @@ -543,7 +540,6 @@ describe("ZoweVsCodeExtension", () => { updateProperty: mockUpdateProperty, }), refresh: jest.fn(), - updateCachedProfile: jest.fn(), }); const showInputBoxSpy = jest.spyOn(Gui, "showInputBox").mockResolvedValueOnce("fakeUser").mockResolvedValueOnce("fakePassword"); jest.spyOn(Gui, "showMessage").mockResolvedValueOnce(undefined); diff --git a/packages/zowe-explorer-api/src/profiles/ProfilesCache.ts b/packages/zowe-explorer-api/src/profiles/ProfilesCache.ts index 90ba3c9260..4ea919cc98 100644 --- a/packages/zowe-explorer-api/src/profiles/ProfilesCache.ts +++ b/packages/zowe-explorer-api/src/profiles/ProfilesCache.ts @@ -128,11 +128,11 @@ export class ProfilesCache { /** * Updates profile in allProfiles array and if default updates defaultProfileByType - * @deprecated Use `updateCachedProfile` instead * @param {string} profileLoaded + * @param {IZoweNodeType} profileNode * @returns {void} */ - public updateProfilesArrays(profileLoaded: zowe.imperative.IProfileLoaded): void { + public updateProfilesArrays(profileLoaded: zowe.imperative.IProfileLoaded, profileNode?: IZoweNodeType): void { // update allProfiles array const promptedTypeIndex = this.allProfiles.findIndex( (profile) => profile?.type === profileLoaded?.type && profile?.name === profileLoaded?.name @@ -143,24 +143,6 @@ export class ProfilesCache { if (defaultProf?.name === profileLoaded?.name) { this.defaultProfileByType.set(profileLoaded?.type, profileLoaded); } - } - - public async updateCachedProfile( - profileLoaded: zowe.imperative.IProfileLoaded, - profileNode?: IZoweNodeType, - zeRegister?: ZoweExplorerApi.IApiRegisterClient - ): Promise { - if ((await this.getProfileInfo()).getTeamConfig().properties.autoStore) { - await this.refresh(zeRegister); - } else { - // Note: When autoStore is disabled, nested profiles within this service profile may not have their credentials updated. - const profIndex = this.allProfiles.findIndex((profile) => profile.type === profileLoaded.type && profile.name === profileLoaded.name); - this.allProfiles[profIndex].profile = profileLoaded.profile; - const defaultProf = this.defaultProfileByType.get(profileLoaded.type); - if (defaultProf != null && defaultProf.name === profileLoaded.name) { - this.defaultProfileByType.set(profileLoaded.type, profileLoaded); - } - } profileNode?.setProfileToChoice(profileLoaded); } diff --git a/packages/zowe-explorer-api/src/vscode/ZoweVsCodeExtension.ts b/packages/zowe-explorer-api/src/vscode/ZoweVsCodeExtension.ts index 53397307e9..dc50d282a3 100644 --- a/packages/zowe-explorer-api/src/vscode/ZoweVsCodeExtension.ts +++ b/packages/zowe-explorer-api/src/vscode/ZoweVsCodeExtension.ts @@ -143,7 +143,7 @@ export class ZoweVsCodeExtension { await profInfo.updateProperty({ ...upd, property: "user", value: creds[0], setSecure }); await profInfo.updateProperty({ ...upd, property: "password", value: creds[1], setSecure }); } - await cache.updateCachedProfile(loadProfile, undefined, apiRegister); + await cache.refresh(apiRegister); return loadProfile; } @@ -232,7 +232,7 @@ export class ZoweVsCodeExtension { await cache.updateBaseProfileFileLogin(profileToUpdate, updBaseProfile, !connOk); serviceProfile.profile = { ...serviceProfile.profile, ...updBaseProfile }; - await cache.updateCachedProfile(serviceProfile, node, zeRegister); + cache.updateProfilesArrays(serviceProfile, node); return true; } @@ -273,7 +273,7 @@ export class ZoweVsCodeExtension { const connOk = serviceProfile.profile.host === baseProfile.profile.host && serviceProfile.profile.port === baseProfile.profile.port; await cache.updateBaseProfileFileLogout(connOk ? baseProfile : serviceProfile); serviceProfile.profile = { ...serviceProfile.profile, tokenType: undefined, tokenValue: undefined }; - await cache.updateCachedProfile(serviceProfile, undefined, zeRegister); + cache.updateProfilesArrays(serviceProfile); } } diff --git a/packages/zowe-explorer/src/Profiles.ts b/packages/zowe-explorer/src/Profiles.ts index b1a1307ead..8a1f0725ed 100644 --- a/packages/zowe-explorer/src/Profiles.ts +++ b/packages/zowe-explorer/src/Profiles.ts @@ -970,7 +970,8 @@ export class Profiles extends ProfilesCache { return; // See https://github.com/zowe/zowe-explorer-vscode/issues/1827 } - const returnValue: string[] = [promptInfo.profile.user, promptInfo.profile.password]; + const returnValue: string[] = [promptInfo.profile.user, promptInfo.profile.password, promptInfo.profile.base64EncodedAuth]; + this.updateProfilesArrays(promptInfo); return returnValue; } @@ -1264,6 +1265,7 @@ export class Profiles extends ProfilesCache { } if (loginOk) { Gui.showMessage(localize("ssoLogin.successful", "Login to authentication service was successful.")); + await Profiles.getInstance().refresh(zeInstance); } else { Gui.showMessage(this.profilesOpCancelled); } @@ -1503,11 +1505,11 @@ export class Profiles extends ProfilesCache { !serviceProfile.profile.tokenType?.startsWith(zowe.imperative.SessConstants.TOKEN_TYPE_APIML) ) { await ZoweExplorerApiRegister.getInstance().getCommonApi(serviceProfile).logout(node.getSession()); - await Profiles.getInstance().updateCachedProfile(serviceProfile, node); } else { await ZoweVsCodeExtension.logoutWithBaseProfile(serviceProfile, ZoweExplorerApiRegister.getInstance(), this); } Gui.showMessage(localize("ssoLogout.successful", "Logout from authentication service was successful for {0}.", serviceProfile.name)); + await Profiles.getInstance().refresh(ZoweExplorerApiRegister.getInstance()); } catch (error) { const message = localize("ssoLogout.error", "Unable to log out with {0}. {1}", serviceProfile.name, error?.message); ZoweLogger.error(message); @@ -1558,7 +1560,7 @@ export class Profiles extends ProfilesCache { session.ISession.user = creds[0]; session.ISession.password = creds[1]; await ZoweExplorerApiRegister.getInstance().getCommonApi(serviceProfile).login(session); - await Profiles.getInstance().updateCachedProfile(serviceProfile, node); + Profiles.getInstance().updateProfilesArrays(serviceProfile, node); return true; } From 21eaae3d9d1a954a260eb2f487eebc1ed762c907 Mon Sep 17 00:00:00 2001 From: Timothy Johnson Date: Thu, 26 Dec 2024 15:00:48 -0500 Subject: [PATCH 4/4] Update l10n and comment formatting Signed-off-by: Timothy Johnson --- packages/zowe-explorer-api/src/profiles/ProfilesCache.ts | 2 ++ packages/zowe-explorer/i18n/sample/src/Profiles.i18n.json | 2 -- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/zowe-explorer-api/src/profiles/ProfilesCache.ts b/packages/zowe-explorer-api/src/profiles/ProfilesCache.ts index 4ea919cc98..a712592132 100644 --- a/packages/zowe-explorer-api/src/profiles/ProfilesCache.ts +++ b/packages/zowe-explorer-api/src/profiles/ProfilesCache.ts @@ -128,8 +128,10 @@ export class ProfilesCache { /** * Updates profile in allProfiles array and if default updates defaultProfileByType + * * @param {string} profileLoaded * @param {IZoweNodeType} profileNode + * * @returns {void} */ public updateProfilesArrays(profileLoaded: zowe.imperative.IProfileLoaded, profileNode?: IZoweNodeType): void { diff --git a/packages/zowe-explorer/i18n/sample/src/Profiles.i18n.json b/packages/zowe-explorer/i18n/sample/src/Profiles.i18n.json index b48b0f2a1b..057a65ee48 100644 --- a/packages/zowe-explorer/i18n/sample/src/Profiles.i18n.json +++ b/packages/zowe-explorer/i18n/sample/src/Profiles.i18n.json @@ -1,8 +1,6 @@ { "profiles.operation.cancelled": "Operation Cancelled", "profiles.manualEditMsg": "The Team configuration file has been opened in the editor. Editing or removal of profiles will need to be done manually.", - "checkCurrentProfile.tokenAuthError.msg": "Token auth error", - "checkCurrentProfile.tokenAuthError.additionalDetails": "Profile was found using token auth, please log in to continue.", "profiles.createNewConnection": "$(plus) Create a new connection to z/OS", "profiles.createTeamConfig": "$(plus) Create a new Team Configuration file", "profiles.editConfig": "$(pencil) Edit Team Configuration file",