Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/main' into fix/uss/save-diff-dir
Browse files Browse the repository at this point in the history
Signed-off-by: Billie Simmons <[email protected]>
  • Loading branch information
JillieBeanSim committed Dec 5, 2023
2 parents 3cac29d + 99fcda2 commit b8f996d
Show file tree
Hide file tree
Showing 19 changed files with 418 additions and 305 deletions.
1 change: 1 addition & 0 deletions packages/zowe-explorer-api/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ 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)
- Added new optional parameter `provider` of type `IZoweTree<IZoweTreeNode>` for `IZoweTree.addSession` to specify a tree to add the profile to.
- Added optional `filter` and `actualJobs` variables to `IZoweJobTreeNode` to track local filter search.
- Added new optional record `openFiles` to `IZoweTree` to track opened files under a specific tree view. [#2597](https://github.com/zowe/vscode-extension-for-zowe/issues/2597)

Expand Down
16 changes: 15 additions & 1 deletion packages/zowe-explorer-api/src/tree/IZoweTree.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
*/

import * as vscode from "vscode";
import { imperative } from "@zowe/cli";
import { IZoweTreeNode } from "./IZoweTreeNode";
import { DataSetAllocTemplate, PersistenceSchemaEnum } from "../profiles/UserSettings";

Expand Down Expand Up @@ -68,14 +69,27 @@ export interface IZoweTree<T> extends vscode.TreeDataProvider<T> {
* Adds a session to the container
* @param sessionName
* @param type e.g. zosmf
* @param provider tree provider to add to, undefined will add for all
*/
addSession(sessionName?: string, type?: string): Promise<void>;
addSession(sessionName?: string, type?: string, provider?: IZoweTree<IZoweTreeNode>): Promise<void>;

/**
* Adds a single session to the tree
* @param profile the profile to add to the tree
*/
addSingleSession(profile: imperative.IProfileLoaded): Promise<void>;

/**
* Edit a session to the container
* @param node This parameter identifies the node that needs to be called
*/
editSession(node: IZoweTreeNode, zoweFileProvider: IZoweTree<IZoweTreeNode>): Promise<void>;

/**
* Get sessions from persistent object of provider
*/
getSessions(): string[];

/**
* Add a new session to the container
* @param zoweFileProvider The tree to which the profile should be added
Expand Down
2 changes: 1 addition & 1 deletion packages/zowe-explorer/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ All notable changes to the "vscode-extension-for-zowe" extension will be documen
- Added support for hiding a Zowe profile across all trees [#2567](https://github.com/zowe/vscode-extension-for-zowe/issues/2567)
- Added support for enabling/disabling validation for a Zowe profile across all trees [#2570](https://github.com/zowe/vscode-extension-for-zowe/issues/2570)
- Added Display confirmation dialog when submitting local JCL. [#2061](https://github.com/zowe/vscode-extension-for-zowe/issues/2061)
- Added "Sort Jobs" feature in Jobs tree view: accessible via sort icon or right-clicking on session node. [#2257](https://github.com/zowe/vscode-extension-for-zowe/issues/2257)
- Added support for adding a Zowe profile across all trees [#2603](https://github.com/zowe/vscode-extension-for-zowe/issues/2603)
- Added "Filter Jobs" feature in Jobs tree view: accessible via filter icon or right-clicking on session node. [#2599](https://github.com/zowe/vscode-extension-for-zowe/issues/2599)

### Bug fixes
Expand Down
4 changes: 4 additions & 0 deletions packages/zowe-explorer/__mocks__/mockCreators/shared.ts
Original file line number Diff line number Diff line change
Expand Up @@ -281,6 +281,7 @@ export function createTreeView(selection?): vscode.TreeView<ZoweTreeProvider> {
visible: true,
onDidChangeVisibility: jest.fn(),
dispose: jest.fn(),
addSingleSession: jest.fn(),
} as unknown as vscode.TreeView<ZoweTreeProvider>;
}

Expand Down Expand Up @@ -588,6 +589,7 @@ export function createTreeProviders() {
deleteSession: jest.fn(),
removeSession: jest.fn(),
refresh: jest.fn(),
addSingleSession: jest.fn(),
} as any,
uss: {
mSessionNodes: [
Expand All @@ -597,6 +599,7 @@ export function createTreeProviders() {
deleteSession: jest.fn(),
removeSession: jest.fn(),
refresh: jest.fn(),
addSingleSession: jest.fn(),
} as any,
job: {
mSessionNodes: [
Expand All @@ -606,6 +609,7 @@ export function createTreeProviders() {
removeSession: jest.fn(),
deleteSession: jest.fn(),
refresh: jest.fn(),
addSingleSession: jest.fn(),
} as any,
};
}
Original file line number Diff line number Diff line change
Expand Up @@ -325,6 +325,10 @@ export async function addProfileDetails(profileName: string) {
await driverChrome.sleep(SHORTSLEEPTIME);
const responseTimeout = await driverChrome.findElement(By.xpath(DatasetsLocators.emptyInputBoxXpath));
responseTimeout.sendKeys(Key.ENTER);
await driverChrome.sleep(SHORTSLEEPTIME);
const addToAllTrees = await driverChrome.findElement(By.xpath(DatasetsLocators.emptyInputBoxXpath));
addToAllTrees.sendKeys("No");
addToAllTrees.sendKeys(Key.ENTER);
}
export async function clickOnDatasetsPanel() {
await driverChrome.findElement(By.id(DatasetsLocators.datasetsPanelId)).click();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import { Builder, By, Key, until } from "selenium-webdriver";
import * as firefox from "selenium-webdriver/firefox";
import { TheiaLocator, DatasetsLocators, UssLocators, JobsLocators } from "./Locators";

const SHORTSLEEPTIME = 2000;
const WAITTIME = 30000;
let driverFirefox: any;

Expand Down Expand Up @@ -72,6 +73,10 @@ export async function addProfileDetailsInUss(profileName: string) {
const ussProfileName = await driverFirefox.findElement(By.xpath(UssLocators.emptyInputBoxXpath));
ussProfileName.sendKeys(profileName);
ussProfileName.sendKeys(Key.ENTER);
await driverFirefox.sleep(SHORTSLEEPTIME);
const addToAllTrees = await driverFirefox.findElement(By.xpath(JobsLocators.emptyInputBoxXpath));
addToAllTrees.sendKeys("No");
addToAllTrees.sendKeys(Key.ENTER);
}

export async function addProfileDetailsInJobs(profileName: string) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ import * as path from "path";
import { SettingsConfig } from "../../src/utils/SettingsConfig";
import { ZoweLogger } from "../../src/utils/LoggerUtils";
import { TreeProviders } from "../../src/shared/TreeProviders";
import { ProfileManagement } from "../../src/utils/ProfileManagement";

jest.mock("child_process");
jest.mock("fs");
Expand Down Expand Up @@ -573,18 +574,41 @@ describe("Profiles Unit Tests - Function createZoweSession", () => {
hide: jest.fn(),
value: "test",
} as any);
jest.spyOn(Gui, "resolveQuickPick").mockResolvedValueOnce(new utils.FilterDescriptor("Test"));
jest.spyOn(Gui, "resolveQuickPick").mockResolvedValueOnce(new utils.FilterDescriptor("Test1"));
jest.spyOn(Gui, "resolveQuickPick").mockResolvedValueOnce(new utils.FilterDescriptor("Test2"));
jest.spyOn(Profiles.getInstance(), "getProfileInfo").mockResolvedValue({
usingTeamConfig: false,
} as any);
jest.spyOn(Gui, "showInputBox").mockResolvedValue("test");
jest.spyOn(Profiles.getInstance(), "createNewConnection").mockResolvedValue("Test");
const refreshSpy = jest.spyOn(Profiles.getInstance(), "refresh").mockImplementation();
jest.spyOn(ProfileManagement, "handleChangeForAllTrees").mockResolvedValue(true);
jest.spyOn(TreeProviders, "providers", "get").mockReturnValue({
ds: { addSingleSession: jest.fn(), mSessionNodes: [...globalMocks.testUSSTree.mSessionNodes], refresh: jest.fn() } as any,
uss: { addSingleSession: jest.fn(), mSessionNodes: [...globalMocks.testUSSTree.mSessionNodes], refresh: jest.fn() } as any,
jobs: { addSingleSession: jest.fn(), mSessionNodes: [...globalMocks.testUSSTree.mSessionNodes], refresh: jest.fn() } as any,
} as any);
await expect(Profiles.getInstance().createZoweSession(globalMocks.testUSSTree)).resolves.not.toThrow();
expect(refreshSpy).toBeCalledTimes(1);
expect(spyInfo).toBeCalledWith("New profile created, test.");
refreshSpy.mockClear();
spyInfo.mockClear();
jest.spyOn(Gui, "resolveQuickPick").mockReset();
});

it("Tests that createZoweSession runs successfully and uses the chosenProfile", async () => {
const globalMocks = await createGlobalMocks();
jest.spyOn(Gui, "createQuickPick").mockReturnValue({
show: jest.fn(),
hide: jest.fn(),
value: "test",
} as any);
jest.spyOn(Gui, "resolveQuickPick").mockResolvedValueOnce({ label: "test" });
const spyInfo = jest.spyOn(ZoweLogger, "info");
jest.spyOn(ProfileManagement, "handleChangeForAllTrees").mockResolvedValue(true);
await expect(Profiles.getInstance().createZoweSession(globalMocks.testUSSTree)).resolves.not.toThrow();
expect(spyInfo).toBeCalledWith("The profile test has been added to the zowe.uss.history tree.");
spyInfo.mockClear();
});

it("Tests that createZoweSession catches error and log warning", async () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@ import { SettingsConfig } from "../../../src/utils/SettingsConfig";
import { ZoweTreeProvider } from "../../../src/abstract/ZoweTreeProvider";
import { ZoweLogger } from "../../../src/utils/LoggerUtils";
import { createDatasetSessionNode } from "../../../__mocks__/mockCreators/datasets";
import { TreeProviders } from "../../../src/shared/TreeProviders";
import { createDatasetTree } from "../../../src/dataset/DatasetTree";
import * as sharedActions from "../../../src/shared/actions";

async function createGlobalMocks() {
const globalMocks = {
Expand All @@ -49,6 +52,7 @@ async function createGlobalMocks() {
testSession: createISession(),
testResponse: createFileResponse({ items: [] }),
testUSSTree: null,
testDSTree: null,
testUSSNode: null,
testSessionNode: null,
testTreeProvider: new ZoweTreeProvider(PersistenceSchemaEnum.USS, null),
Expand Down Expand Up @@ -191,13 +195,29 @@ describe("ZoweJobNode unit tests - Function editSession", () => {
it("Tests that editSession is executed successfully ", async () => {
const globalMocks = await createGlobalMocks();
const blockMocks = await createBlockMocks(globalMocks);
const checkSession = jest.spyOn(blockMocks.testJobsProvider, "editSession");
const spy = jest.spyOn(ZoweLogger, "trace");
await blockMocks.testJobsProvider.editSession(blockMocks.jobNode, globalMocks.testUSSTree);
expect(globalMocks.mockEditSession).toHaveBeenCalled();
expect(spy).toBeCalled();
spy.mockClear();
});
it("Tests that the session is edited and added to only the specific tree modified", async () => {
const globalMocks = await createGlobalMocks();
const blockMocks = await createBlockMocks(globalMocks);
const deleteSessionForProviderSpy = jest.spyOn(ZoweTreeProvider.prototype as any, "deleteSessionForProvider");
const mockJobProvider = {
addSingleSession: jest.fn(),
mSessionNodes: [blockMocks.jobNode],
refresh: jest.fn(),
removeSession: jest.fn(),
} as any;
jest.spyOn(TreeProviders, "providers", "get").mockReturnValue({ job: mockJobProvider } as any);
jest.spyOn(blockMocks.jobNode, "getSession").mockReturnValue(null);
blockMocks.jobNode.contextValue = globals.JOBS_SESSION_CONTEXT;
await blockMocks.testJobsProvider.editSession(blockMocks.jobNode, globalMocks.testUSSTree);
expect(globalMocks.mockEditSession).toHaveBeenCalled();
expect(deleteSessionForProviderSpy).toBeCalledWith(blockMocks.jobNode, mockJobProvider);
});
});

describe("Tree Provider unit tests, function getTreeItem", () => {
Expand Down Expand Up @@ -510,3 +530,26 @@ describe("Tree Provider Unit Tests - function ssoLogout", () => {
expect(blockMocks.executeCommandSpy).not.toHaveBeenCalledWith("zowe.ds.refreshAll");
});
});

describe("Tree Provider Unit Tests - function loadProfileByPersistedProfile", () => {
it("should reset validation settings and warn the user of an error when loading default", async () => {
const globalMocks = await createGlobalMocks();
globalMocks.testDSTree = createDatasetTree(imperative.Logger.getAppLogger());
globalMocks.testDSTree.mSessionNodes = [
{ label: "profile1", getProfileName: (): string => "sestest" },
{ label: "profile2", getProfileName: (): string => "sestest" },
];
globalMocks.testDSTree.getSessions = (): string[] => ["sestest"];
globalMocks.testDSTree.addSingleSession = jest.fn();

const resetValidationSettingsSpy = jest.spyOn(sharedActions, "resetValidationSettings");
resetValidationSettingsSpy.mockImplementation();

const zoweLoggerWarnSpy = jest.spyOn(ZoweLogger, "warn");

await expect(ZoweTreeProvider.prototype["loadProfileByPersistedProfile"](globalMocks.testDSTree, "zosmf", true)).resolves.not.toThrow();
expect(globalMocks.testDSTree.addSingleSession).toBeCalledTimes(1);
expect(resetValidationSettingsSpy).toBeCalledTimes(2);
expect(zoweLoggerWarnSpy).toBeCalledTimes(2);
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -930,6 +930,12 @@ describe("Dataset Tree Unit Tests - Function addSession", () => {
mocked(vscode.window.createTreeView).mockReturnValueOnce(blockMocks.treeView);
const testTree = new DatasetTree();
testTree.mSessionNodes.push(blockMocks.datasetSessionNode);
jest.spyOn(testTree, "addSingleSession").mockImplementation();
jest.spyOn(TreeProviders, "providers", "get").mockReturnValue({
ds: { addSingleSession: jest.fn(), mSessionNodes: [blockMocks.datasetSessionNode], refresh: jest.fn() } as any,
uss: { addSingleSession: jest.fn(), mSessionNodes: [blockMocks.datasetSessionNode], refresh: jest.fn() } as any,
jobs: { addSingleSession: jest.fn(), mSessionNodes: [blockMocks.datasetSessionNode], refresh: jest.fn() } as any,
} as any);

await testTree.addSession(blockMocks.imperativeProfile.name);
expect(testTree.mSessionNodes[1].label).toBe(blockMocks.imperativeProfile.name);
Expand Down Expand Up @@ -1060,6 +1066,28 @@ describe("USSTree Unit Tests - Function USSTree.addSingleSession()", () => {
expect(blockMocks.testTree.mSessionNodes.length).toEqual(2);
expect(blockMocks.testTree.mSessionNodes[1].profile.name).toEqual(blockMocks.testProfile.name);
});

it("should log the error if the error includes the hostname", () => {
createGlobalMocks();
const blockMocks = createBlockMocks();
jest.spyOn(ZoweExplorerApiRegister.getMvsApi(blockMocks.testProfile), "getSession").mockImplementationOnce(() => {
throw new Error("test error hostname:sample.com");
});
const zoweLoggerErrorSpy = jest.spyOn(ZoweLogger, "error");
expect(blockMocks.testTree.addSingleSession({ name: "test1234" }));
expect(zoweLoggerErrorSpy).toBeCalledTimes(1);
});

it("should call 'errorHandling()' if the error does not include the hostname", () => {
createGlobalMocks();
const blockMocks = createBlockMocks();
jest.spyOn(ZoweExplorerApiRegister.getMvsApi(blockMocks.testProfile), "getSession").mockImplementationOnce(() => {
throw new Error("test error");
});
const errorHandlingSpy = jest.spyOn(utils, "errorHandling");
expect(blockMocks.testTree.addSingleSession({ name: "test1234" }));
expect(errorHandlingSpy).toBeCalledTimes(1);
});
});

describe("Dataset Tree Unit Tests - Function addFavorite", () => {
Expand Down Expand Up @@ -1554,6 +1582,13 @@ describe("Dataset Tree Unit Tests - Function datasetFilterPrompt", () => {
);
favoriteSearch.contextValue = globals.DS_SESSION_CONTEXT + globals.FAV_SUFFIX;

jest.spyOn(testTree, "addSingleSession").mockImplementation();
jest.spyOn(TreeProviders, "providers", "get").mockReturnValue({
ds: { addSingleSession: jest.fn(), mSessionNodes: [blockMocks.datasetSessionNode], refresh: jest.fn() } as any,
uss: { addSingleSession: jest.fn(), mSessionNodes: [blockMocks.datasetSessionNode], refresh: jest.fn() } as any,
jobs: { addSingleSession: jest.fn(), mSessionNodes: [blockMocks.datasetSessionNode], refresh: jest.fn() } as any,
} as any);

await testTree.datasetFilterPrompt(favoriteSearch);

expect(addSessionSpy).toHaveBeenLastCalledWith(blockMocks.datasetSessionNode.label.trim());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -219,9 +219,12 @@ describe("ZoweJobNode unit tests - Function createJobsTree", () => {
describe("ZoweJobNode unit tests - Function addSession", () => {
it("Tests that addSession adds the session to the tree", async () => {
const globalMocks = await createGlobalMocks();

jest.spyOn(TreeProviders, "providers", "get").mockReturnValue({
ds: { addSingleSession: jest.fn(), mSessionNodes: [...globalMocks.testJobsProvider.mSessionNodes], refresh: jest.fn() } as any,
uss: { addSingleSession: jest.fn(), mSessionNodes: [...globalMocks.testJobsProvider.mSessionNodes], refresh: jest.fn() } as any,
jobs: { addSingleSession: jest.fn(), mSessionNodes: [...globalMocks.testJobsProvider.mSessionNodes], refresh: jest.fn() } as any,
} as any);
await globalMocks.testJobsProvider.addSession("sestest");

expect(globalMocks.testJobsProvider.mSessionNodes[1]).toBeDefined();
expect(globalMocks.testJobsProvider.mSessionNodes[1].label).toEqual("sestest");
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,12 @@ async function createGlobalMocks() {
value: jest.fn().mockReturnValue({ usingTeamConfig: false }),
});

jest.spyOn(TreeProviders, "providers", "get").mockReturnValue({
ds: { addSingleSession: jest.fn(), mSessionNodes: [...globalMocks.testTree.mSessionNodes], refresh: jest.fn() } as any,
uss: { addSingleSession: jest.fn(), mSessionNodes: [...globalMocks.testTree.mSessionNodes], refresh: jest.fn() } as any,
jobs: { addSingleSession: jest.fn(), mSessionNodes: [...globalMocks.testTree.mSessionNodes], refresh: jest.fn() } as any,
} as any);

return globalMocks;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -290,6 +290,7 @@ describe("ProfileManagement unit tests", () => {
ProfileManagement["getPromptChangeForAllTreesOptions"]()[1]
);
mocks.mockJobSessionNode.contextValue = globals.JOBS_SESSION_CONTEXT;
mocks.mockJobSessionNode.getLabel = jest.fn(() => "test");
await expect(ProfileManagement["handleHideProfiles"](mocks.mockJobSessionNode)).resolves.toEqual(undefined);
expect(commandSpy).toHaveBeenCalledWith("zowe.jobs.removeSession", mocks.mockJobSessionNode, null, false);
});
Expand Down Expand Up @@ -371,4 +372,34 @@ describe("ProfileManagement unit tests", () => {
expect(warnSpy).toBeCalledWith(thrownError);
});
});

describe("promptChangeForAllTrees unit tests", () => {
beforeEach(() => {
jest.resetAllMocks();
jest.clearAllMocks();
jest.restoreAllMocks();
});

it("should prompt for applying change to all trees", async () => {
jest.spyOn(TreeProviders, "sessionIsPresentInOtherTrees").mockReturnValue(false);
const expectedResult = { label: "test", description: "test" } as vscode.QuickPickItem;
const createQuickPickSpy = jest.spyOn(Gui, "createQuickPick");
const resolveQuickPickSpy = jest.spyOn(Gui, "resolveQuickPick");
const showSpy = jest.fn();
const hideSpy = jest.fn();
createQuickPickSpy.mockReturnValue({
placeholder: "",
items: [],
activeItems: [],
show: showSpy,
hide: hideSpy,
} as any);
resolveQuickPickSpy.mockResolvedValue(expectedResult);
await expect(ProfileManagement["promptChangeForAllTrees"]("test", true)).resolves.toEqual(expectedResult);
expect(createQuickPickSpy).toBeCalledTimes(1);
expect(resolveQuickPickSpy).toBeCalledTimes(1);
expect(showSpy).toBeCalledTimes(1);
expect(hideSpy).toBeCalledTimes(1);
});
});
});
Loading

0 comments on commit b8f996d

Please sign in to comment.