Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add option for hiding profile from all trees #2566

Merged
merged 11 commits into from
Nov 16, 2023
2 changes: 2 additions & 0 deletions packages/zowe-explorer-api/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ All notable changes to the "zowe-explorer-api" extension will be documented in t

### New features and enhancements

- Added new optional boolean parameter `hideFromAllTrees` to `IZoweTree.deleteSession` for specifying whether to hide from all trees or current tree. [#2567](https://github.com/zowe/vscode-extension-for-zowe/issues/2567)

### Bug fixes

## `2.12.1`
Expand Down
8 changes: 7 additions & 1 deletion packages/zowe-explorer-api/src/tree/IZoweTree.ts
Original file line number Diff line number Diff line change
Expand Up @@ -206,8 +206,9 @@ export interface IZoweTree<T> extends vscode.TreeDataProvider<T> {
/**
* Deletes a root node from the tree.
* @param node: A root node representing a session
* @param hideFromAllTrees: <optional> whether to hide from all trees or just the single tree
*/
deleteSession(node: IZoweTreeNode);
deleteSession(node: IZoweTreeNode, hideFromAllTrees?: boolean);
/**
* Lets the user open a dataset by filtering the currently-loaded list
*/
Expand Down Expand Up @@ -268,6 +269,11 @@ export interface IZoweTree<T> extends vscode.TreeDataProvider<T> {
* @param {string} name the member to remove
*/
removeFileHistory?(name: string);
/**
* Removes session from the session array
* @param {string} name the sessions to remove
*/
removeSession?(name: string): void;
/**
* Returns a new dataset filter string, from an old filter and a new string
*
Expand Down
1 change: 1 addition & 0 deletions packages/zowe-explorer/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ All notable changes to the "vscode-extension-for-zowe" extension will be documen

### New features and enhancements

- Added support for hiding a Zowe profile across all trees [#2567](https://github.com/zowe/vscode-extension-for-zowe/issues/2567)
- Added Display confirmation dialog when submitting local JCL. [#2061](https://github.com/zowe/vscode-extension-for-zowe/issues/2061)

### Bug fixes
Expand Down
43 changes: 42 additions & 1 deletion packages/zowe-explorer/__mocks__/mockCreators/shared.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,11 @@ import { ZoweTreeProvider } from "../../src/abstract/ZoweTreeProvider";
import { ZoweDatasetNode } from "../../src/dataset/ZoweDatasetNode";
import { ZoweUSSNode } from "../../src/uss/ZoweUSSNode";
import * as vscode from "vscode";
import { ValidProfileEnum } from "@zowe/zowe-explorer-api";
import { ValidProfileEnum, IZoweTreeNode } from "@zowe/zowe-explorer-api";
import { FilterDescriptor } from "../../src/utils/ProfilesUtils";
import { imperative, ZosmfSession } from "@zowe/cli";
import { SettingsConfig } from "../../src/utils/SettingsConfig";
import * as globals from "../../src/globals";

export function createPersistentConfig() {
return {
Expand Down Expand Up @@ -548,3 +549,43 @@ export function createOutputChannel() {
replace: jest.fn(),
} as vscode.OutputChannel;
}

export function createMockNode(name: string, context: string): IZoweTreeNode {
return {
dirty: false,
getLabel: jest.fn(() => name),
getChildren: jest.fn(),
getParent: jest.fn(),
getProfile: jest.fn(),
getProfileName: jest.fn(),
getSession: jest.fn(),
getSessionNode: jest.fn(),
setProfileToChoice: jest.fn(),
setSessionToChoice: jest.fn(),
label: name,
contextValue: context,
};
}

export function createTreeProviders() {
return {
ds: {
mSessionNodes: [createMockNode("zosmf", globals.DS_SESSION_CONTEXT), createMockNode("zosmf2", globals.DS_SESSION_CONTEXT)],
deleteSession: jest.fn(),
removeSession: jest.fn(),
refresh: jest.fn(),
} as any,
uss: {
mSessionNodes: [createMockNode("zosmf", globals.USS_SESSION_CONTEXT), createMockNode("zosmf2", globals.USS_SESSION_CONTEXT)],
deleteSession: jest.fn(),
removeSession: jest.fn(),
refresh: jest.fn(),
} as any,
job: {
mSessionNodes: [createMockNode("zosmf", globals.JOBS_SESSION_CONTEXT), createMockNode("zosmf2", globals.JOBS_SESSION_CONTEXT)],
removeSession: jest.fn(),
deleteSession: jest.fn(),
refresh: jest.fn(),
} as any,
};
}
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,8 @@ export async function hideProfileInUss() {
const manageProfile = driverChrome.wait(until.elementLocated(By.xpath(UssLocators.emptyInputBoxXpath)), WAITTIME);
manageProfile.sendKeys("Hide Profile");
manageProfile.sendKeys(Key.ENTER);
manageProfile.sendKeys("No");
manageProfile.sendKeys(Key.ENTER);
}

export async function hideProfileInJobs() {
Expand All @@ -153,6 +155,8 @@ export async function hideProfileInJobs() {
const manageProfile = driverChrome.wait(until.elementLocated(By.xpath(JobsLocators.emptyInputBoxXpath)), WAITTIME);
manageProfile.sendKeys("Hide Profile");
manageProfile.sendKeys(Key.ENTER);
manageProfile.sendKeys("No");
manageProfile.sendKeys(Key.ENTER);
}

export async function verifyProfileIsHideInUss() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ import {
createValidIProfile,
createInstanceOfProfileInfo,
createGetConfigMock,
createTreeProviders,
createMockNode,
} from "../../../__mocks__/mockCreators/shared";
import { createDatasetSessionNode, createDatasetTree, createDatasetFavoritesNode } from "../../../__mocks__/mockCreators/datasets";
import { bindMvsApi, createMvsApi } from "../../../__mocks__/mockCreators/api";
Expand All @@ -49,6 +51,7 @@ import * as dsUtils from "../../../src/dataset/utils";
import { SettingsConfig } from "../../../src/utils/SettingsConfig";
import * as sharedActions from "../../../src/shared/actions";
import { ZoweLogger } from "../../../src/utils/LoggerUtils";
import { TreeProviders } from "../../../src/shared/TreeProviders";

jest.mock("fs");
jest.mock("util");
Expand All @@ -63,6 +66,7 @@ function createGlobalMocks() {
mockShowWarningMessage: jest.fn(),
mockProfileInfo: createInstanceOfProfileInfo(),
mockProfilesCache: new ProfilesCache(zowe.imperative.Logger.getAppLogger()),
mockTreeProviders: createTreeProviders(),
};

globalMocks.mockProfileInstance = createInstanceOfProfile(globalMocks.testProfileLoaded);
Expand Down Expand Up @@ -1327,17 +1331,37 @@ describe("Dataset Tree Unit Tests - Function deleteSession", () => {
};
}

it("Checking common run of function", async () => {
createGlobalMocks();
it("Checking common run of function", () => {
const globalMocks = createGlobalMocks();
const blockMocks = createBlockMocks();

jest.spyOn(TreeProviders, "providers", "get").mockReturnValue(globalMocks.mockTreeProviders);
mocked(vscode.window.createTreeView).mockReturnValueOnce(blockMocks.treeView);
const testTree = new DatasetTree();
testTree.mSessionNodes.push(blockMocks.datasetSessionNode);
testTree.mSessionNodes = globalMocks.mockTreeProviders.ds.mSessionNodes;
testTree.mSessionNodes.push(createMockNode("Favorites", globals.DS_SESSION_CONTEXT));

testTree.deleteSession(testTree.mSessionNodes[0]);
testTree.deleteSession(testTree.mSessionNodes[1]);

expect(testTree.mSessionNodes.map((node) => node.label)).toEqual(["Favorites"]);
expect(globalMocks.mockTreeProviders.ds.mSessionNodes.map((node) => node.label)).toEqual(["Favorites"]);
});

it("Checking case profile needs to be hidden for all trees", () => {
const globalMocks = createGlobalMocks();
const blockMocks = createBlockMocks();

jest.spyOn(TreeProviders, "providers", "get").mockReturnValue(globalMocks.mockTreeProviders);
mocked(vscode.window.createTreeView).mockReturnValueOnce(blockMocks.treeView);
const testTree = new DatasetTree();
testTree.mSessionNodes = globalMocks.mockTreeProviders.ds.mSessionNodes;

testTree.deleteSession(testTree.mSessionNodes[0], true);
testTree.deleteSession(testTree.mSessionNodes[1], true);

expect(globalMocks.mockTreeProviders.ds.mSessionNodes.map((node) => node.label)).toEqual([]);
expect(globalMocks.mockTreeProviders.uss.mSessionNodes.map((node) => node.label)).toEqual([]);
expect(globalMocks.mockTreeProviders.job.mSessionNodes.map((node) => node.label)).toEqual([]);
});
});
describe("Dataset Tree Unit Tests - Function flipState", () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ describe("Test src/dataset/extension", () => {
name: "zowe.ds.removeSession",
mock: [
{ spy: jest.spyOn(contextuals, "isDsSession"), arg: [test.value], ret: true },
{ spy: jest.spyOn(dsProvider, "deleteSession"), arg: [test.value] },
{ spy: jest.spyOn(dsProvider, "deleteSession"), arg: [test.value, undefined] },
],
},
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -546,10 +546,12 @@ describe("Extension Unit Tests", () => {
getProfile: jest.fn(),
getParent: jest.fn().mockReturnValue({ getLabel: jest.fn() }),
label: "TestNode",
getLabel: jest.fn(() => "TestNode"),
};

const deleteSessionSpy = jest.spyOn(providerObject.prototype, "deleteSession");
const commandFunction = allCommands.find((cmd) => command === cmd.cmd);
await (commandFunction as any).fun(testNode, [testNode]);
await (commandFunction as any).fun(testNode, [testNode], true);
expect(deleteSessionSpy).toHaveBeenCalled();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,12 @@ import {
createInstanceOfProfile,
createISessionWithoutCredentials,
createInstanceOfProfileInfo,
createTreeProviders,
} from "../../../__mocks__/mockCreators/shared";
import * as contextually from "../../../src/shared/context";
import { ZoweLogger } from "../../../src/utils/LoggerUtils";
import { bindJesApi, createJesApi } from "../../../__mocks__/mockCreators/api";
import { TreeProviders } from "../../../src/shared/TreeProviders";

async function createGlobalMocks() {
const globalMocks = {
Expand Down Expand Up @@ -86,6 +88,7 @@ async function createGlobalMocks() {
}),
mockProfileInfo: createInstanceOfProfileInfo(),
mockProfilesCache: new ProfilesCache(zowe.imperative.Logger.getAppLogger()),
mockTreeProviders: createTreeProviders(),
};

Object.defineProperty(globals, "LOG", { value: jest.fn(), configurable: true });
Expand Down Expand Up @@ -237,10 +240,15 @@ describe("ZoweJobNode unit tests - Function addSession", () => {
describe("ZoweJobNode unit tests - Function deleteSession", () => {
it("Tests that deleteSession removes the session from the tree", async () => {
const globalMocks = await createGlobalMocks();

await globalMocks.testJobsProvider.deleteSession(globalMocks.testJobsProvider.mSessionNodes[1]);

expect(globalMocks.testJobsProvider.mSessionNodes.length).toBe(1);
jest.spyOn(TreeProviders, "providers", "get").mockReturnValue(globalMocks.mockTreeProviders);
globalMocks.testJobsProvider.mSessionNodes = globalMocks.mockTreeProviders.ds.mSessionNodes;
expect(globalMocks.mockTreeProviders.ds.mSessionNodes.length).toEqual(2);
expect(globalMocks.mockTreeProviders.uss.mSessionNodes.length).toEqual(2);
expect(globalMocks.mockTreeProviders.job.mSessionNodes.length).toEqual(2);
await globalMocks.testJobsProvider.deleteSession(globalMocks.testJobsProvider.mSessionNodes[1], true);
expect(globalMocks.mockTreeProviders.ds.mSessionNodes.length).toEqual(1);
expect(globalMocks.mockTreeProviders.uss.mSessionNodes.length).toEqual(1);
expect(globalMocks.mockTreeProviders.job.mSessionNodes.length).toEqual(1);
});
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ describe("Test src/jobs/extension", () => {
name: "zowe.jobs.removeJobsSession",
mock: [
{ spy: jest.spyOn(contextuals, "isJobsSession"), arg: [test.value], ret: true },
{ spy: jest.spyOn(jobsProvider, "deleteSession"), arg: [test.value] },
{ spy: jest.spyOn(jobsProvider, "deleteSession"), arg: [test.value, undefined] },
],
},
{
Expand Down
17 changes: 14 additions & 3 deletions packages/zowe-explorer/__tests__/__unit__/uss/USSTree.unit.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import {
createInstanceOfProfile,
createValidIProfile,
createTreeView,
createTreeProviders,
} from "../../../__mocks__/mockCreators/shared";
import * as globals from "../../../src/globals";
import * as vscode from "vscode";
Expand All @@ -32,6 +33,7 @@ import { getIconByNode } from "../../../src/generators/icons";
import * as workspaceUtils from "../../../src/utils/workspace";
import { createUssApi, bindUssApi } from "../../../__mocks__/mockCreators/api";
import { ZoweLogger } from "../../../src/utils/LoggerUtils";
import { TreeProviders } from "../../../src/shared/TreeProviders";

async function createGlobalMocks() {
const globalMocks = {
Expand Down Expand Up @@ -76,6 +78,7 @@ async function createGlobalMocks() {
testTree: null,
profilesForValidation: { status: "active", name: "fake" },
mockProfilesCache: new ProfilesCache(zowe.imperative.Logger.getAppLogger()),
mockTreeProviders: createTreeProviders(),
};

globalMocks.mockTextDocuments.push(globalMocks.mockTextDocumentDirty);
Expand Down Expand Up @@ -503,7 +506,7 @@ describe("USSTree Unit Tests - Function USSTree.deleteSession()", () => {
const newMocks = {
testTree2: new USSTree(),
testSessionNode: new ZoweUSSNode("testSessionNode", vscode.TreeItemCollapsibleState.Collapsed, null, globalMocks.testSession, null),
startLength: null,
startLength: 0,
};
const ussSessionTestNode = createUSSSessionNode(globalMocks.testSession, globalMocks.testProfile);
newMocks.testTree2.mSessionNodes.push(ussSessionTestNode);
Expand All @@ -517,8 +520,16 @@ describe("USSTree Unit Tests - Function USSTree.deleteSession()", () => {
const globalMocks = await createGlobalMocks();
const blockMocks = await createBlockMocks(globalMocks);

blockMocks.testTree2.deleteSession(blockMocks.testTree2.mSessionNodes[blockMocks.startLength - 1]);
expect(blockMocks.testTree2.mSessionNodes.length).toEqual(blockMocks.startLength - 1);
jest.spyOn(TreeProviders, "providers", "get").mockReturnValue(globalMocks.mockTreeProviders);

blockMocks.testTree2.mSessionNodes = globalMocks.mockTreeProviders.ds.mSessionNodes;
expect(globalMocks.mockTreeProviders.ds.mSessionNodes.length).toEqual(2);
expect(globalMocks.mockTreeProviders.uss.mSessionNodes.length).toEqual(2);
expect(globalMocks.mockTreeProviders.job.mSessionNodes.length).toEqual(2);
blockMocks.testTree2.deleteSession(globalMocks.mockTreeProviders.ds.mSessionNodes[1], true);
expect(globalMocks.mockTreeProviders.ds.mSessionNodes.length).toEqual(1);
expect(globalMocks.mockTreeProviders.uss.mSessionNodes.length).toEqual(1);
expect(globalMocks.mockTreeProviders.job.mSessionNodes.length).toEqual(1);
});
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ describe("Test src/dataset/extension", () => {
name: "zowe.uss.removeSession",
mock: [
{ spy: jest.spyOn(contextuals, "isUssSession"), arg: [test.value], ret: true },
{ spy: jest.spyOn(ussFileProvider, "deleteSession"), arg: [test.value] },
{ spy: jest.spyOn(ussFileProvider, "deleteSession"), arg: [test.value, undefined] },
],
},
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import * as vscode from "vscode";
import { imperative } from "@zowe/cli";
import { ZoweUSSNode } from "../../../src/uss/ZoweUSSNode";
import { ZoweExplorerApiRegister } from "../../../src/ZoweExplorerApiRegister";
import { TreeProviders } from "../../../src/shared/TreeProviders";

jest.mock("fs");
jest.mock("vscode");
Expand Down Expand Up @@ -54,6 +55,7 @@ describe("ProfileManagement unit tests", () => {
mockDisableValidationChosen: ProfileManagement.disableProfileValildationQpItem[ProfileManagement.AuthQpLabels.disable],
mockProfileInfo: { usingTeamConfig: true },
mockProfileInstance: null as any,
mockTreeProviders: sharedMock.createTreeProviders(),
debugLogSpy: null as any,
promptSpy: null as any,
editSpy: null as any,
Expand Down Expand Up @@ -141,10 +143,12 @@ describe("ProfileManagement unit tests", () => {
value: jest.fn().mockResolvedValue(mocks.mockProfileInfo as imperative.ProfileInfo),
configurable: true,
});
jest.spyOn(TreeProviders, "providers", "get").mockReturnValue(mocks.mockTreeProviders);
mocks.mockResolveQp.mockResolvedValueOnce(mocks.mockHideProfChosen);
mocks.mockResolveQp.mockResolvedValueOnce(ProfileManagement["getPromptHideFromAllTreesQpItems"]()[0]);
await ProfileManagement.manageProfile(mocks.mockDsSessionNode);
expect(mocks.debugLogSpy).toBeCalledWith(mocks.logMsg);
expect(mocks.commandSpy).toHaveBeenLastCalledWith("zowe.ds.removeSession", mocks.mockDsSessionNode);
expect(mocks.commandSpy).toHaveBeenLastCalledWith("zowe.ds.removeSession", mocks.mockDsSessionNode, null, false);
});
it("profile using basic authentication should see delete commands called when Delete Profile chosen with v1 profile", async () => {
const mocks = createBlockMocks(createGlobalMocks());
Expand Down Expand Up @@ -188,10 +192,12 @@ describe("ProfileManagement unit tests", () => {
});
it("profile using token authentication should see correct command called for hiding a unix tree session node", async () => {
const mocks = createBlockMocks(createGlobalMocks());
jest.spyOn(TreeProviders, "providers", "get").mockReturnValue(mocks.mockTreeProviders);
mocks.mockResolveQp.mockResolvedValueOnce(mocks.mockHideProfChosen);
mocks.mockResolveQp.mockResolvedValueOnce(ProfileManagement["getPromptHideFromAllTreesQpItems"]()[1]);
await ProfileManagement.manageProfile(mocks.mockUnixSessionNode);
expect(mocks.debugLogSpy).toBeCalledWith(mocks.logMsg);
expect(mocks.commandSpy).toHaveBeenLastCalledWith("zowe.uss.removeSession", mocks.mockUnixSessionNode);
expect(mocks.commandSpy).toHaveBeenLastCalledWith("zowe.uss.removeSession", mocks.mockUnixSessionNode, null, false);
});
it("profile using token authentication should see correct command called for enabling validation a unix tree session node", async () => {
const mocks = createBlockMocks(createGlobalMocks());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,12 @@
"qpPlaceholders.qp.basic": "Profile {0} is using basic authentication. Choose a profile action.",
"qpPlaceholders.qp.token": "Profile {0} is using token authentication. Choose a profile action.",
"qpPlaceholders.qp.choose": "Profile {0} doesn't specify an authentication method. Choose a profile action.",
"ProfileManagement.promptHideFromAllTrees.allLbl": "Yes",
"ProfileManagement.promptHideFromAllTrees.allDesc": "Hide for all trees",
"ProfileManagement.promptHideFromAllTrees.currentLbl": "No",
"ProfileManagement.promptHideFromAllTrees.currentDesc": "Hide for current tree selected",
"ProfileManagement.promptHideFromAllTrees.howToHide": "Do you wish to hide this profile from all trees?",
"ProfileManagement.handleHideProfiles.cancelled": "Operation Cancelled",
"addBasicAuthQpItem.addCredentials.qpLabel": "$(plus) Add Credentials",
"addBasicAuthQpItem.addCredentials.qpDetail": "Add username and password for basic authentication",
"updateBasicAuthQpItem.updateCredentials.qpLabel": "$(refresh) Update Credentials",
Expand Down
Loading
Loading