From b9b54ef64a8c7c1a9ca7a7b6f96f41cee51a0371 Mon Sep 17 00:00:00 2001 From: Colin Stone <30794003+Colin-Stone@users.noreply.github.com> Date: Tue, 24 Dec 2019 13:59:26 +0000 Subject: [PATCH 01/19] Rebased on interface Signed-off-by: Colin Stone <30794003+Colin-Stone@users.noreply.github.com> --- .../USSTree.integration.test.ts | 4 +- .../ZoweNode.integration.test.ts | 6 +- .../extension.integration.test.ts | 10 +- __tests__/__unit__/USSTree.unit.test.ts | 16 +- __tests__/__unit__/ZoweJobNode.unit.test.ts | 31 +- __tests__/__unit__/ZoweNode.unit.test.ts | 2 +- __tests__/__unit__/ZoweUSSNode.unit.test.ts | 2 +- __tests__/__unit__/extension.unit.test.ts | 34 ++- .../__unit__/uss/ussNodeActions.unit.test.ts | 18 +- src/DatasetTree.ts | 142 +++------- src/USSTree.ts | 171 ++--------- src/ZosJobsProvider.ts | 266 +++++++----------- src/ZoweJobNode.ts | 58 ++-- src/ZoweNode.ts | 35 +-- src/ZoweTree.ts | 42 --- src/ZoweUSSNode.ts | 60 ++-- src/abstract/ZoweTreeNode.ts | 75 +++++ src/abstract/ZoweTreeProvider.ts | 153 ++++++++++ src/api/ZoweTree.ts | 239 ++++++++++++++++ src/extension.ts | 175 ++++++------ src/jobs/jobNodeActions.ts | 27 ++ src/mvs/mvsNodeActions.ts | 2 +- src/uss/ussNodeActions.ts | 17 +- src/utils.ts | 24 +- 24 files changed, 900 insertions(+), 709 deletions(-) delete mode 100644 src/ZoweTree.ts create mode 100644 src/abstract/ZoweTreeNode.ts create mode 100644 src/abstract/ZoweTreeProvider.ts create mode 100644 src/api/ZoweTree.ts create mode 100644 src/jobs/jobNodeActions.ts diff --git a/__tests__/__integration__/USSTree.integration.test.ts b/__tests__/__integration__/USSTree.integration.test.ts index 727c6cb561..d84df4379a 100644 --- a/__tests__/__integration__/USSTree.integration.test.ts +++ b/__tests__/__integration__/USSTree.integration.test.ts @@ -109,7 +109,7 @@ describe("USSTree Integration Tests", async () => { expect(sessChildren2.length).toEqual(sampleRChildren.length); expect(dirChildren.length).toBe(2); expect(dirChildren[0].label).toBe("aFile4.txt"); - expect(dirChildren[0].mParent.tooltip).toContain("/group/aDir5"); + expect(dirChildren[0].getParent().tooltip).toContain("/group/aDir5"); expect(dirChildren[0].tooltip).toContain("/group/aDir5/aFile4.txt"); expect(dirChildren[1].label).toBe("aFile5.txt"); expect(dirChildren[1].tooltip).toContain("/group/aDir5/aFile5.txt"); @@ -201,7 +201,7 @@ describe("USSTree Integration Tests", async () => { await testTree.addSession(); const favoriteNode = new ZoweUSSNode("file.txt", vscode.TreeItemCollapsibleState.Collapsed, sessNode, null, sessNode.fullPath, testConst.profile.name); - await testTree.addUSSFavorite(favoriteNode); + await testTree.addFavorite(favoriteNode); const filtered = testTree.mFavorites.filter((temp) => temp.label === `[${favoriteNode.getSessionNode().label}]: ${favoriteNode.label}`); expect(filtered.length).toEqual(1); diff --git a/__tests__/__integration__/ZoweNode.integration.test.ts b/__tests__/__integration__/ZoweNode.integration.test.ts index ed216156ed..52fd13eac2 100644 --- a/__tests__/__integration__/ZoweNode.integration.test.ts +++ b/__tests__/__integration__/ZoweNode.integration.test.ts @@ -40,14 +40,14 @@ describe("ZoweNode Integration Tests", async () => { expect(emptyPONode.label).toBeDefined(); expect(emptyPONode.collapsibleState).toBeDefined(); - expect(emptyPONode.mParent).toBeDefined(); + expect(emptyPONode.getParent()).toBeDefined(); // Tests PS node const PSNode = new ZoweNode(pattern + ".TPS", vscode.TreeItemCollapsibleState.None, sessNode, null); expect(PSNode.label).toBeDefined(); expect(PSNode.collapsibleState).toBeDefined(); - expect(PSNode.mParent).toBeDefined(); + expect(PSNode.getParent()).toBeDefined(); }); /************************************************************************************************************* @@ -59,7 +59,7 @@ describe("ZoweNode Integration Tests", async () => { expect(edgeNode.label).toBeDefined(); expect(edgeNode.collapsibleState).toBeDefined(); - expect(edgeNode.mParent).toBeDefined(); + expect(edgeNode.getParent()).toBeDefined(); }); /************************************************************************************************************* diff --git a/__tests__/__integration__/extension.integration.test.ts b/__tests__/__integration__/extension.integration.test.ts index 7c59865cd5..0f064e2147 100644 --- a/__tests__/__integration__/extension.integration.test.ts +++ b/__tests__/__integration__/extension.integration.test.ts @@ -26,7 +26,7 @@ import { DatasetTree, createDatasetTree } from "../../src/DatasetTree"; import { ZoweNode } from "../../src/ZoweNode"; import { USSTree } from "../../src/USSTree"; import { ZoweUSSNode } from "../../src/ZoweUSSNode"; -import { ZosJobsProvider } from "../../src/ZosJobsProvider"; +import { IZoweTreeNode } from "../../src/api/ZoweTree"; const TIMEOUT = 45000; declare var it: Mocha.ITestDefinition; @@ -861,8 +861,8 @@ describe("Extension Integration Tests", () => { /************************************************************************************************************* * Returns array of all subnodes of given node *************************************************************************************************************/ -async function getAllNodes(nodes: ZoweNode[]) { - let allNodes = new Array(); +async function getAllNodes(nodes: IZoweTreeNode[]) { + let allNodes = new Array(); for (const node of nodes) { allNodes = allNodes.concat(await getAllNodes(await node.getChildren())); @@ -1066,8 +1066,8 @@ describe("TreeView", () => { /************************************************************************************************************* * Returns array of all subnodes of given node *************************************************************************************************************/ -async function getAllUSSNodes(nodes: ZoweUSSNode[]) { - let allNodes = new Array(); +async function getAllUSSNodes(nodes: IZoweTreeNode[]) { + let allNodes = new Array(); for (const node of nodes) { allNodes = allNodes.concat(await getAllUSSNodes(await node.getChildren())); diff --git a/__tests__/__unit__/USSTree.unit.test.ts b/__tests__/__unit__/USSTree.unit.test.ts index b83c0696a7..8461659179 100644 --- a/__tests__/__unit__/USSTree.unit.test.ts +++ b/__tests__/__unit__/USSTree.unit.test.ts @@ -113,7 +113,7 @@ describe("Unit Tests (Jest)", () => { expect(testNode.label).toBeDefined(); expect(testNode.collapsibleState).toBeDefined(); expect(testNode.label).toBeDefined(); - expect(testNode.mParent).toBeDefined(); + expect(testNode.getParent()).toBeDefined(); expect(testNode.getSession()).toBeDefined(); }); @@ -275,11 +275,11 @@ describe("Unit Tests (Jest)", () => { childFile.contextValue = extension.DS_TEXT_FILE_CONTEXT; // Check adding directory - await testTree.addUSSFavorite(parentDir); + await testTree.addFavorite(parentDir); // Check adding duplicates - await testTree.addUSSFavorite(parentDir); + await testTree.addFavorite(parentDir); // Check adding file - await testTree.addUSSFavorite(childFile); + await testTree.addFavorite(childFile); expect(testTree.mFavorites.length).toEqual(2); }); @@ -302,8 +302,8 @@ describe("Unit Tests (Jest)", () => { * Testing that removeFavorite works properly *************************************************************************************************************/ it("Testing that removeFavorite works properly", async () => { - testTree.removeUSSFavorite(testTree.mFavorites[0]); - testTree.removeUSSFavorite(testTree.mFavorites[0]); + testTree.removeFavorite(testTree.mFavorites[0]); + testTree.removeFavorite(testTree.mFavorites[0]); expect(testTree.mFavorites).toEqual([]); }); @@ -320,14 +320,14 @@ describe("Unit Tests (Jest)", () => { childFile.contextValue = extension.USS_SESSION_CONTEXT; // Check adding file - await testTree.addUSSFavorite(childFile); + await testTree.addFavorite(childFile); expect(testTree.mFavorites.length).toEqual(1); childFile = new ZoweUSSNode("folder", vscode.TreeItemCollapsibleState.None, parentDir, null, "/parent"); childFile.contextValue = extension.USS_DIR_CONTEXT; - await testTree.addUSSFavorite(childFile); + await testTree.addFavorite(childFile); // tslint:disable-next-line: no-magic-numbers expect(testTree.mFavorites.length).toEqual(2); diff --git a/__tests__/__unit__/ZoweJobNode.unit.test.ts b/__tests__/__unit__/ZoweJobNode.unit.test.ts index dc6009577a..6ce92c1f50 100644 --- a/__tests__/__unit__/ZoweJobNode.unit.test.ts +++ b/__tests__/__unit__/ZoweJobNode.unit.test.ts @@ -21,7 +21,6 @@ import * as profileLoader from "../../src/Profiles"; import * as utils from "../../src/utils"; import { Job } from "../../src/ZoweJobNode"; import { ZosJobsProvider, createJobsTree } from "../../src/ZosJobsProvider"; -import { ZoweUSSNode } from "../../src/ZoweUSSNode"; describe("Zos Jobs Unit Tests", () => { @@ -282,7 +281,10 @@ describe("Zos Jobs Unit Tests", () => { expect(job.prefix).toEqual("*"); job.prefix = "zowe*"; expect(job.prefix).toEqual("zowe*"); - job.reset(); + // reset + utils.labelHack(job); + job.children = []; + job.dirty = true; }); it("should set the search jobid to a specific value", async () => { @@ -293,7 +295,10 @@ describe("Zos Jobs Unit Tests", () => { const job = jobs[0]; job.searchId = "JOB12345"; expect(job.searchId).toEqual("JOB12345"); - job.reset(); + // reset + utils.labelHack(job); + job.children = []; + job.dirty = true; }); it("Testing that expand tree is executed successfully", async () => { @@ -310,7 +315,7 @@ describe("Zos Jobs Unit Tests", () => { expect(JSON.stringify(testJobsProvider.mSessionNodes[1].iconPath)).toContain("folder-root-default-open.svg"); const job = new Job("JOB1283", vscode.TreeItemCollapsibleState.Collapsed, testJobsProvider.mSessionNodes[0], - testJobsProvider.mSessionNodes[1].session, iJob); + testJobsProvider.mSessionNodes[1].getSession(), iJob); job.contextValue = "job"; await testJobsProvider.flipState(job, true); expect(JSON.stringify(job.iconPath)).toContain("folder-open.svg"); @@ -417,9 +422,9 @@ describe("Zos Jobs Unit Tests", () => { createBasicZosmfSession.mockReturnValue(sessionwocred); const newjobNode = new Job("[fake]: Owner:fakeUser Prefix:*", vscode.TreeItemCollapsibleState.Expanded, jobNode, sessionwocred, iJob); newjobNode.contextValue = extension.JOBS_SESSION_CONTEXT + extension.FAV_SUFFIX; - newjobNode.session.ISession.user = ""; - newjobNode.session.ISession.password = ""; - newjobNode.session.ISession.base64EncodedAuth = ""; + newjobNode.getSession().ISession.user = ""; + newjobNode.getSession().ISession.password = ""; + newjobNode.getSession().ISession.base64EncodedAuth = ""; const testJobsProvider = await createJobsTree(Logger.getAppLogger()); const qpItem: vscode.QuickPickItem = testJobsProvider.createOwner; const resolveQuickPickHelper = jest.spyOn(utils, "resolveQuickPickHelper").mockImplementation( @@ -702,10 +707,10 @@ describe("Zos Jobs Unit Tests", () => { const testTree = await createJobsTree(Logger.getAppLogger()); testTree.mFavorites = []; const job = new Job("MYHLQ(JOB1283) - Input", vscode.TreeItemCollapsibleState.Collapsed, testTree.mSessionNodes[1], - testTree.mSessionNodes[1].session, iJob); + testTree.mSessionNodes[1].getSession(), iJob); // Check adding job - await testTree.addJobsFavorite(job); + await testTree.addFavorite(job); expect(testTree.mFavorites.length).toEqual(1); testTree.mSessionNodes[1].owner = "myHLQ"; @@ -732,10 +737,10 @@ describe("Zos Jobs Unit Tests", () => { // tslint:disable-next-line: no-magic-numbers expect(testTree.mFavorites[3].label).toEqual("[firstProfileName]: MYHLQ(JOB1283)"); - testTree.removeJobsFavorite(testTree.mFavorites[0]); - testTree.removeJobsFavorite(testTree.mFavorites[0]); - testTree.removeJobsFavorite(testTree.mFavorites[0]); - testTree.removeJobsFavorite(testTree.mFavorites[0]); + testTree.removeFavorite(testTree.mFavorites[0]); + testTree.removeFavorite(testTree.mFavorites[0]); + testTree.removeFavorite(testTree.mFavorites[0]); + testTree.removeFavorite(testTree.mFavorites[0]); expect(testTree.mFavorites).toEqual([]); }); }); diff --git a/__tests__/__unit__/ZoweNode.unit.test.ts b/__tests__/__unit__/ZoweNode.unit.test.ts index 265ed87929..5ce311635e 100644 --- a/__tests__/__unit__/ZoweNode.unit.test.ts +++ b/__tests__/__unit__/ZoweNode.unit.test.ts @@ -53,7 +53,7 @@ describe("Unit Tests (Jest)", () => { expect(testNode.label).toBeDefined(); expect(testNode.collapsibleState).toBeDefined(); expect(testNode.label).toBeDefined(); - expect(testNode.mParent).toBeDefined(); + expect(testNode.getParent()).toBeDefined(); expect(testNode.getSession()).toBeDefined(); }); diff --git a/__tests__/__unit__/ZoweUSSNode.unit.test.ts b/__tests__/__unit__/ZoweUSSNode.unit.test.ts index 6b50ff3510..6565704fc3 100644 --- a/__tests__/__unit__/ZoweUSSNode.unit.test.ts +++ b/__tests__/__unit__/ZoweUSSNode.unit.test.ts @@ -63,7 +63,7 @@ describe("Unit Tests (Jest)", () => { expect(testNode.label).toBeDefined(); expect(testNode.collapsibleState).toBeDefined(); expect(testNode.label).toBeDefined(); - expect(testNode.mParent).toBeDefined(); + expect(testNode.getParent()).toBeDefined(); expect(testNode.getSession()).toBeDefined(); }); diff --git a/__tests__/__unit__/extension.unit.test.ts b/__tests__/__unit__/extension.unit.test.ts index cbde9b2dc3..1ffd8a01c0 100644 --- a/__tests__/__unit__/extension.unit.test.ts +++ b/__tests__/__unit__/extension.unit.test.ts @@ -204,7 +204,6 @@ describe("Extension Unit Tests", () => { const findFavoritedNode = jest.fn(); const findNonFavoritedNode = jest.fn(); const concatChildNodes = jest.fn(); - const concatUSSChildNodes = jest.fn(); let mockClipboardData: string; const clipboard = { writeText: jest.fn().mockImplementation((value) => mockClipboardData = value), @@ -293,7 +292,6 @@ describe("Extension Unit Tests", () => { }) }); Object.defineProperty(utils, "concatChildNodes", {value: concatChildNodes}); - Object.defineProperty(utils, "concatUSSChildNodes", {value: concatUSSChildNodes}); Object.defineProperty(fs, "mkdirSync", {value: mkdirSync}); Object.defineProperty(brtimperative, "CliProfileManager", {value: CliProfileManager}); Object.defineProperty(vscode.window, "createTreeView", {value: createTreeView}); @@ -796,7 +794,7 @@ describe("Extension Unit Tests", () => { await extension.refreshPS(child); - expect(dataSet.mock.calls[0][1]).toBe(child.mParent.label + "(" + child.label + ")"); + expect(dataSet.mock.calls[0][1]).toBe(child.getParent().getLabel() + "(" + child.label + ")"); expect(showErrorMessage.mock.calls.length).toBe(1); expect(showErrorMessage.mock.calls[0][0]).toEqual(""); @@ -1365,7 +1363,7 @@ describe("Extension Unit Tests", () => { await extension.deleteDataset(child, testTree); expect(unlinkSync.mock.calls.length).toBe(0); - expect(delDataset.mock.calls[0][1]).toBe(child.mParent.label + "(" + child.label + ")"); + expect(delDataset.mock.calls[0][1]).toBe(child.getParent().getLabel() + "(" + child.label + ")"); delDataset.mockReset(); delDataset.mockRejectedValueOnce(Error("not found")); @@ -2302,7 +2300,7 @@ describe("Extension Unit Tests", () => { existsSync.mockReset(); withProgress.mockReset(); - const node = new ZoweUSSNode("node", vscode.TreeItemCollapsibleState.None, ussNode, null, "/"); + const node = new ZoweUSSNode("node", vscode.TreeItemCollapsibleState.None, ussNode, null, "/", false, "aProfileName"); const parent = new ZoweUSSNode("parent", vscode.TreeItemCollapsibleState.Collapsed, ussNode, null, "/"); const child = new ZoweUSSNode("child", vscode.TreeItemCollapsibleState.None, parent, null, "/parent"); @@ -2322,7 +2320,7 @@ describe("Extension Unit Tests", () => { await extension.openUSS(node, false, true); expect(existsSync.mock.calls.length).toBe(1); - expect(existsSync.mock.calls[0][0]).toBe(path.join(extension.USS_DIR, "/" + node.getSessionNode().mProfileName + "/", node.fullPath)); + expect(existsSync.mock.calls[0][0]).toBe(path.join(extension.USS_DIR, "/" + node.getProfileName() + "/", node.fullPath)); expect(isFileTagBinOrAscii.mock.calls.length).toBe(1); expect(isFileTagBinOrAscii.mock.calls[0][0]).toBe(session); expect(isFileTagBinOrAscii.mock.calls[0][1]).toBe(node.fullPath); @@ -2430,7 +2428,7 @@ describe("Extension Unit Tests", () => { existsSync.mockReset(); withProgress.mockReset(); - const node = new ZoweUSSNode("node", vscode.TreeItemCollapsibleState.None, ussNode, null, "/"); + const node = new ZoweUSSNode("node", vscode.TreeItemCollapsibleState.None, ussNode, null, "/", false, "aProfileName"); const parent = new ZoweUSSNode("parent", vscode.TreeItemCollapsibleState.Collapsed, ussNode, null, "/"); const child = new ZoweUSSNode("child", vscode.TreeItemCollapsibleState.None, parent, null, "/parent"); @@ -2450,7 +2448,7 @@ describe("Extension Unit Tests", () => { await extension.openUSS(node, false, true); expect(existsSync.mock.calls.length).toBe(1); - expect(existsSync.mock.calls[0][0]).toBe(path.join(extension.USS_DIR, "/" + node.getSessionNode().mProfileName + "/", node.fullPath)); + expect(existsSync.mock.calls[0][0]).toBe(path.join(extension.USS_DIR, "/" + node.getProfileName() + "/", node.fullPath)); expect(withProgress).toBeCalledWith( { location: vscode.ProgressLocation.Notification, @@ -2609,20 +2607,20 @@ describe("Extension Unit Tests", () => { testResponse.apiResponse.items = [{name: "testFile", mode: "-rwxrwx"}]; fileToUSSFile.mockReset(); showErrorMessage.mockReset(); - concatUSSChildNodes.mockReset(); + concatChildNodes.mockReset(); const mockGetEtag = jest.spyOn(node, "getEtag").mockImplementation(() => "123"); testResponse.success = true; fileToUSSFile.mockResolvedValue(testResponse); withProgress.mockReturnValueOnce(testResponse); - concatUSSChildNodes.mockReturnValueOnce([ussNode.children[0]]); + concatChildNodes.mockReturnValueOnce([ussNode.children[0]]); await extension.saveUSSFile(testDoc, testUSSTree); - expect(concatUSSChildNodes.mock.calls.length).toBe(1); + expect(concatChildNodes.mock.calls.length).toBe(1); expect(mockGetEtag).toBeCalledTimes(1); expect(mockGetEtag).toReturnWith("123"); - concatUSSChildNodes.mockReset(); - concatUSSChildNodes.mockReturnValueOnce([ussNode.children[0]]); + concatChildNodes.mockReset(); + concatChildNodes.mockReturnValueOnce([ussNode.children[0]]); testResponse.success = false; testResponse.commandResponse = "Save failed"; fileToUSSFile.mockResolvedValueOnce(testResponse); @@ -2633,8 +2631,8 @@ describe("Extension Unit Tests", () => { expect(showErrorMessage.mock.calls.length).toBe(1); expect(showErrorMessage.mock.calls[0][0]).toBe("Save failed"); - concatUSSChildNodes.mockReset(); - concatUSSChildNodes.mockReturnValueOnce([ussNode.children[0]]); + concatChildNodes.mockReset(); + concatChildNodes.mockReturnValueOnce([ussNode.children[0]]); showErrorMessage.mockReset(); withProgress.mockRejectedValueOnce(Error("Test Error")); @@ -2642,8 +2640,8 @@ describe("Extension Unit Tests", () => { expect(showErrorMessage.mock.calls.length).toBe(1); expect(showErrorMessage.mock.calls[0][0]).toBe("Test Error"); - concatUSSChildNodes.mockReset(); - concatUSSChildNodes.mockReturnValueOnce([ussNode.children[0]]); + concatChildNodes.mockReset(); + concatChildNodes.mockReturnValueOnce([ussNode.children[0]]); showWarningMessage.mockReset(); testResponse.success = false; testResponse.commandResponse = "Rest API failure with HTTP(S) status 412"; @@ -3183,7 +3181,7 @@ describe("Extension Unit Tests", () => { await extension.downloadSpool(jobNode); expect(showOpenDialog).toBeCalled(); expect(downloadAllSpoolContentCommon).toBeCalled(); - expect(downloadAllSpoolContentCommon.mock.calls[0][0]).toEqual(jobNode.session); + expect(downloadAllSpoolContentCommon.mock.calls[0][0]).toEqual(jobNode.getSession()); expect(downloadAllSpoolContentCommon.mock.calls[0][1]).toEqual( { jobid: jobNode.job.jobid, diff --git a/__tests__/__unit__/uss/ussNodeActions.unit.test.ts b/__tests__/__unit__/uss/ussNodeActions.unit.test.ts index 78cd8245d0..f311f086ee 100644 --- a/__tests__/__unit__/uss/ussNodeActions.unit.test.ts +++ b/__tests__/__unit__/uss/ussNodeActions.unit.test.ts @@ -29,8 +29,8 @@ const mockaddZoweSession = jest.fn(); const mockUSSRefresh = jest.fn(); const mockUSSRefreshElement = jest.fn(); const mockGetUSSChildren = jest.fn(); -const mockRemoveUSSFavorite = jest.fn(); -const mockAddUSSFavorite = jest.fn(); +const mockRemoveFavorite = jest.fn(); +const mockAddFavorite = jest.fn(); const mockInitializeFavorites = jest.fn(); const showInputBox = jest.fn(); const showErrorMessage = jest.fn(); @@ -46,22 +46,20 @@ const existsSync = jest.fn(); const createBasicZosmfSession = jest.fn(); function getUSSNode() { - const ussNode1 = new ZoweUSSNode("usstest", vscode.TreeItemCollapsibleState.Expanded, null, session, null); const mParent = new ZoweUSSNode("parentNode", vscode.TreeItemCollapsibleState.Expanded, null, session, null); + const ussNode1 = new ZoweUSSNode("usstest", vscode.TreeItemCollapsibleState.Expanded, mParent, session, null); ussNode1.contextValue = extension.USS_SESSION_CONTEXT; ussNode1.fullPath = "/u/myuser"; - ussNode1.mParent = mParent; return ussNode1; } function getFavoriteUSSNode() { - const ussNodeF = new ZoweUSSNode("[profile]: usstest", vscode.TreeItemCollapsibleState.Expanded, null, session, null); const mParent = new ZoweUSSNode("Favorites", vscode.TreeItemCollapsibleState.Expanded, null, session, null); + const ussNodeF = new ZoweUSSNode("[profile]: usstest", vscode.TreeItemCollapsibleState.Expanded, mParent, session, null); mParent.contextValue = extension.FAVORITE_CONTEXT; ussNodeF.contextValue = extension.DS_TEXT_FILE_CONTEXT + extension.FAV_SUFFIX; ussNodeF.fullPath = "/u/myuser/usstest"; ussNodeF.tooltip = "/u/myuser/usstest"; - ussNodeF.mParent = mParent; return ussNodeF; } @@ -77,8 +75,8 @@ function getUSSTree() { refreshAll: mockUSSRefresh, refreshElement: mockUSSRefreshElement, getChildren: mockGetUSSChildren, - addUSSFavorite: mockAddUSSFavorite, - removeUSSFavorite: mockRemoveUSSFavorite, + addFavorite: mockAddFavorite, + removeFavorite: mockRemoveFavorite, initializeUSSFavorites: mockInitializeFavorites }; }); @@ -356,8 +354,8 @@ describe("ussNodeActions", () => { expect(testUSSTree.refresh).toHaveBeenCalled(); expect(showErrorMessage.mock.calls.length).toBe(0); expect(renameUSSFile.mock.calls.length).toBe(1); - expect(mockRemoveUSSFavorite.mock.calls.length).toBe(1); - expect(mockAddUSSFavorite.mock.calls.length).toBe(1); + expect(mockRemoveFavorite.mock.calls.length).toBe(1); + expect(mockAddFavorite.mock.calls.length).toBe(1); }); }); describe("uploadFile", () => { diff --git a/src/DatasetTree.ts b/src/DatasetTree.ts index 89a72116da..160ea28cfe 100644 --- a/src/DatasetTree.ts +++ b/src/DatasetTree.ts @@ -15,10 +15,10 @@ import * as path from "path"; import * as vscode from "vscode"; import * as nls from "vscode-nls"; import * as extension from "../src/extension"; -import { PersistentFilters } from "./PersistentFilters"; import { Profiles } from "./Profiles"; import { sortTreeItems, applyIcons, FilterDescriptor, FilterItem, getAppName, resolveQuickPickHelper } from "./utils"; -import { IZoweTree } from "./ZoweTree"; +import { IZoweTree, IZoweDatasetTreeNode } from "./api/ZoweTree"; +import { ZoweTreeProvider } from "./abstract/ZoweTreeProvider"; import { ZoweNode } from "./ZoweNode"; const localize = nls.config({ messageFormat: nls.MessageFormat.file })(); @@ -41,27 +41,36 @@ export async function createDatasetTree(log: Logger) { * @class DatasetTree * @implements {vscode.TreeDataProvider} */ -export class DatasetTree implements IZoweTree { +export class DatasetTree extends ZoweTreeProvider implements IZoweTree { private static readonly persistenceSchema: string = "Zowe-DS-Persistent"; private static readonly defaultDialogText: string = "\uFF0B " + localize("ussFilterPrompt.option.prompt.search", "Create a new filter"); - public mSessionNodes: ZoweNode[]; - public mFavoriteSession: ZoweNode; - public mFavorites: ZoweNode[] = []; - // Event Emitters used to notify subscribers that the refresh event has fired - public mOnDidChangeTreeData: vscode.EventEmitter = new vscode.EventEmitter(); - public readonly onDidChangeTreeData: vscode.Event = this.mOnDidChangeTreeData.event; - private mHistory: PersistentFilters; - private log: Logger; - private validProfile: number = -1; + public mSessionNodes: IZoweDatasetTreeNode[] = []; + public mFavorites: IZoweDatasetTreeNode[] = []; constructor() { - this.mFavoriteSession = new ZoweNode(localize("FavoriteSession", "Favorites"), vscode.TreeItemCollapsibleState.Collapsed, null, null); + super(DatasetTree.persistenceSchema, new ZoweNode(localize("Favorites", "Favorites"), + vscode.TreeItemCollapsibleState.Collapsed, null, null, null)); this.mFavoriteSession.contextValue = extension.FAVORITE_CONTEXT; this.mFavoriteSession.iconPath = applyIcons(this.mFavoriteSession); this.mSessionNodes = [this.mFavoriteSession]; - this.mHistory = new PersistentFilters(DatasetTree.persistenceSchema); + } + + /** + * Takes argument of type IZoweDatasetTreeNode and retrieves all of the first level children + * + * @param {IZoweDatasetTreeNode} [element] - Optional parameter; if not passed, returns root session nodes + * @returns {IZoweDatasetTreeNode[] | Promise} + */ + public async getChildren(element?: IZoweDatasetTreeNode | undefined): Promise { + if (element) { + if (element.contextValue === extension.FAVORITE_CONTEXT) { + return this.mFavorites; + } + return element.getChildren(); + } + return this.mSessionNodes; } /** @@ -135,59 +144,6 @@ export class DatasetTree implements IZoweTree { } } - /** - * Takes argument of type ZoweNode and returns it converted to a general [TreeItem] - * - * @param {ZoweNode} element - * @returns {vscode.TreeItem} - */ - public getTreeItem(element: ZoweNode): vscode.TreeItem { - return element; - } - - /** - * Takes argument of type ZoweNode and retrieves all of the first level children - * - * @param {ZoweNode} [element] - Optional parameter; if not passed, returns root session nodes - * @returns {ZoweNode[] | Promise} - */ - public getChildren(element?: ZoweNode): ZoweNode[] | Promise { - if (element) { - if (element.contextValue === extension.FAVORITE_CONTEXT) { - return this.mFavorites; - } - return element.getChildren(); - } - return this.mSessionNodes; - } - - /** - * Called whenever the tree needs to be refreshed, and fires the data change event - * - */ - public refresh(): void { - this.mOnDidChangeTreeData.fire(); - } - - /** - * Called whenever the tree needs to be refreshed, and fires the data change event - * - */ - public refreshElement(element: ZoweNode): void { - element.dirty = true; - this.mOnDidChangeTreeData.fire(element); - } - - /** - * Returns the parent node or null if it has no parent - * - * @param {ZoweNode} element - * @returns {vscode.ProviderResult} - */ - public getParent(element: ZoweNode): vscode.ProviderResult { - return element.mParent; - } - /** * Adds a new session to the data set tree * @@ -223,9 +179,9 @@ export class DatasetTree implements IZoweTree { /** * Removes a session from the list in the data set tree * - * @param {ZoweNode} [node] + * @param {IZoweDatasetTreeNode} [node] */ - public deleteSession(node: ZoweNode) { + public deleteSession(node: IZoweDatasetTreeNode) { this.mSessionNodes = this.mSessionNodes.filter((tempNode) => tempNode.label.trim() !== node.label.trim()); let revisedLabel = node.label; if (revisedLabel.includes("[")) { @@ -238,16 +194,16 @@ export class DatasetTree implements IZoweTree { /** * Adds a node to the favorites list * - * @param {ZoweNode} node + * @param {IZoweDatasetTreeNode} node */ - public async addFavorite(node: ZoweNode) { + public async addFavorite(node: IZoweDatasetTreeNode) { let temp: ZoweNode; if (node.contextValue === extension.DS_MEMBER_CONTEXT) { - if (node.mParent.contextValue === extension.DS_PDS_CONTEXT + extension.FAV_SUFFIX) { + if (node.getParent().contextValue === extension.DS_PDS_CONTEXT + extension.FAV_SUFFIX) { vscode.window.showInformationMessage(localize("addFavorite", "PDS already in favorites")); return; } - this.addFavorite(node.mParent); + this.addFavorite(node.getParent()); return; } else if (node.contextValue === extension.DS_SESSION_CONTEXT) { temp = new ZoweNode("[" + node.getSessionNode().label.trim() + "]: " + node.pattern, vscode.TreeItemCollapsibleState.None, @@ -298,9 +254,9 @@ export class DatasetTree implements IZoweTree { /** * Renames a node from the favorites list * - * @param {ZoweNode} node + * @param {IZoweDatasetTreeNode} node */ - public async renameFavorite(node: ZoweNode, newLabel: string) { + public async renameFavorite(node: IZoweDatasetTreeNode, newLabel: string) { const matchingNode = this.mFavorites.find( (temp) => (temp.label === node.label) && (temp.contextValue.startsWith(node.contextValue)) ); @@ -314,19 +270,19 @@ export class DatasetTree implements IZoweTree { /** * Finds the equivalent node as a favorite * - * @param {ZoweNode} node + * @param {IZoweDatasetTreeNode} node */ - public findFavoritedNode(node: ZoweNode) { + public findFavoritedNode(node: IZoweDatasetTreeNode) { return this.mFavorites.find( - (temp) => (temp.label === `[${node.mParent.label.trim()}]: ${node.label}`) && (temp.contextValue.includes(node.contextValue)) + (temp) => (temp.label === `[${node.getParent().getLabel()}]: ${node.label}`) && (temp.contextValue.includes(node.contextValue)) ); } /** * Finds the equivalent node not as a favorite * - * @param {ZoweNode} node + * @param {IZoweDatasetTreeNode} node */ - public findNonFavoritedNode(node: ZoweNode) { + public findNonFavoritedNode(node: IZoweDatasetTreeNode) { const profileLabel = node.label.substring(1, node.label.indexOf("]")); const nodeLabel = node.label.substring(node.label.indexOf(":") + 2); const sessionNode = this.mSessionNodes.find((session) => session.label.trim() === profileLabel); @@ -336,9 +292,9 @@ export class DatasetTree implements IZoweTree { /** * Removes a node from the favorites list * - * @param {ZoweNode} node + * @param {IZoweDatasetTreeNode} node */ - public async removeFavorite(node: ZoweNode) { + public async removeFavorite(node: IZoweDatasetTreeNode) { this.mFavorites = this.mFavorites.filter((temp) => !((temp.label === node.label) && (temp.contextValue.startsWith(node.contextValue))) ); @@ -354,23 +310,7 @@ export class DatasetTree implements IZoweTree { this.mHistory.updateFavorites(settings); } - public async onDidChangeConfiguration(e) { - if (e.affectsConfiguration(DatasetTree.persistenceSchema)) { - const setting: any = { ...vscode.workspace.getConfiguration().get(DatasetTree.persistenceSchema) }; - if (!setting.persistence) { - setting.favorites = []; - setting.history = []; - await vscode.workspace.getConfiguration().update(DatasetTree.persistenceSchema, setting, vscode.ConfigurationTarget.Global); - } - } - } - - public async addHistory(criteria: string) { - this.mHistory.addHistory(criteria); - this.refresh(); - } - - public async datasetFilterPrompt(node: ZoweNode) { + public async datasetFilterPrompt(node: IZoweDatasetTreeNode) { this.log.debug(localize("enterPattern.log.debug.prompt", "Prompting the user for a data set pattern")); let pattern: string; let usrNme: string; @@ -459,7 +399,7 @@ export class DatasetTree implements IZoweTree { } } else { // executing search from saved search in favorites - pattern = node.label.trim().substring(node.label.trim().indexOf(":") + 2); + pattern = node.label.trim().substring(node.getLabel().indexOf(":") + 2); const session = node.label.trim().substring(node.label.trim().indexOf("[") + 1, node.label.trim().indexOf("]")); await this.addSession(session); const faveNode = node; @@ -487,7 +427,7 @@ export class DatasetTree implements IZoweTree { * @param element the node being flipped * @param isOpen the intended state of the the tree view provider, true or false */ - public async flipState(element: ZoweNode, isOpen: boolean = false) { + public async flipState(element: IZoweDatasetTreeNode, isOpen: boolean = false) { if (element.label !== "Favorites") { let usrNme: string; let passWrd: string; diff --git a/src/USSTree.ts b/src/USSTree.ts index adb44fb695..da18d171b6 100644 --- a/src/USSTree.ts +++ b/src/USSTree.ts @@ -14,12 +14,12 @@ import * as zowe from "@brightside/core"; import { IProfileLoaded, Logger } from "@brightside/imperative"; import { applyIcons, FilterItem, FilterDescriptor, getAppName, resolveQuickPickHelper, sortTreeItems } from "./utils"; import * as vscode from "vscode"; -import { IZoweTree } from "./ZoweTree"; +import { IZoweTree, IZoweUSSTreeNode } from "./api/ZoweTree"; import { ZoweUSSNode } from "./ZoweUSSNode"; import { Profiles } from "./Profiles"; -import { PersistentFilters } from "./PersistentFilters"; import * as extension from "../src/extension"; import * as nls from "vscode-nls"; +import { ZoweTreeProvider } from "./abstract/ZoweTreeProvider"; const localize = nls.config({ messageFormat: nls.MessageFormat.file })(); /** @@ -41,49 +41,29 @@ export async function createUSSTree(log: Logger) { * @class USSTree * @implements {vscode.TreeDataProvider} */ -export class USSTree implements IZoweTree { +export class USSTree extends ZoweTreeProvider implements IZoweTree { + public static readonly defaultDialogText: string = "\uFF0B " + localize("ussFilterPrompt.option.prompt.search", "Create a new filter"); private static readonly persistenceSchema: string = "Zowe-USS-Persistent"; - public mSessionNodes: ZoweUSSNode[]; - public mFavoriteSession: ZoweUSSNode; - public mFavorites: ZoweUSSNode[] = []; - - // Event Emitters used to notify subscribers that the refresh event has fired - public mOnDidChangeTreeData: vscode.EventEmitter = new vscode.EventEmitter(); - public readonly onDidChangeTreeData: vscode.Event = this.mOnDidChangeTreeData.event; - - private mHistory: PersistentFilters; - private log: Logger; - private validProfile: number = -1; + public mSessionNodes: IZoweUSSTreeNode[] = []; + public mFavorites: IZoweUSSTreeNode[] = []; constructor() { - this.mSessionNodes = []; - this.mFavoriteSession = new ZoweUSSNode(localize("Favorites", "Favorites"), - vscode.TreeItemCollapsibleState.Collapsed, null, null, null); + super(USSTree.persistenceSchema, new ZoweUSSNode(localize("Favorites", "Favorites"), + vscode.TreeItemCollapsibleState.Collapsed, null, null, null)); this.mFavoriteSession.contextValue = extension.FAVORITE_CONTEXT; - this.mSessionNodes = [this.mFavoriteSession]; this.mFavoriteSession.iconPath = applyIcons(this.mFavoriteSession); - this.mHistory = new PersistentFilters(USSTree.persistenceSchema); - } - - /** - * Takes argument of type ZoweUSSNode and returns it converted to a general [TreeItem] - * - * @param {ZoweUSSNode} element - * @returns {vscode.TreeItem} - */ - public getTreeItem(element: ZoweUSSNode): vscode.TreeItem { - return element; + this.mSessionNodes = [this.mFavoriteSession]; } /** - * Takes argument of type ZoweUSSNode and retrieves all of the first level children + * Takes argument of type IZoweUSSTreeNode and retrieves all of the first level children * - * @param {ZoweUSSNode} [element] - Optional parameter; if not passed, returns root session nodes - * @returns {ZoweUSSNode[] | Promise} + * @param {IZoweUSSTreeNode} [element] - Optional parameter; if not passed, returns root session nodes + * @returns {IZoweUSSTreeNode[] | Promise} */ - public getChildren(element?: ZoweUSSNode): ZoweUSSNode[] | Promise { + public async getChildren(element?: IZoweUSSTreeNode | undefined): Promise { if (element) { if (element.contextValue === extension.FAVORITE_CONTEXT) { return this.mFavorites; @@ -93,33 +73,6 @@ export class USSTree implements IZoweTree { return this.mSessionNodes; } - /** - * Called whenever the tree needs to be refreshed, and fires the data change event - * - */ - public refresh(): void { - this.mOnDidChangeTreeData.fire(); - } - - /** - * Called whenever the tree needs to be refreshed, and fires the data change event - * - */ - public refreshElement(element: ZoweUSSNode): void { - element.dirty = true; - this.mOnDidChangeTreeData.fire(element); - } - - /** - * Returns the parent node or null if it has no parent - * - * @param {ZoweUSSNode} element - * @returns {vscode.ProviderResult} - */ - public getParent(element: ZoweUSSNode): vscode.ProviderResult { - return element.mParent; - } - /** * Adds a new session to the uss files tree * @@ -155,9 +108,9 @@ export class USSTree implements IZoweTree { /** * Removes a session from the list in the uss files tree * - * @param {ZoweUSSNode} [node] + * @param {IZoweUSSTreeNode} [node] */ - public deleteSession(node: ZoweUSSNode) { + public deleteSession(node: IZoweUSSTreeNode) { this.mSessionNodes = this.mSessionNodes.filter((tempNode) => tempNode.label.trim() !== node.label.trim()); let revisedLabel = node.label; if (revisedLabel.includes("[")) { @@ -170,17 +123,17 @@ export class USSTree implements IZoweTree { /** * Adds a node to the USS favorites list * - * @param {ZoweUSSNode} node + * @param {IZoweUSSTreeNode} node */ - public async addUSSFavorite(node: ZoweUSSNode) { + public async addFavorite(node: IZoweUSSTreeNode) { let temp: ZoweUSSNode; temp = new ZoweUSSNode(node.fullPath, node.collapsibleState, this.mFavoriteSession, node.getSession(), - node.mParent.fullPath, + node.getParent().fullPath, false, - node.getSessionNode().mProfileName); + node.getSessionNode().getProfileName()); temp.contextValue += extension.FAV_SUFFIX; if (temp.contextValue === extension.DS_TEXT_FILE_CONTEXT + extension.FAV_SUFFIX || temp.contextValue === extension.DS_BINARY_FILE_CONTEXT + extension.FAV_SUFFIX) { @@ -198,12 +151,12 @@ export class USSTree implements IZoweTree { /** * Adds a search node to the USS favorites list * - * @param {ZoweUSSNode} node + * @param {IZoweUSSTreeNode} node */ - public async addUSSSearchFavorite(node: ZoweUSSNode) { - const label = "[" + node.getSessionNode().mProfileName + "]: " + node.fullPath; + public async addUSSSearchFavorite(node: IZoweUSSTreeNode) { + const label = "[" + node.getSessionNode().getProfileName() + "]: " + node.fullPath; const temp = new ZoweUSSNode(label, vscode.TreeItemCollapsibleState.None, - this.mFavoriteSession, node.getSession(), null, false, node.getSessionNode().mProfileName); + this.mFavoriteSession, node.getSession(), null, false, node.getSessionNode().getProfileName()); temp.fullPath = node.fullPath; temp.label = temp.tooltip = label; @@ -221,9 +174,9 @@ export class USSTree implements IZoweTree { /** * Removes a node from the favorites list * - * @param {ZoweUSSNode} node + * @param {IZoweUSSTreeNode} node */ - public async removeUSSFavorite(node: ZoweUSSNode) { + public async removeFavorite(node: IZoweUSSTreeNode) { this.mFavorites = this.mFavorites.filter((temp) => !((temp.fullPath === node.fullPath) && (temp.contextValue.startsWith(node.contextValue)))); await this.updateFavorites(); @@ -234,81 +187,19 @@ export class USSTree implements IZoweTree { const settings: any = { ...vscode.workspace.getConfiguration().get(USSTree.persistenceSchema) }; if (settings.persistence) { settings.favorites = this.mFavorites.map((fav) => - (fav.fullPath.startsWith(fav.profileName) ? fav.fullPath : fav.profileName + fav.fullPath) + "{" + + (fav.fullPath.startsWith(fav.getProfileName()) ? fav.fullPath : fav.getProfileName() + fav.fullPath) + "{" + fav.contextValue.substring(0, fav.contextValue.indexOf(extension.FAV_SUFFIX)) + "}"); await vscode.workspace.getConfiguration().update(USSTree.persistenceSchema, settings, vscode.ConfigurationTarget.Global); } } - /** - * Change the state of an expandable node - * @param provider the tree view provider - * @param element the node being flipped - * @param isOpen the intended state of the the tree view provider, true or false - */ - public async flipState(element: ZoweUSSNode, isOpen: boolean = false) { - if (element.label !== "Favorites") { - let usrNme: string; - let passWrd: string; - let baseEncd: string; - if ((!element.getSession().ISession.user) || (!element.getSession().ISession.password)) { - try { - const values = await Profiles.getInstance().promptCredentials(element.mProfileName); - if (values !== undefined) { - usrNme = values [0]; - passWrd = values [1]; - baseEncd = values [2]; - } - } catch (error) { - vscode.window.showErrorMessage(error.message); - } - if (usrNme !== undefined && passWrd !== undefined && baseEncd !== undefined) { - element.getSession().ISession.user = usrNme; - element.getSession().ISession.password = passWrd; - element.getSession().ISession.base64EncodedAuth = baseEncd; - this.validProfile = 1; - } else { - return; - } - await this.refreshElement(element); - await this.refresh(); - } else { - this.validProfile = 1; - } - } else { - this.validProfile = 1; - } - if (this.validProfile === 1) { - element.iconPath = applyIcons(element, isOpen ? extension.ICON_STATE_OPEN : extension.ICON_STATE_CLOSED); - element.dirty = true; - this.mOnDidChangeTreeData.fire(element); - } - } - - public async onDidChangeConfiguration(e) { - if (e.affectsConfiguration(USSTree.persistenceSchema)) { - const setting: any = { ...vscode.workspace.getConfiguration().get(USSTree.persistenceSchema) }; - if (!setting.persistence) { - setting.favorites = []; - setting.history = []; - await vscode.workspace.getConfiguration().update(USSTree.persistenceSchema, - setting, vscode.ConfigurationTarget.Global); - } - } - } - - public async addHistory(criteria: string) { - this.mHistory.addHistory(criteria); - this.refresh(); - } - /** * Prompts the user for a path, and populates the [TreeView]{@link vscode.TreeView} based on the path * - * @param {ZoweUSSNode} node - The session node + * @param {IZoweUSSTreeNode} node - The session node * @returns {Promise} */ - public async ussFilterPrompt(node: ZoweUSSNode) { + public async ussFilterPrompt(node: IZoweUSSTreeNode) { if (this.log) { this.log.debug(localize("ussFilterPrompt.log.debug.promptUSSPath", "Prompting the user for a USS path")); } @@ -319,7 +210,7 @@ export class USSTree implements IZoweTree { let baseEncd: string; if ((!(node.getSession().ISession.user).trim()) || (!(node.getSession().ISession.password).trim())) { try { - const values = await Profiles.getInstance().promptCredentials(node.mProfileName); + const values = await Profiles.getInstance().promptCredentials(node.getProfileName()); if (values !== undefined) { usrNme = values [0]; passWrd = values [1]; @@ -400,7 +291,7 @@ export class USSTree implements IZoweTree { await this.addSession(session); const faveNode = node; sessionNode = this.mSessionNodes.find((tempNode) => - tempNode.mProfileName === session + tempNode.getProfileName() === session ); if ((!sessionNode.getSession().ISession.user) || (!sessionNode.getSession().ISession.password)) { sessionNode.getSession().ISession.user = faveNode.getSession().ISession.user; @@ -414,7 +305,7 @@ export class USSTree implements IZoweTree { sessionNode.collapsibleState = vscode.TreeItemCollapsibleState.Expanded; sessionNode.iconPath = applyIcons(sessionNode, extension.ICON_STATE_OPEN); // update the treeview with the new path - sessionNode.label = `${sessionNode.mProfileName} [${sanitizedPath}]`; + sessionNode.label = `${sessionNode.getProfileName()} [${sanitizedPath}]`; sessionNode.dirty = true; this.addHistory(sanitizedPath); } diff --git a/src/ZosJobsProvider.ts b/src/ZosJobsProvider.ts index 07e7bae755..a154fb86d0 100644 --- a/src/ZosJobsProvider.ts +++ b/src/ZosJobsProvider.ts @@ -10,11 +10,10 @@ */ import * as vscode from "vscode"; -import { ZosmfSession, IJob, DeleteJobs, Utilities } from "@brightside/core"; +import { ZosmfSession, IJob, DeleteJobs } from "@brightside/core"; import { IProfileLoaded, Logger } from "@brightside/imperative"; // tslint:disable-next-line: no-duplicate-imports import { Profiles } from "./Profiles"; -import { PersistentFilters } from "./PersistentFilters"; import { Job } from "./ZoweJobNode"; import { OwnerFilterDescriptor, @@ -24,9 +23,11 @@ import { FilterDescriptor, getAppName, resolveQuickPickHelper, - sortTreeItems + sortTreeItems, + labelHack } from "./utils"; -import { IZoweTree } from "./ZoweTree"; +import { IZoweTree, IZoweJobTreeNode } from "./api/ZoweTree"; +import { ZoweTreeProvider } from "./abstract/ZoweTreeProvider"; import * as extension from "../src/extension"; import * as nls from "vscode-nls"; const localize = nls.config({ messageFormat: nls.MessageFormat.file })(); @@ -46,36 +47,36 @@ export async function createJobsTree(log: Logger) { } // tslint:disable-next-line: max-classes-per-file -export class ZosJobsProvider implements IZoweTree { +export class ZosJobsProvider extends ZoweTreeProvider implements IZoweTree { + public static readonly JobId = "JobId:"; public static readonly Owner = "Owner:"; public static readonly Prefix = "Prefix:"; public static readonly defaultDialogText: string = localize("SpecifyCriteria", "Create new.."); private static readonly persistenceSchema: string = "Zowe-Jobs-Persistent"; - public mSessionNodes: Job[] = []; - public mFavoriteSession: Job; - public mFavorites: Job[] = []; - - // Event Emitters used to notify subscribers that the refresh event has fired - public mOnDidChangeTreeData: vscode.EventEmitter = new vscode.EventEmitter(); - public readonly onDidChangeTreeData: vscode.Event = this.mOnDidChangeTreeData.event; + public mSessionNodes: IZoweJobTreeNode[] = []; + public mFavorites: IZoweJobTreeNode[] = []; public createOwner = new OwnerFilterDescriptor(); public createId = new JobIdFilterDescriptor(); - private validProfile: number = -1; - private mHistory: PersistentFilters; - private log: Logger; - constructor() { - this.mFavoriteSession = new Job(localize("FavoriteSession", "Favorites"), vscode.TreeItemCollapsibleState.Collapsed, null, null, null); + super(ZosJobsProvider.persistenceSchema, + new Job(localize("Favorites", "Favorites"), vscode.TreeItemCollapsibleState.Collapsed, null, null, null)); + + this.mFavoriteSession = new Job(localize("Favorites", "Favorites"),vscode.TreeItemCollapsibleState.Collapsed, null, null, null); this.mFavoriteSession.contextValue = extension.FAVORITE_CONTEXT; this.mFavoriteSession.iconPath = applyIcons(this.mFavoriteSession); this.mSessionNodes = [this.mFavoriteSession]; - this.mHistory = new PersistentFilters(ZosJobsProvider.persistenceSchema); } - public getChildren(element?: Job | undefined): vscode.ProviderResult { + /** + * Takes argument of type IZoweJobTreeNode and retrieves all of the first level children + * + * @param {IZoweJobTreeNode} [element] - Optional parameter; if not passed, returns root session nodes + * @returns {IZoweJobTreeNode[] | Promise} + */ + public async getChildren(element?: IZoweJobTreeNode | undefined): Promise { if (element) { // solution for optional credentials. Owner is having error on initialization. if (element.owner === "") { @@ -89,13 +90,6 @@ export class ZosJobsProvider implements IZoweTree { return this.mSessionNodes; } - public getTreeItem(element: Job): vscode.TreeItem | Thenable { - return element; - } - public getParent(element: Job): Job { - return element.mParent; - } - /** * Adds a session to the data set tree * @@ -128,104 +122,16 @@ export class ZosJobsProvider implements IZoweTree { this.refresh(); } - public deleteSession(node: Job) { - this.mSessionNodes = this.mSessionNodes.filter((tempNode) => tempNode.label.trim() !== node.label.trim()); - let revisedLabel = node.label; - if (revisedLabel.includes("[")) { - revisedLabel = revisedLabel.substring(0, revisedLabel.indexOf(" [")); - } - this.mHistory.removeSession(revisedLabel); - this.refresh(); - } - - public async deleteJob(node: Job) { + public async deleteJob(node: IZoweJobTreeNode) { try { - await DeleteJobs.deleteJob(node.session, node.job.jobname, node.job.jobid); + await DeleteJobs.deleteJob(node.getSession(), node.job.jobname, node.job.jobid); vscode.window.showInformationMessage(localize("deleteJob.job", "Job ") + node.job.jobname + "(" + node.job.jobid + ")" + localize("deleteJob.delete", " deleted")); - this.removeJobsFavorite(this.createJobsFavorite(node)); + this.removeFavorite(this.createJobsFavorite(node)); } catch (error) { vscode.window.showErrorMessage(error.message); } } - /** - * Selects a specific job in the Jobs view - * - * @param {Job} - */ - public setJob(treeView: vscode.TreeView, job: Job) { - treeView.reveal(job, { select: true, focus: true }); - } - - - /** - * Called whenever the tree needs to be refreshed, and fires the data change event - * - */ - public refreshElement(element: Job): void { - element.dirty = true; - this.mOnDidChangeTreeData.fire(element); - } - - /** - * Called whenever the tree needs to be refreshed, and fires the data change event - * - */ - public refresh(): void { - this.mOnDidChangeTreeData.fire(); - } - - /** - * Change the state of an expandable node - * @param provider the tree view provider - * @param element the node being flipped - * @param isOpen the intended state of the the tree view provider, true or false - */ - public async flipState(element: Job, isOpen: boolean = false) { - if (element.label !== "Favorites") { - let usrNme: string; - let passWrd: string; - let baseEncd: string; - let sesNamePrompt: string; - if (element.contextValue.endsWith(extension.FAV_SUFFIX)) { - sesNamePrompt = element.label.substring(1, element.label.indexOf("]")); - } else { - sesNamePrompt = element.label; - } - if ((!element.session.ISession.user) || (!element.session.ISession.password)) { - try { - const values = await Profiles.getInstance().promptCredentials(sesNamePrompt); - if (values !== undefined) { - usrNme = values [0]; - passWrd = values [1]; - baseEncd = values [2]; - } - } catch (error) { - vscode.window.showErrorMessage(error.message); - } - if (usrNme !== undefined && passWrd !== undefined && baseEncd !== undefined) { - element.session.ISession.user = usrNme; - element.session.ISession.password = passWrd; - element.session.ISession.base64EncodedAuth = baseEncd; - element.owner = usrNme; - this.validProfile = 1; - } else { - return; - } - await this.refreshElement(element); - await this.refresh(); - } else { - this.validProfile = 1; - } - } else { - this.validProfile = 1; - } - if (this.validProfile === 1) { - element.iconPath = applyIcons(element, isOpen ? extension.ICON_STATE_OPEN : extension.ICON_STATE_CLOSED); - element.dirty = true; - this.mOnDidChangeTreeData.fire(element); - } - } /** * Initialize the favorites and history information @@ -277,9 +183,9 @@ export class ZosJobsProvider implements IZoweTree { /** * Adds a node to the Jobs favorites list * - * @param {Job} node + * @param {IZoweJobTreeNode} node */ - public async addJobsFavorite(node: Job) { + public async addFavorite(node: IZoweJobTreeNode) { const favJob = this.createJobsFavorite(node); if (!this.mFavorites.find((tempNode) => tempNode.label === favJob.label)) { this.mFavorites.push(favJob); @@ -292,13 +198,13 @@ export class ZosJobsProvider implements IZoweTree { /** * Adds a save search to the Jobs favorites list * - * @param {Job} node + * @param {IZoweJobTreeNode} node */ - public async saveSearch(node: Job) { + public async saveSearch(node: IZoweJobTreeNode) { const favSessionContext = extension.JOBS_SESSION_CONTEXT + extension.FAV_SUFFIX; - const favJob = new Job("[" + node.getSessionName() + "]: " + + const favJob = new Job("[" + node.getProfileName() + "]: " + this.createSearchLabel(node.owner, node.prefix, node.searchId), - vscode.TreeItemCollapsibleState.None, node.mParent, node.session, node.job); + vscode.TreeItemCollapsibleState.None, node.getParent(), node.getSession(), node.job); favJob.owner = node.owner; favJob.prefix = node.prefix; favJob.searchId = node.searchId; @@ -315,9 +221,9 @@ export class ZosJobsProvider implements IZoweTree { /** * Removes a node from the favorites list * - * @param {Job} node + * @param {IZoweJobTreeNode} node */ - public async removeJobsFavorite(node: Job) { + public async removeFavorite(node: IZoweJobTreeNode) { const startLength = this.mFavorites.length; this.mFavorites = this.mFavorites.filter((temp) => !((temp.label === node.label) && (temp.contextValue.startsWith(node.contextValue)))); @@ -338,13 +244,66 @@ export class ZosJobsProvider implements IZoweTree { } } + /** + * Change the state of an expandable node + * @param provider the tree view provider + * @param element the node being flipped + * @param isOpen the intended state of the the tree view provider, true or false + * N.B. Specific implementation for Jobs as owner field set. + */ + public async flipState(element: IZoweJobTreeNode, isOpen: boolean = false) { + if (element.label !== "Favorites") { + let usrNme: string; + let passWrd: string; + let baseEncd: string; + let sesNamePrompt: string; + if (element.contextValue.endsWith(extension.FAV_SUFFIX)) { + sesNamePrompt = element.label.substring(1, element.label.indexOf("]")); + } else { + sesNamePrompt = element.label; + } + if ((!element.getSession().ISession.user) || (!element.getSession().ISession.password)) { + try { + const values = await Profiles.getInstance().promptCredentials(sesNamePrompt); + if (values !== undefined) { + usrNme = values [0]; + passWrd = values [1]; + baseEncd = values [2]; + } + } catch (error) { + vscode.window.showErrorMessage(error.message); + } + if (usrNme !== undefined && passWrd !== undefined && baseEncd !== undefined) { + element.getSession().ISession.user = usrNme; + element.getSession().ISession.password = passWrd; + element.getSession().ISession.base64EncodedAuth = baseEncd; + element.owner = usrNme; + this.validProfile = 1; + } else { + return; + } + await this.refreshElement(element); + await this.refresh(); + } else { + this.validProfile = 1; + } + } else { + this.validProfile = 1; + } + if (this.validProfile === 1) { + element.iconPath = applyIcons(element, isOpen ? extension.ICON_STATE_OPEN : extension.ICON_STATE_CLOSED); + element.dirty = true; + this.mOnDidChangeTreeData.fire(element); + } + } + /** * Prompts the user for search details to populate the [TreeView]{@link vscode.TreeView} * - * @param {Job} node - The session node + * @param {IZoweJobTreeNode} node - The session node * @returns {Promise} */ - public async searchPrompt(node: Job) { + public async searchPrompt(node: IZoweJobTreeNode) { let choice: vscode.QuickPickItem; let searchCriteria: string = ""; const hasHistory = this.mHistory.getHistory().length > 0; @@ -357,7 +316,7 @@ export class ZosJobsProvider implements IZoweTree { } else { sesNamePrompt = node.label; } - if ((!node.session.ISession.user) || (!node.session.ISession.password)) { + if ((!node.getSession().ISession.user) || (!node.getSession().ISession.password)) { try { const values = await Profiles.getInstance().promptCredentials(sesNamePrompt); if (values !== undefined) { @@ -369,9 +328,9 @@ export class ZosJobsProvider implements IZoweTree { vscode.window.showErrorMessage(error.message); } if (usrNme !== undefined && passWrd !== undefined && baseEncd !== undefined) { - node.session.ISession.user = usrNme; - node.session.ISession.password = passWrd; - node.session.ISession.base64EncodedAuth = baseEncd; + node.getSession().ISession.user = usrNme; + node.getSession().ISession.password = passWrd; + node.getSession().ISession.base64EncodedAuth = baseEncd; node.owner = usrNme; this.validProfile = 0; } else { @@ -489,37 +448,23 @@ export class ZosJobsProvider implements IZoweTree { const faveNode = node; await this.addSession(session); node = this.mSessionNodes.find((tempNode) => tempNode.label.trim() === session); - if ((!node.session.ISession.user) || (!node.session.ISession.password)) { - node.session.ISession.user = faveNode.session.ISession.user; - node.session.ISession.password = faveNode.session.ISession.password; - node.session.ISession.base64EncodedAuth = faveNode.session.ISession.base64EncodedAuth; + if ((!node.getSession().ISession.user) || (!node.getSession().ISession.password)) { + node.getSession().ISession.user = faveNode.getSession().ISession.user; + node.getSession().ISession.password = faveNode.getSession().ISession.password; + node.getSession().ISession.base64EncodedAuth = faveNode.getSession().ISession.base64EncodedAuth; } this.applySearchLabelToNode(node, searchCriteria); } - this.addHistory(searchCriteria); - - node.collapsibleState = vscode.TreeItemCollapsibleState.Expanded; - node.iconPath = applyIcons(node.getSessionNode(), extension.ICON_STATE_OPEN); + node.label = node.label.trim()+ " "; + node.label.trim(); node.dirty = true; - this.refreshElement(node); - } - } - - public async onDidChangeConfiguration(e: vscode.ConfigurationChangeEvent) { - if (e.affectsConfiguration(ZosJobsProvider.persistenceSchema)) { - const setting: any = { ...vscode.workspace.getConfiguration().get(ZosJobsProvider.persistenceSchema) }; - if (!setting.persistence) { - setting.favorites = []; - setting.history = []; - await vscode.workspace.getConfiguration().update(ZosJobsProvider.persistenceSchema, setting, vscode.ConfigurationTarget.Global); - } + this.addHistory(searchCriteria); } } - public async addHistory(criteria: string) { - if (criteria) { - this.mHistory.addHistory(criteria); - } + public deleteSession(node: IZoweJobTreeNode) { + this.mSessionNodes = this.mSessionNodes.filter((tempNode) => tempNode.label.trim() !== node.label.trim()); + this.deleteSessionByLabel(node.getLabel()); } /** @@ -581,12 +526,13 @@ export class ZosJobsProvider implements IZoweTree { } return this.createSearchLabel(owner, prefix, jobId); } + /** * Function that takes a search criteria and updates a search node based upon it - * @param node - a Job node + * @param node - a IZoweJobTreeNode node * @param storedSearch - The original search string */ - private applySearchLabelToNode(node: Job, storedSearch: string) { + private applySearchLabelToNode(node: IZoweJobTreeNode, storedSearch: string) { if (storedSearch) { node.searchId = ""; node.owner = "*"; @@ -612,10 +558,10 @@ export class ZosJobsProvider implements IZoweTree { } } - private createJobsFavorite(node: Job) { - const favJob = new Job("[" + node.getSessionName() + "]: " + + private createJobsFavorite(node: IZoweJobTreeNode): IZoweJobTreeNode { + const favJob = new Job("[" + node.getSessionNode().label + "]: " + node.label.substring(0, node.label.lastIndexOf(")") + 1), - vscode.TreeItemCollapsibleState.Collapsed, node.mParent, node.session, node.job); + vscode.TreeItemCollapsibleState.Collapsed, node.getParent(), node.getSession(), node.job); favJob.contextValue = extension.JOBS_JOB_CONTEXT + extension.FAV_SUFFIX; favJob.command = { command: "zowe.zosJobsSelectjob", title: "", arguments: [favJob] }; favJob.iconPath = applyIcons(favJob); diff --git a/src/ZoweJobNode.ts b/src/ZoweJobNode.ts index a7601c62d2..f81c888098 100644 --- a/src/ZoweJobNode.ts +++ b/src/ZoweJobNode.ts @@ -11,21 +11,22 @@ import * as vscode from "vscode"; import * as zowe from "@brightside/core"; -import { Session, IProfileLoaded, Logger } from "@brightside/imperative"; +import { Session } from "@brightside/imperative"; // tslint:disable-next-line: no-duplicate-imports import { IJob, IJobFile } from "@brightside/core"; import * as extension from "./extension"; -import { IZoweTreeNode } from "./ZoweTree"; +import { IZoweJobTreeNode } from "./api/ZoweTree"; +import { ZoweTreeNode } from "./abstract/ZoweTreeNode"; import * as utils from "./utils"; // tslint:disable-next-line: max-classes-per-file -export class Job extends vscode.TreeItem implements IZoweTreeNode { +export class Job extends ZoweTreeNode implements IZoweJobTreeNode { public static readonly JobId = "JobId:"; public static readonly Owner = "Owner:"; public static readonly Prefix = "Prefix:"; + public children: IZoweJobTreeNode[] = []; public dirty = extension.ISTHEIA; // Make sure this is true for theia instances - private children: Job[] = []; // tslint:disable-next-line: variable-name private _owner: string; // tslint:disable-next-line: variable-name @@ -33,9 +34,12 @@ export class Job extends vscode.TreeItem implements IZoweTreeNode { // tslint:disable-next-line: variable-name private _searchId: string; - constructor(public label: string, public mCollapsibleState: vscode.TreeItemCollapsibleState, - public mParent: Job, public session: Session, public job: IJob) { - super(label, mCollapsibleState); + constructor(label: string, + collapsibleState: vscode.TreeItemCollapsibleState, + mParent: IZoweJobTreeNode, + session: Session, + public job: IJob) { + super(label, collapsibleState, mParent, session); if (session) { this._owner = session.ISession.user; } @@ -46,27 +50,19 @@ export class Job extends vscode.TreeItem implements IZoweTreeNode { /** * Implements access to profile name - * for {IZoweTreeNode}. * * @returns {string} */ public getProfileName(): string { - return this.label.trim(); + return this.getLabel(); } - public getSessionName(): string { - return this.getSessionNode().label.trim(); - } - - public getSessionNode(): Job { - if(this.mParent == null) { - return this; - } else { - return this.mParent; - } - } - - public async getChildren(): Promise { + /** + * Retrieves child nodes of this IZoweJobTreeNode + * + * @returns {Promise} + */ + public async getChildren(): Promise { if (this.dirty) { const elementChildren = []; let spools: zowe.IJobFile[] = []; @@ -83,7 +79,7 @@ export class Job extends vscode.TreeItem implements IZoweTreeNode { } const sessionName = this.contextValue === extension.JOBS_JOB_CONTEXT + extension.FAV_SUFFIX ? this.label.substring(1, this.label.lastIndexOf("]")).trim() : - this.getSessionName(); + this.getProfileName(); const spoolNode = new Spool(`${spool.stepname}:${spool.ddname}(${spool.id})`, vscode.TreeItemCollapsibleState.None, this, this.session, spool, this.job, this); spoolNode.iconPath = utils.applyIcons(spoolNode); @@ -136,6 +132,14 @@ export class Job extends vscode.TreeItem implements IZoweTreeNode { this.dirty = true; } + // tslint:disable-next-line: no-empty + public rename(newNamePath: string) { + } + + public getSessionNode(): IZoweJobTreeNode { + return this.getParent() ? this.getParent().getSessionNode() : this; + } + get tooltip(): string { if (this.job !== null) { if (this.job.retcode) { @@ -178,21 +182,21 @@ export class Job extends vscode.TreeItem implements IZoweTreeNode { return this._prefix; } - set searchId(newId: string) { + public set searchId(newId: string) { if (newId !== undefined) { this._searchId = newId; } } - get searchId() { + public get searchId() { return this._searchId; } } // tslint:disable-next-line: max-classes-per-file class Spool extends Job { - constructor(public label: string, public mCollapsibleState: vscode.TreeItemCollapsibleState, public mParent: Job, - public session: Session, public spool: IJobFile, public job: IJob, public parent: Job) { + constructor(label: string, mCollapsibleState: vscode.TreeItemCollapsibleState, mParent: IZoweJobTreeNode, + session: Session, spool: IJobFile, job: IJob, parent: IZoweJobTreeNode) { super(label, mCollapsibleState, mParent, session, job); this.contextValue = extension.JOBS_SPOOL_CONTEXT; utils.applyIcons(this); diff --git a/src/ZoweNode.ts b/src/ZoweNode.ts index 84db261e28..8248e50b95 100644 --- a/src/ZoweNode.ts +++ b/src/ZoweNode.ts @@ -15,7 +15,8 @@ import { Session } from "@brightside/imperative"; import * as nls from "vscode-nls"; import * as utils from "./utils"; import * as extension from "../src/extension"; -import { IZoweTreeNode } from "./ZoweTree"; +import { IZoweDatasetTreeNode } from "./api/ZoweTree"; +import { ZoweTreeNode } from "./abstract/ZoweTreeNode"; const localize = nls.config({ messageFormat: nls.MessageFormat.file })(); /** @@ -25,7 +26,7 @@ const localize = nls.config({ messageFormat: nls.MessageFormat.file })(); * @class ZoweNode * @extends {vscode.TreeItem} */ -export class ZoweNode extends vscode.TreeItem implements IZoweTreeNode { +export class ZoweNode extends ZoweTreeNode implements IZoweDatasetTreeNode { public command: vscode.Command; public pattern = ""; public dirty = extension.ISTHEIA; // Make sure this is true for theia instances @@ -41,28 +42,27 @@ export class ZoweNode extends vscode.TreeItem implements IZoweTreeNode { */ constructor(label: string, collapsibleState: vscode.TreeItemCollapsibleState, - public mParent: ZoweNode, - private session: Session, + mParent: IZoweDatasetTreeNode, + session: Session, contextOverride?: string, private etag?: string) { - super(label, collapsibleState); + super(label, collapsibleState, mParent, session); if (contextOverride) { this.contextValue = contextOverride; } else if (collapsibleState !== vscode.TreeItemCollapsibleState.None) { this.contextValue = extension.DS_PDS_CONTEXT; - } else if (mParent && mParent.mParent !== null) { + } else if (mParent && mParent.getParent()) { this.contextValue = extension.DS_MEMBER_CONTEXT; } else { this.contextValue = extension.DS_DS_CONTEXT; } this.tooltip = this.label; - this.etag = etag ? etag : ""; utils.applyIcons(this); } /** * Implements access to profile name - * for {IZoweTreeNode}. + * for {IZoweDatasetTreeNode}. * * @returns {string} */ @@ -163,24 +163,9 @@ export class ZoweNode extends vscode.TreeItem implements IZoweTreeNode { } } - /** - * Returns the [Session] for this node - * - * @returns {Session} - */ - public getSession(): Session { - return this.session || this.mParent.getSession(); + public getSessionNode(): IZoweDatasetTreeNode { + return this.getParent() ? this.getParent().getSessionNode() : this; } - - /** - * Returns the session node for this node - * - * @returns {ZoweNode} - */ - public getSessionNode(): ZoweNode { - return this.session ? this : this.mParent.getSessionNode(); - } - /** * Returns the [etag] for this node * diff --git a/src/ZoweTree.ts b/src/ZoweTree.ts deleted file mode 100644 index e1e1c1a4ed..0000000000 --- a/src/ZoweTree.ts +++ /dev/null @@ -1,42 +0,0 @@ -/* -* This program and the accompanying materials are made available under the terms of the * -* Eclipse Public License v2.0 which accompanies this distribution, and is available at * -* https://www.eclipse.org/legal/epl-v20.html * -* * -* SPDX-License-Identifier: EPL-2.0 * -* * -* Copyright Contributors to the Zowe Project. * -* * -*/ - -// TODO: Evolve these interfaces for additional refactoring of the commonalities of -// the three tree views. Consider adding also abstract base classes as well. - -import * as vscode from "vscode"; - -/** - * The base interface for Zowe tree brosers that implement the - * vscode.TreeDataProvider. - * - * @export - * @interface IZoweTree - * @extends {vscode.TreeDataProvider} - * @template T provide a subtype of vscode.TreeItem - */ -export interface IZoweTree extends vscode.TreeDataProvider { - mSessionNodes: T[]; - mFavoriteSession: T; - mFavorites: T[]; - - addSession(sessionName?: string): Promise; - refresh(): void; -} -/** - * The base interface for Zowe tree nodes. - * - * @export - * @interface IZoweTreeNode - */ -export interface IZoweTreeNode { - getProfileName(): string; -} diff --git a/src/ZoweUSSNode.ts b/src/ZoweUSSNode.ts index ce9b087d5e..7bdb5e0915 100644 --- a/src/ZoweUSSNode.ts +++ b/src/ZoweUSSNode.ts @@ -13,10 +13,11 @@ import * as zowe from "@brightside/core"; import { Session } from "@brightside/imperative"; import * as vscode from "vscode"; import * as nls from "vscode-nls"; -import { IZoweTreeNode } from "./ZoweTree"; +import { IZoweUSSTreeNode } from "./api/ZoweTree"; const localize = nls.config({ messageFormat: nls.MessageFormat.file })(); import * as extension from "../src/extension"; import * as utils from "./utils"; +import { ZoweTreeNode } from "./abstract/ZoweTreeNode"; /** * A type of TreeItem used to represent sessions and USS directories and files @@ -25,12 +26,13 @@ import * as utils from "./utils"; * @class ZoweUSSNode * @extends {vscode.TreeItem} */ -export class ZoweUSSNode extends vscode.TreeItem implements IZoweTreeNode { +export class ZoweUSSNode extends ZoweTreeNode implements IZoweUSSTreeNode { public command: vscode.Command; public fullPath = ""; public dirty = extension.ISTHEIA; // Make sure this is true for theia instances - public children: ZoweUSSNode[] = []; + public children: IZoweUSSTreeNode[] = []; public binaryFiles = {}; + public binary = false; public profileName = ""; public shortLabel = ""; @@ -39,20 +41,22 @@ export class ZoweUSSNode extends vscode.TreeItem implements IZoweTreeNode { * * @param {string} label - Displayed in the [TreeView] * @param {vscode.TreeItemCollapsibleState} collapsibleState - file/directory - * @param {ZoweUSSNode} mParent - The parent node + * @param {IZoweUSSTreeNode} mParent - The parent node * @param {Session} session * @param {String} parentPath - The file path of the parent on the server + * @param {boolean} binary - Indictaes if this is a text or binary file * @param {String} mProfileName - Profile to which the node belongs to */ constructor(label: string, collapsibleState: vscode.TreeItemCollapsibleState, - public mParent: ZoweUSSNode, - private session: Session, + mParent: IZoweUSSTreeNode, + session: Session, private parentPath: string, - public binary = false, + binary = false, public mProfileName?: string, - private etag?: string) { - super(label, collapsibleState); + private etag: string = "") { + super(label, collapsibleState, mParent, session); + this.binary = binary; if (collapsibleState !== vscode.TreeItemCollapsibleState.None) { this.contextValue = extension.USS_DIR_CONTEXT; } else if (binary) { @@ -67,7 +71,7 @@ export class ZoweUSSNode extends vscode.TreeItem implements IZoweTreeNode { this.fullPath = this.tooltip = "/" + label; } } - if (this.mParent && this.mParent.contextValue === extension.FAVORITE_CONTEXT) { + if (mParent && mParent.contextValue === extension.FAVORITE_CONTEXT) { this.profileName = "[" + mProfileName + "]: "; this.fullPath = label.trim(); // File or directory name only (no parent path) @@ -76,7 +80,6 @@ export class ZoweUSSNode extends vscode.TreeItem implements IZoweTreeNode { this.label = this.profileName + this.shortLabel; this.tooltip = this.profileName + this.fullPath; } - this.etag = etag ? etag : ""; utils.applyIcons(this); } @@ -90,12 +93,16 @@ export class ZoweUSSNode extends vscode.TreeItem implements IZoweTreeNode { return this.mProfileName; } + public getSessionNode(): IZoweUSSTreeNode { + return this.session ? this : this.getParent().getSessionNode(); + } + /** - * Retrieves child nodes of this ZoweUSSNode + * Retrieves child nodes of this IZoweTreeNode * - * @returns {Promise} + * @returns {Promise} */ - public async getChildren(): Promise { + public async getChildren(): Promise { if ((!this.fullPath && this.contextValue === extension.USS_SESSION_CONTEXT) || (this.contextValue === extension.DS_TEXT_FILE_CONTEXT || this.contextValue === extension.DS_BINARY_FILE_CONTEXT + extension.FAV_SUFFIX)) { @@ -184,24 +191,6 @@ export class ZoweUSSNode extends vscode.TreeItem implements IZoweTreeNode { return this.children = Object.keys(elementChildren).sort().map((labels) => elementChildren[labels]); } - /** - * Returns the [Session] for this node - * - * @returns {Session} - */ - public getSession(): Session { - return this.session || this.mParent.getSession(); - } - - /** - * Returns the session node for this node - * - * @returns {ZoweUSSNode} - */ - public getSessionNode(): ZoweUSSNode { - return this.session ? this : this.mParent.getSessionNode(); - } - public setBinary(binary: boolean) { this.binary = binary; if(this.binary){ @@ -211,7 +200,7 @@ export class ZoweUSSNode extends vscode.TreeItem implements IZoweTreeNode { this.contextValue = extension.DS_TEXT_FILE_CONTEXT; delete this.getSessionNode().binaryFiles[this.fullPath]; } - if (this.mParent && this.mParent.contextValue === extension.FAVORITE_CONTEXT) { + if (this.getParent() && this.getParent().contextValue === extension.FAVORITE_CONTEXT) { this.binary ? this.contextValue = extension.DS_BINARY_FILE_CONTEXT + extension.FAV_SUFFIX : this.contextValue = extension.DS_TEXT_FILE_CONTEXT + extension.FAV_SUFFIX; } @@ -247,10 +236,5 @@ export class ZoweUSSNode extends vscode.TreeItem implements IZoweTreeNode { */ public setEtag(etagValue): void { this.etag = etagValue; - /** - * helper method to change the node names in one go - * @param oldReference string - * @param revision string - */ } } diff --git a/src/abstract/ZoweTreeNode.ts b/src/abstract/ZoweTreeNode.ts new file mode 100644 index 0000000000..1a714a4b96 --- /dev/null +++ b/src/abstract/ZoweTreeNode.ts @@ -0,0 +1,75 @@ +/* +* This program and the accompanying materials are made available under the terms of the * +* Eclipse Public License v2.0 which accompanies this distribution, and is available at * +* https://www.eclipse.org/legal/epl-v20.html * +* * +* SPDX-License-Identifier: EPL-2.0 * +* * +* Copyright Contributors to the Zowe Project. * +* * +*/ + +import * as vscode from "vscode"; +import { Session } from "@brightside/imperative"; +import { IZoweTreeNode } from "../api/ZoweTree"; +// import * as extension from "../extension"; + +/** + * Common implementation of functions and methods associated with the + * IZoweTreeNode + * + * @export + * @class ZoweNode + * @extends {vscode.TreeItem} + */ +export class ZoweTreeNode extends vscode.TreeItem { + public command: vscode.Command; + public fullPath = ""; + public dirty = false; + public children: IZoweTreeNode[] = []; + public binaryFiles = {}; + public binary = false; + public shortLabel = ""; + + /** + * Creates an instance of ZoweNode + * + * @param {string} label - Displayed in the [TreeView] + * @param {vscode.TreeItemCollapsibleState} mCollapsibleState - file/folder + * @param {IZoweTreeNode} mParent + * @param {Session} session + * @param {string} etag + */ + constructor(label: string, + collapsibleState: vscode.TreeItemCollapsibleState, + private mParent: IZoweTreeNode, + protected session: Session) { + super(label, collapsibleState); + } + + /** + * Retrieves parent node of this IZoweTreeNode + * + * @returns {Promise} + */ + public getParent(): IZoweTreeNode { + return this.mParent; + } + + /** + * Returns the [Session] for this node + * + * @returns {Session} + */ + public getSession(): Session { + return this.session || (this.getParent() ? this.getParent().getSession(): undefined); + } + + /** + * This is the default was that the label should be accessed as it + * automatically trims the value + */ + public getLabel(): string { + return this.label.trim(); + } +} diff --git a/src/abstract/ZoweTreeProvider.ts b/src/abstract/ZoweTreeProvider.ts new file mode 100644 index 0000000000..6910127141 --- /dev/null +++ b/src/abstract/ZoweTreeProvider.ts @@ -0,0 +1,153 @@ +/* +* This program and the accompanying materials are made available under the terms of the * +* Eclipse Public License v2.0 which accompanies this distribution, and is available at * +* https://www.eclipse.org/legal/epl-v20.html * +* * +* SPDX-License-Identifier: EPL-2.0 * +* * +* Copyright Contributors to the Zowe Project. * +* * +*/ + +import * as vscode from "vscode"; +import { Logger } from "@brightside/imperative"; +// tslint:disable-next-line: no-duplicate-imports +import { Profiles } from "../Profiles"; +import { PersistentFilters } from "../PersistentFilters"; +import { OwnerFilterDescriptor, applyIcons } from "../utils"; +import { IZoweTreeNode } from "../api/ZoweTree"; +import * as extension from "../extension"; + +// tslint:disable-next-line: max-classes-per-file +export class ZoweTreeProvider { + + // Event Emitters used to notify subscribers that the refresh event has fired + public mOnDidChangeTreeData: vscode.EventEmitter = new vscode.EventEmitter(); + public readonly onDidChangeTreeData: vscode.Event = this.mOnDidChangeTreeData.event; + public createOwner = new OwnerFilterDescriptor(); + + protected mHistory: PersistentFilters; + protected log: Logger; + protected validProfile: number = -1; + + constructor(protected persistenceSchema: string, public mFavoriteSession: IZoweTreeNode) { + this.mHistory = new PersistentFilters(this.persistenceSchema); + } + + /** + * Takes argument of type IZoweTreeNode and returns it converted to a general [TreeItem] + * + * @param {IZoweTreeNode} element + * @returns {vscode.TreeItem} + */ + public getTreeItem(element: IZoweTreeNode): vscode.TreeItem | Thenable { + return element; + } + + public getParent(element: IZoweTreeNode): IZoweTreeNode { + return element.getParent(); + } + + /** + * Selects a specific item in the tree view + * + * @param {IZoweTreeNode} + */ + public setItem(treeView: vscode.TreeView, item: IZoweTreeNode) { + treeView.reveal(item, { select: true, focus: true }); + } + + /** + * Called whenever the tree needs to be refreshed, and fires the data change event + * + */ + public refreshElement(element: IZoweTreeNode): void { + element.dirty = true; + this.mOnDidChangeTreeData.fire(element); + } + + /** + * Called whenever the tree needs to be refreshed, and fires the data change event + * + */ + public refresh(): void { + this.mOnDidChangeTreeData.fire(); + } + + /** + * Change the state of an expandable node + * @param provider the tree view provider + * @param element the node being flipped + * @param isOpen the intended state of the the tree view provider, true or false + */ + public async flipState(element: IZoweTreeNode, isOpen: boolean = false) { + if (element.label !== "Favorites") { + let usrNme: string; + let passWrd: string; + let baseEncd: string; + let sesNamePrompt: string; + if (element.contextValue.endsWith(extension.FAV_SUFFIX)) { + sesNamePrompt = element.label.substring(1, element.label.indexOf("]")); + } else { + sesNamePrompt = element.label; + } + if ((!element.getSession().ISession.user) || (!element.getSession().ISession.password)) { + try { + const values = await Profiles.getInstance().promptCredentials(sesNamePrompt); + if (values !== undefined) { + usrNme = values [0]; + passWrd = values [1]; + baseEncd = values [2]; + } + } catch (error) { + vscode.window.showErrorMessage(error.message); + } + if (usrNme !== undefined && passWrd !== undefined && baseEncd !== undefined) { + element.getSession().ISession.user = usrNme; + element.getSession().ISession.password = passWrd; + element.getSession().ISession.base64EncodedAuth = baseEncd; + this.validProfile = 1; + } else { + return; + } + await this.refreshElement(element); + await this.refresh(); + } else { + this.validProfile = 1; + } + } else { + this.validProfile = 1; + } + if (this.validProfile === 1) { + element.iconPath = applyIcons(element, isOpen ? extension.ICON_STATE_OPEN : extension.ICON_STATE_CLOSED); + element.dirty = true; + this.mOnDidChangeTreeData.fire(element); + } + } + + public async onDidChangeConfiguration(e: vscode.ConfigurationChangeEvent) { + if (e.affectsConfiguration(this.persistenceSchema)) { + const setting: any = { ...vscode.workspace.getConfiguration().get(this.persistenceSchema) }; + if (!setting.persistence) { + setting.favorites = []; + setting.history = []; + await vscode.workspace.getConfiguration().update(this.persistenceSchema, setting, vscode.ConfigurationTarget.Global); + } + } + } + + public async addHistory(criteria: string) { + if (criteria) { + this.mHistory.addHistory(criteria); + this.refresh(); + } + } + + protected deleteSessionByLabel(revisedLabel: string) { + if (revisedLabel.includes("[")) { + revisedLabel = revisedLabel.substring(0, revisedLabel.indexOf(" [")); + } + this.mHistory.removeSession(revisedLabel); + this.refresh(); + } +} diff --git a/src/api/ZoweTree.ts b/src/api/ZoweTree.ts new file mode 100644 index 0000000000..f8c7f8b5ce --- /dev/null +++ b/src/api/ZoweTree.ts @@ -0,0 +1,239 @@ +/* +* This program and the accompanying materials are made available under the terms of the * +* Eclipse Public License v2.0 which accompanies this distribution, and is available at * +* https://www.eclipse.org/legal/epl-v20.html * +* * +* SPDX-License-Identifier: EPL-2.0 * +* * +* Copyright Contributors to the Zowe Project. * +* * +*/ + +import * as vscode from "vscode"; +import { Session } from "@brightside/imperative"; +import { IJob } from "@brightside/core"; + +/** + * The base interface for Zowe tree browsers that implement the + * vscode.TreeDataProvider. + * + * @export + * @interface IZoweTree + * @extends {vscode.TreeDataProvider} + * @template T provide a subtype of vscode.TreeItem + */ +export interface IZoweTree extends vscode.TreeDataProvider { + /** + * Root session nodes + */ + mSessionNodes: T[]; + /** + * Root favorites node + */ + mFavoriteSession: T; + /** + * Array of favorite nodes + */ + mFavorites: T[]; + /** + * Adds a session to the container + * @param sessionName + * @param type e.g. zosmf + */ + addSession(sessionName?: string, type?: string): Promise; + /** + * Adds a favorite node + * @param favorite Adds a favorite node + */ + addFavorite(favorite: IZoweTreeNode); + /** + * Removes a favorite node + * @param favorite Adds a favorite node + */ + removeFavorite(node: IZoweTreeNode); + /** + * Refreshes the tree + */ + refresh(): void; +} +/** + * The base interface for Zowe tree nodes. + * + * @export + * @interface IZoweTreeNode + */ +export interface IZoweTreeNode { + /** + * The icon path or [ThemeIcon](#ThemeIcon) for the tree item. + */ + iconPath?: string | vscode.Uri | { light: string | vscode.Uri; dark: string | vscode.Uri } | vscode.ThemeIcon; + /** + * Indicator that the child data may have become stale and requires refreshing. + */ + dirty: boolean; + /** + * A human-readable string describing this item. + */ + label?: string; + /** + * The tooltip text when you hover over this item. + */ + tooltip?: string; + /** + * Describes the full path of a file + */ + fullPath?: string; + /** + * Children nodes of this node + */ + children?: IZoweTreeNode[]; + /** + * [TreeItemCollapsibleState](#TreeItemCollapsibleState) of the tree item. + */ + collapsibleState?: vscode.TreeItemCollapsibleState; + /** + * Context value of the tree item. This can be used to contribute item specific actions in the tree. + * + * This will show action `extension.deleteFolder` only for items with `contextValue` is `folder`. + */ + contextValue?: string; + /** + * Retrieves the node label + */ + getLabel(): string; + /** + * Retrieves the nodes parent node + */ + getParent(): IZoweTreeNode; + /** + * Retrieves the nodes children nodes + */ + getChildren(): Promise; + /** + * Retrieves the profile name in use with this node + */ + getProfileName(): string; + /** + * Retrieves the session node in use with this node + */ + getSessionNode(): IZoweTreeNode; + /** + * Retrieves the session object in use with this node + */ + getSession(): Session; +} + +/** + * Extended interface for Zowe Dataset tree nodes. + * + * @export + * @interface export interface IZoweDatasetTreeNode extends IZoweTreeNode { + */ +export interface IZoweDatasetTreeNode extends IZoweTreeNode { + /** + * Search criteria for a Dataset search + */ + pattern?: string; + + /** + * Retrieves child nodes of this IZoweDatasetTreeNode + * + * @returns {Promise} + */ + getChildren(): Promise; + /** + * Retrieves the etag value for the file + * + * @returns {string} + */ + getEtag?(): string; + /** + * Sets the etag value for the file + * + * @param {string} + */ + setEtag?(etag: string); +} + +/** + * Extended interface for Zowe USS tree nodes. + * + * @export + * @interface export interface IZoweUSSTreeNode extends IZoweTreeNode { + */ +export interface IZoweUSSTreeNode extends IZoweTreeNode { + /** + * Retrieves an abridged for of the label + */ + shortLabel?: string; + /** + * List of child nodes downloaded in binary format + */ + binaryFiles?: {}; + /** + * Binary indicator. Default false (text) + */ + binary?: boolean; + + /** + * Retrieves child nodes of this IZoweUSSTreeNode + * + * @returns {Promise} + */ + getChildren(): Promise; + /** + * Retrieves the etag value for the file + * + * @returns {string} + */ + getEtag?(): string; + /** + * Sets the etag value for the file + * + * @param {string} + */ + setEtag?(etag: string); + /** + * Renaming a USS Node. This could be a Favorite Node + * + * @param {string} newNamePath + */ + rename?(newNamePath: string); +} + +/** + * Extended interface for Zowe Job tree nodes. + * + * @export + * @interface export interface IZoweJobTreeNode extends IZoweTreeNode { + */ +export interface IZoweJobTreeNode extends IZoweTreeNode { + + /** + * Standard job response document + * Represents the attributes and status of a z/OS batch job + * @interface IJob + */ + job?: IJob; + /** + * Search criteria for a Job search + */ + searchId?: string; + /** + * Job Prefix i.e "MYJOB" + * Attribute of Job query + */ + prefix?: string; + /** + * Job Owner i.e "MYID" + * Attribute of Job query + */ + owner?: string; + + /** + * Retrieves child nodes of this IZoweJobTreeNode + * + * @returns {Promise} + */ + getChildren(): Promise; +} diff --git a/src/extension.ts b/src/extension.ts index 26472595cd..ca581b6971 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -14,7 +14,7 @@ import * as fs from "fs"; import { moveSync } from "fs-extra"; import * as path from "path"; import * as vscode from "vscode"; -import { IZoweTree, IZoweTreeNode } from "./ZoweTree"; +import { IZoweTree, IZoweTreeNode, IZoweJobTreeNode, IZoweUSSTreeNode, IZoweDatasetTreeNode } from "./api/ZoweTree"; import { ZoweNode } from "./ZoweNode"; import { Logger, TextUtils, IProfileLoaded, ISession, IProfile, Session } from "@brightside/imperative"; import { DatasetTree, createDatasetTree } from "./DatasetTree"; @@ -204,8 +204,8 @@ export async function activate(context: vscode.ExtensionContext) { } } if (ussFileProvider) { - vscode.commands.registerCommand("zowe.uss.addFavorite", async (node) => ussFileProvider.addUSSFavorite(node)); - vscode.commands.registerCommand("zowe.uss.removeFavorite", async (node) => ussFileProvider.removeUSSFavorite(node)); + vscode.commands.registerCommand("zowe.uss.addFavorite", async (node) => ussFileProvider.addFavorite(node)); + vscode.commands.registerCommand("zowe.uss.removeFavorite", async (node) => ussFileProvider.removeFavorite(node)); vscode.commands.registerCommand("zowe.uss.addSession", async () => addZoweSession(ussFileProvider)); vscode.commands.registerCommand("zowe.uss.refreshAll", () => ussActions.refreshAllUSS(ussFileProvider)); vscode.commands.registerCommand("zowe.uss.refreshUSS", (node) => refreshUSS(node)); @@ -225,7 +225,7 @@ export async function activate(context: vscode.ExtensionContext) { vscode.commands.registerCommand("zowe.uss.copyPath", async (node) => ussActions.copyPath(node)); vscode.commands.registerCommand("zowe.uss.editFile", (node) => openUSS(node, false, false)); vscode.commands.registerCommand("zowe.uss.saveSearch", async (node) => ussFileProvider.addUSSSearchFavorite(node)); - vscode.commands.registerCommand("zowe.uss.removeSavedSearch", async (node) => ussFileProvider.removeUSSFavorite(node)); + vscode.commands.registerCommand("zowe.uss.removeSavedSearch", async (node) => ussFileProvider.removeFavorite(node)); vscode.workspace.onDidChangeConfiguration(async (e) => { ussFileProvider.onDidChangeConfiguration(e); }); @@ -256,7 +256,10 @@ export async function activate(context: vscode.ExtensionContext) { vscode.commands.registerCommand("zowe.refreshAllJobs", () => { jobsProvider.mSessionNodes.forEach((jobNode) => { if (jobNode.contextValue === JOBS_SESSION_CONTEXT) { - jobNode.reset(); + // reset + utils.labelHack(jobNode); + jobNode.children = []; + jobNode.dirty = true; } }); jobsProvider.refresh(); @@ -284,24 +287,24 @@ export async function activate(context: vscode.ExtensionContext) { const job = jobs.find((jobNode) => { return jobNode.job.jobid === jobid; }); - jobsProvider.setJob(jobView, job); + jobsProvider.setItem(jobView, job); }); vscode.commands.registerCommand("zowe.jobs.search", (node) => jobsProvider.searchPrompt(node)); vscode.commands.registerCommand("zowe.issueTsoCmd", async () => issueTsoCommand(outputChannel)); vscode.workspace.onDidChangeConfiguration(async (e) => { jobsProvider.onDidChangeConfiguration(e); }); - vscode.commands.registerCommand("zowe.jobs.addFavorite", async (node) => jobsProvider.addJobsFavorite(node)); - vscode.commands.registerCommand("zowe.jobs.removeFavorite", async (node) => jobsProvider.removeJobsFavorite(node)); + vscode.commands.registerCommand("zowe.jobs.addFavorite", async (node) => jobsProvider.addFavorite(node)); + vscode.commands.registerCommand("zowe.jobs.removeFavorite", async (node) => jobsProvider.removeFavorite(node)); vscode.commands.registerCommand("zowe.jobs.saveSearch", async (node) => jobsProvider.saveSearch(node)); - vscode.commands.registerCommand("zowe.jobs.removeSearchFavorite", async (node) => jobsProvider.removeJobsFavorite(node)); + vscode.commands.registerCommand("zowe.jobs.removeSearchFavorite", async (node) => jobsProvider.removeFavorite(node)); const jobView = vscode.window.createTreeView("zowe.jobs", { treeDataProvider: jobsProvider }); context.subscriptions.push(jobView); if (!ISTHEIA) { - jobView.onDidCollapseElement( async (e: { element: Job; }) => { + jobView.onDidCollapseElement( async (e: { element: IZoweJobTreeNode; }) => { jobsProvider.flipState(e.element, false); }); - jobView.onDidExpandElement( async (e: { element: Job; }) => { + jobView.onDidExpandElement( async (e: { element: IZoweJobTreeNode; }) => { jobsProvider.flipState(e.element, true); }); } @@ -442,7 +445,7 @@ export async function downloadSpool(job: Job){ canSelectMany: false }); if (dirUri !== undefined) { - zowe.DownloadJobs.downloadAllSpoolContentCommon(job.session, { + zowe.DownloadJobs.downloadAllSpoolContentCommon(job.getSession(), { jobid: job.job.jobid, jobname: job.job.jobname, outDir: dirUri[0].fsPath @@ -456,7 +459,7 @@ export async function downloadSpool(job: Job){ export async function downloadJcl(job: Job) { try { - const jobJcl = await zowe.GetJobs.getJclForJob(job.session, job.job); + const jobJcl = await zowe.GetJobs.getJclForJob(job.getSession(), job.job); const jclDoc = await vscode.workspace.openTextDocument({language: "jcl", content: jobJcl}); await vscode.window.showTextDocument(jclDoc); } catch (error) { @@ -543,30 +546,30 @@ export async function submitJcl(datasetProvider: DatasetTree) { * @export * @param node The dataset member */ -export async function submitMember(node: ZoweNode) { +export async function submitMember(node: IZoweTreeNode) { const labelregex = /\[(.+)\]\: (.+)/g; let label; let sesName; - switch (node.mParent.contextValue) { + switch (node.getParent().contextValue) { case (FAVORITE_CONTEXT): { - const regex = labelregex.exec(node.label); + const regex = labelregex.exec(node.getLabel()); sesName = regex[1]; label = regex[2]; break; } case (DS_PDS_CONTEXT + FAV_SUFFIX): { - const regex = labelregex.exec(node.mParent.label); + const regex = labelregex.exec(node.getParent().getLabel()); sesName = regex[1]; label = regex[2] + "(" + node.label.trim()+ ")"; break; } case (DS_SESSION_CONTEXT): - sesName = node.mParent.label; + sesName = node.getParent().getLabel(); label = node.label; break; case (DS_PDS_CONTEXT): - sesName = node.mParent.mParent.label; - label = node.mParent.label.trim()+ "(" + node.label.trim()+ ")"; + sesName = node.getParent().getParent().getLabel(); + label = node.getParent().getLabel() + "(" + node.label.trim()+ ")"; break; default: vscode.window.showErrorMessage(localize("submitMember.invalidNode", "submitMember() called from invalid node.")); @@ -922,28 +925,28 @@ export async function renameDataSet(node: ZoweNode, datasetProvider: DatasetTree datasetProvider.renameFavorite(node, afterDataSetName); node.label = temp; } - datasetProvider.refreshElement(node.mParent); + datasetProvider.refreshElement(node.getParent()); datasetProvider.updateFavorites(); } } -function getProfileAndDataSetName(node: ZoweNode) { +function getProfileAndDataSetName(node: IZoweTreeNode) { let profileName; let dataSetName; if (node.contextValue.includes(FAV_SUFFIX)) { profileName = node.label.substring(1, node.label.indexOf("]")); dataSetName = node.label.substring(node.label.indexOf(":") + 2); } else { - profileName = node.mParent.label.trim(); + profileName = node.getParent().getLabel(); dataSetName = node.label.trim(); } return { profileName, dataSetName }; } -function getNodeLabels(node: ZoweNode) { +function getNodeLabels(node: IZoweTreeNode) { if (node.contextValue.includes(DS_MEMBER_CONTEXT)) { - return { ...getProfileAndDataSetName(node.mParent), memberName: node.label.trim() }; + return { ...getProfileAndDataSetName(node.getParent()), memberName: node.getLabel()}; } else { return getProfileAndDataSetName(node); } @@ -1028,19 +1031,19 @@ export async function pasteDataSet(node: ZoweNode, datasetProvider: DatasetTree) * Rename data set members * * @export - * @param {ZoweNode} node - The node + * @param {IZoweTreeNode} node - The node * @param {DatasetTree} datasetProvider - the tree which contains the nodes */ -export async function renameDataSetMember(node: ZoweNode, datasetProvider: DatasetTree) { +export async function renameDataSetMember(node: IZoweTreeNode, datasetProvider: DatasetTree) { const beforeMemberName = node.label.trim(); let dataSetName; let profileLabel; - if (node.mParent.contextValue.includes(FAV_SUFFIX)) { - profileLabel = node.mParent.label.substring(0, node.mParent.label.indexOf(":") + 2); - dataSetName = node.mParent.label.substring(node.mParent.label.indexOf(":") + 2); + if (node.getParent().contextValue.includes(FAV_SUFFIX)) { + profileLabel = node.getParent().getLabel().substring(0, node.getParent().getLabel().indexOf(":") + 2); + dataSetName = node.getParent().getLabel().substring(node.getParent().getLabel().indexOf(":") + 2); } else { - dataSetName = node.mParent.label.trim(); + dataSetName = node.getParent().getLabel(); } const afterMemberName = await vscode.window.showInputBox({ value: beforeMemberName }); @@ -1054,8 +1057,8 @@ export async function renameDataSetMember(node: ZoweNode, datasetProvider: Datas vscode.window.showErrorMessage(localize("renameDataSet.error", "Unable to rename data set: ") + err.message); throw err; } - if (node.mParent.contextValue.includes(FAV_SUFFIX)) { - const nonFavoritedParent = datasetProvider.findNonFavoritedNode(node.mParent); + if (node.getParent().contextValue.includes(FAV_SUFFIX)) { + const nonFavoritedParent = datasetProvider.findNonFavoritedNode(node.getParent()); if (nonFavoritedParent) { const nonFavoritedMember = nonFavoritedParent.children.find((child) => child.label === beforeMemberName); if (nonFavoritedMember) { @@ -1064,7 +1067,7 @@ export async function renameDataSetMember(node: ZoweNode, datasetProvider: Datas } } } else { - const favoritedParent = datasetProvider.findFavoritedNode(node.mParent); + const favoritedParent = datasetProvider.findFavoritedNode(node.getParent()); if (favoritedParent) { const favoritedMember = favoritedParent.children.find((child) => child.label === beforeMemberName); if (favoritedMember) { @@ -1073,7 +1076,7 @@ export async function renameDataSetMember(node: ZoweNode, datasetProvider: Datas } } } - datasetProvider.refreshElement(node.mParent); + datasetProvider.refreshElement(node.getParent()); } } @@ -1129,10 +1132,10 @@ export async function deactivate() { * Deletes a dataset * * @export - * @param {ZoweNode} node - The node to be deleted + * @param {IZoweTreeNode} node - The node to be deleted * @param {DatasetTree} datasetProvider - the tree which contains the nodes */ -export async function deleteDataset(node: ZoweNode, datasetProvider: DatasetTree) { +export async function deleteDataset(node: IZoweTreeNode, datasetProvider: DatasetTree) { log.debug(localize("deleteDataset.log.debug", "Deleting data set ") + node.label); const quickPickOptions: vscode.QuickPickOptions = { placeHolder: localize("deleteDataset.quickPickOption", "Are you sure you want to delete ") + node.label, @@ -1149,20 +1152,20 @@ export async function deleteDataset(node: ZoweNode, datasetProvider: DatasetTree let label = ""; let fav = false; try { - switch (node.mParent.contextValue) { + switch (node.getParent().contextValue) { case (FAVORITE_CONTEXT): label = node.label.substring(node.label.indexOf(":") + 1).trim(); fav = true; break; case (DS_PDS_CONTEXT + FAV_SUFFIX): - label = node.mParent.label.substring(node.mParent.label.indexOf(":") + 1).trim() + "(" + node.label.trim()+ ")"; + label = node.getParent().getLabel().substring(node.getParent().getLabel().indexOf(":") + 1).trim() + "(" + node.getLabel()+ ")"; fav = true; break; case (DS_SESSION_CONTEXT): - label = node.label.trim(); + label = node.getLabel(); break; case (DS_PDS_CONTEXT): - label = node.mParent.label.trim()+ "(" + node.label.trim()+ ")"; + label = node.getParent().getLabel()+ "(" + node.getLabel()+ ")"; break; default: throw Error(localize("deleteDataSet.invalidNode.error", "deleteDataSet() called from invalid node.")); @@ -1183,7 +1186,8 @@ export async function deleteDataset(node: ZoweNode, datasetProvider: DatasetTree if (fav) { datasetProvider.mSessionNodes.forEach((ses) => { if (node.label.substring(node.label.indexOf("[") + 1, node.label.indexOf("]")) === ses.label.trim()|| - node.mParent.label.substring(node.mParent.label.indexOf("["), node.mParent.label.indexOf("]")) === ses.label) { + node.getParent().getLabel().substring(node.getParent().getLabel().indexOf("["), + node.getParent().getLabel().indexOf("]")) === ses.label) { ses.dirty = true; } }); @@ -1211,11 +1215,11 @@ export async function deleteDataset(node: ZoweNode, datasetProvider: DatasetTree /** * Prompts the user for a pattern, and populates the [TreeView]{@link vscode.TreeView} based on the pattern * - * @param {ZoweNode} node - The session node + * @param {IZoweDatasetTreeNode} node - The session node * @param {DatasetTree} datasetProvider - Current DatasetTree used to populate the TreeView * @returns {Promise} */ -export async function enterPattern(node: ZoweNode, datasetProvider: DatasetTree) { +export async function enterPattern(node: IZoweDatasetTreeNode, datasetProvider: DatasetTree) { if (log) { log.debug(localize("enterPattern.log.debug.prompt", "Prompting the user for a data set pattern")); } @@ -1257,9 +1261,9 @@ export async function enterPattern(node: ZoweNode, datasetProvider: DatasetTree) * Returns the profile for the specified node * * @export - * @param {ZoweNode} node + * @param {IZoweTreeNode} node */ -export function getProfile(node: ZoweNode) { +export function getProfile(node: IZoweTreeNode) { let profile = node.getSessionNode().label.trim(); // if this is a favorite node, further extraction is necessary if (profile.includes("[")) { @@ -1274,8 +1278,8 @@ export function getProfile(node: ZoweNode) { * @export * @param {ZoweUSSNode} node */ -export function getUSSProfile(node: ZoweUSSNode) { - const profile = node.getSessionNode().mProfileName; +export function getUSSProfile(node: IZoweUSSTreeNode) { + const profile = node.getSessionNode().getProfileName(); return profile; } @@ -1327,13 +1331,13 @@ function appendSuffix(label: string): string { } /** - * Returns the file path for the ZoweNode + * Returns the file path for the IZoweTreeNode * * @export * @param {string} label - If node is a member, label includes the name of the PDS * @param {ZoweNode} node */ -export function getDocumentFilePath(label: string, node: ZoweNode) { +export function getDocumentFilePath(label: string, node: IZoweTreeNode) { return path.join(DS_DIR, "/" + getProfile(node) + "/" + appendSuffix(label) ); } @@ -1343,22 +1347,22 @@ export function getDocumentFilePath(label: string, node: ZoweNode) { * @export * @param {ZoweUSSNode} node */ -export function getUSSDocumentFilePath(node: ZoweUSSNode) { +export function getUSSDocumentFilePath(node: IZoweUSSTreeNode) { return path.join(USS_DIR, "/" + getUSSProfile(node) + "/", node.fullPath); } /** * Downloads and displays a PS in a text editor view * - * @param {ZoweNode} node + * @param {IZoweDatasetTreeNode} node */ -export async function openPS(node: ZoweNode, previewMember: boolean) { +export async function openPS(node: IZoweDatasetTreeNode, previewMember: boolean) { const datasetProvider = new DatasetTree(); let sesNamePrompt: string; if (node.contextValue.endsWith(FAV_SUFFIX)) { - sesNamePrompt = node.label.substring(1, node.label.indexOf("]")); + sesNamePrompt = node.getLabel().substring(1, node.getLabel().indexOf("]")); } else { - sesNamePrompt = node.label; + sesNamePrompt = node.getLabel(); } if ((!node.getSession().ISession.user) || (!node.getSession().ISession.password)) { try { @@ -1387,18 +1391,18 @@ export async function openPS(node: ZoweNode, previewMember: boolean) { if (validProfile === 0) { try { let label: string; - switch (node.mParent.contextValue) { + switch (node.getParent().contextValue) { case (FAVORITE_CONTEXT): label = node.label.substring(node.label.indexOf(":") + 1).trim(); break; case (DS_PDS_CONTEXT + FAV_SUFFIX): - label = node.mParent.label.substring(node.mParent.label.indexOf(":") + 1).trim() + "(" + node.label.trim()+ ")"; + label = node.getParent().getLabel().substring(node.getParent().getLabel().indexOf(":") + 1).trim() + "(" + node.getLabel()+ ")"; break; case (DS_SESSION_CONTEXT): label = node.label.trim(); break; case (DS_PDS_CONTEXT): - label = node.mParent.label.trim() + "(" + node.label.trim()+ ")"; + label = node.getParent().getLabel().trim() + "(" + node.getLabel()+ ")"; break; default: vscode.window.showErrorMessage(localize("openPS.invalidNode", "openPS() called from invalid node.")); @@ -1460,18 +1464,18 @@ export async function refreshAll(datasetProvider: DatasetTree) { export async function refreshPS(node: ZoweNode) { let label; try { - switch (node.mParent.contextValue) { + switch (node.getParent().contextValue) { case (FAVORITE_CONTEXT): label = node.label.substring(node.label.indexOf(":") + 1).trim(); break; case (DS_PDS_CONTEXT + FAV_SUFFIX): - label = node.mParent.label.substring(node.mParent.label.indexOf(":") + 1).trim() + "(" + node.label.trim()+ ")"; + label = node.getParent().getLabel().substring(node.getParent().getLabel().indexOf(":") + 1).trim() + "(" + node.getLabel()+ ")"; break; case (DS_SESSION_CONTEXT): label = node.label.trim(); break; case (DS_PDS_CONTEXT): - label = node.mParent.label.trim() + "(" + node.label.trim() + ")"; + label = node.getParent().getLabel() + "(" + node.getLabel() + ")"; break; default: throw Error(localize("refreshPS.error.invalidNode", "refreshPS() called from invalid node.")); @@ -1508,7 +1512,7 @@ export async function refreshPS(node: ZoweNode) { */ export async function refreshUSS(node: ZoweUSSNode) { let label; - switch (node.mParent.contextValue) { + switch (node.getParent().contextValue) { case (USS_DIR_CONTEXT + FAV_SUFFIX): label = node.fullPath; break; @@ -1561,7 +1565,7 @@ function checkForAddedSuffix(filename: string): boolean { * @export * @param {vscode.TextDocument} doc - TextDocument that is being saved */ -export async function saveFile(doc: vscode.TextDocument, datasetProvider: DatasetTree) { +export async function saveFile(doc: vscode.TextDocument, datasetProvider: IZoweTree) { // Check if file is a data set, instead of some other file log.debug(localize("saveFile.log.debug.request", "requested to save data set: ") + doc.fileName); const docPath = path.join(doc.fileName, ".."); @@ -1577,7 +1581,7 @@ export async function saveFile(doc: vscode.TextDocument, datasetProvider: Datase // get session from session name let documentSession: Session; - let node: ZoweNode; + let node: IZoweDatasetTreeNode; const sesNode = (await datasetProvider.getChildren()).find((child) => child.label.trim() === sesName); if (sesNode) { @@ -1610,7 +1614,7 @@ export async function saveFile(doc: vscode.TextDocument, datasetProvider: Datase } } // Get specific node based on label and parent tree (session / favorites) - let nodes: ZoweNode[]; + let nodes: IZoweTreeNode[]; let isFromFavorites: boolean; if (!sesNode || sesNode.children.length === 0) { // saving from favorites @@ -1706,25 +1710,26 @@ export async function saveUSSFile(doc: vscode.TextDocument, ussFileProvider: USS // get session from session name let documentSession: Session; let binary; - let node: ZoweUSSNode; - const sesNode = (await ussFileProvider.mSessionNodes.find((child) => child.mProfileName && child.mProfileName.trim()=== sesName.trim())); + let node: IZoweDatasetTreeNode; + const sesNode = (await ussFileProvider.mSessionNodes.find((child) => child.getProfileName() && child.getProfileName()=== sesName.trim())); if (sesNode) { documentSession = sesNode.getSession(); binary = Object.keys(sesNode.binaryFiles).find((child) => child === remote) !== undefined; } // Get specific node based on label and parent tree (session / favorites) - let nodes: ZoweUSSNode[]; + let nodes: IZoweDatasetTreeNode[]; if (!sesNode || sesNode.children.length === 0) { // saving from favorites - nodes = utils.concatUSSChildNodes(ussFileProvider.mFavorites); + nodes = utils.concatChildNodes(ussFileProvider.mFavorites); } else { // saving from session - nodes = utils.concatUSSChildNodes([sesNode]); + nodes = utils.concatChildNodes([sesNode]); } - node = await nodes.find((zNode) => { + node = nodes.find((zNode) => { if (zNode.contextValue === DS_FAV_TEXT_FILE_CONTEXT || zNode.contextValue === DS_TEXT_FILE_CONTEXT) { return (zNode.fullPath.trim() === remote); - } else { + } + else { return false; } }); @@ -1785,13 +1790,13 @@ export async function saveUSSFile(doc: vscode.TextDocument, ussFileProvider: USS /** * Downloads and displays a file in a text editor view * - * @param {ZoweUSSNode} node + * @param {IZoweTreeNode} node */ -export async function openUSS(node: ZoweUSSNode, download = false, previewFile: boolean) { +export async function openUSS(node: IZoweUSSTreeNode, download = false, previewFile: boolean) { const ussFileProvider = new USSTree(); if ((!node.getSession().ISession.user) || (!node.getSession().ISession.password)) { try { - const values = await Profiles.getInstance().promptCredentials(node.mProfileName); + const values = await Profiles.getInstance().promptCredentials(node.getProfileName()); if (values !== undefined) { usrNme = values [0]; passWrd = values [1]; @@ -1816,7 +1821,7 @@ export async function openUSS(node: ZoweUSSNode, download = false, previewFile: if (validProfile === 0) { try { let label: string; - switch (node.mParent.contextValue) { + switch (node.getParent().contextValue) { case (FAVORITE_CONTEXT): label = node.label.substring(node.label.indexOf(":") + 1).trim(); break; @@ -1869,7 +1874,7 @@ export async function modifyCommand(job: Job) { try { const command = await vscode.window.showInputBox({ prompt: localize("modifyCommand.command.prompt", "Modify Command") }); if (command !== undefined) { - const response = await zowe.IssueCommand.issueSimple(job.session, `f ${job.job.jobname},${command}`); + const response = await zowe.IssueCommand.issueSimple(job.getSession(), `f ${job.job.jobname},${command}`); vscode.window.showInformationMessage(localize("modifyCommand.response", "Command response: ") + response.commandResponse); } } catch (error) { @@ -1879,7 +1884,7 @@ export async function modifyCommand(job: Job) { export async function stopCommand(job: Job) { try { - const response = await zowe.IssueCommand.issueSimple(job.session, `p ${job.job.jobname}`); + const response = await zowe.IssueCommand.issueSimple(job.getSession(), `p ${job.job.jobname}`); vscode.window.showInformationMessage(localize("stopCommand.response", "Command response: ") + response.commandResponse); } catch (error) { vscode.window.showErrorMessage(error.message); @@ -1920,19 +1925,19 @@ export async function getSpoolContent(session: string, spool: IJobFile) { } } -export async function setOwner(job: Job, jobsProvider: ZosJobsProvider) { +export async function setOwner(job: IZoweJobTreeNode, jobsProvider: ZosJobsProvider) { const newOwner = await vscode.window.showInputBox({ prompt: localize("setOwner.newOwner.prompt.owner", "Owner") }); job.owner = newOwner; jobsProvider.refreshElement(job); } -export async function setPrefix(job: Job, jobsProvider: ZosJobsProvider) { +export async function setPrefix(job: IZoweJobTreeNode, jobsProvider: ZosJobsProvider) { const newPrefix = await vscode.window.showInputBox({ prompt: localize("setOwner.newOwner.prompt.prefix", "Prefix") }); job.prefix = newPrefix; jobsProvider.refreshElement(job); } -export async function refreshJobsServer(node: Job) { +export async function refreshJobsServer(node: IZoweJobTreeNode) { const jobsProvider = new ZosJobsProvider(); let sesNamePrompt: string; if (node.contextValue.endsWith(FAV_SUFFIX)) { @@ -1940,7 +1945,7 @@ export async function refreshJobsServer(node: Job) { } else { sesNamePrompt = node.label; } - if ((!node.session.ISession.user ) || (!node.session.ISession.password)) { + if ((!node.getSession().ISession.user ) || (!node.getSession().ISession.password)) { try { const values = await Profiles.getInstance().promptCredentials(sesNamePrompt); if (values !== undefined) { @@ -1952,9 +1957,9 @@ export async function refreshJobsServer(node: Job) { vscode.window.showErrorMessage(error.message); } if (usrNme !== undefined && passWrd !== undefined && baseEncd !== undefined) { - node.session.ISession.user = usrNme; - node.session.ISession.password = passWrd; - node.session.ISession.base64EncodedAuth = baseEncd; + node.getSession().ISession.user = usrNme; + node.getSession().ISession.password = passWrd; + node.getSession().ISession.base64EncodedAuth = baseEncd; node.owner = usrNme; validProfile = 0; } diff --git a/src/jobs/jobNodeActions.ts b/src/jobs/jobNodeActions.ts new file mode 100644 index 0000000000..0623a159e7 --- /dev/null +++ b/src/jobs/jobNodeActions.ts @@ -0,0 +1,27 @@ +/* +* This program and the accompanying materials are made available under the terms of the * +* Eclipse Public License v2.0 which accompanies this distribution, and is available at * +* https://www.eclipse.org/legal/epl-v20.html * +* * +* SPDX-License-Identifier: EPL-2.0 * +* * +* Copyright Contributors to the Zowe Project. * +* * +*/ + +import * as vscode from "vscode"; +import { DeleteJobs } from "@brightside/core"; +import * as nls from "vscode-nls"; +import { Job } from "../ZoweJobNode"; +const localize = nls.config({ messageFormat: nls.MessageFormat.file })(); + +export async function deleteJob(node: Job) { + try { + await DeleteJobs.deleteJob(node.getSession(), node.job.jobname, node.job.jobid); + vscode.window.showInformationMessage(localize("deleteJob.job", "Job ") + node.job.jobname + "(" + node.job.jobid + ")" + + localize("deleteJob.delete", " deleted")); + } catch (error) { + vscode.window.showErrorMessage(error.message); + } +} + diff --git a/src/mvs/mvsNodeActions.ts b/src/mvs/mvsNodeActions.ts index b626560685..bbc4395d6e 100644 --- a/src/mvs/mvsNodeActions.ts +++ b/src/mvs/mvsNodeActions.ts @@ -35,7 +35,7 @@ export async function uploadDialog(node: ZoweNode, datasetProvider: DatasetTree) } export function getDatasetLabel(node: ZoweNode) { - if (node.mParent && node.mParent.contextValue === extension.FAVORITE_CONTEXT) { + if (node.getParent() && node.getParent().contextValue === extension.FAVORITE_CONTEXT) { const profileEnd = "]: "; const profileIndex = node.label.indexOf(profileEnd); return node.label.substr(profileIndex + profileEnd.length, node.label.length); diff --git a/src/uss/ussNodeActions.ts b/src/uss/ussNodeActions.ts index 8af0b82ae4..c8eed99db7 100644 --- a/src/uss/ussNodeActions.ts +++ b/src/uss/ussNodeActions.ts @@ -21,6 +21,7 @@ import * as extension from "../../src/extension"; import * as path from "path"; import { ISTHEIA } from "../extension"; import { Profiles } from "../Profiles"; +import { IZoweTreeNode, IZoweTree, IZoweUSSTreeNode } from "../api/ZoweTree"; /** * Prompts the user for a path, and populates the [TreeView]{@link vscode.TreeView} based on the path * @@ -91,7 +92,7 @@ export async function createUSSNodeDialog(node: ZoweUSSNode, ussFileProvider: US } } -export async function deleteUSSNode(node: ZoweUSSNode, ussFileProvider: USSTree, filePath: string) { +export async function deleteUSSNode(node: IZoweTreeNode, ussFileProvider: IZoweTree, filePath: string) { // handle zosmf api issue with file paths const nodePath = node.fullPath.startsWith("/") ? node.fullPath.substring(1) : node.fullPath; const quickPickOptions: vscode.QuickPickOptions = { @@ -108,7 +109,7 @@ export async function deleteUSSNode(node: ZoweUSSNode, ussFileProvider: USSTree, try { const isRecursive = node.contextValue === extension.USS_DIR_CONTEXT ? true : false; await zowe.Delete.ussFile(node.getSession(), nodePath, isRecursive); - node.mParent.dirty = true; + node.getParent().dirty = true; deleteFromDisk(node, filePath); } catch (err) { vscode.window.showErrorMessage(localize("deleteUSSNode.error.node", "Unable to delete node: ") + err.message); @@ -116,7 +117,7 @@ export async function deleteUSSNode(node: ZoweUSSNode, ussFileProvider: USSTree, } // Remove node from the USS Favorites tree - ussFileProvider.removeUSSFavorite(node); + ussFileProvider.removeFavorite(node); ussFileProvider.refresh(); } @@ -140,11 +141,11 @@ export async function refreshAllUSS(ussFileProvider: USSTree) { /** * Process for renaming a USS Node. This could be a Favorite Node * - * @param {ZoweUSSNode} originalNode + * @param {IZoweTreeNode} originalNode * @param {USSTree} ussFileProvider * @param {string} filePath */ -export async function renameUSSNode(originalNode: ZoweUSSNode, ussFileProvider: USSTree, filePath: string) { +export async function renameUSSNode(originalNode: IZoweUSSTreeNode, ussFileProvider: IZoweTree, filePath: string) { // Could be a favorite or regular entry always deal with the regular entry const isFav = originalNode.contextValue.endsWith(extension.FAV_SUFFIX); const oldLabel = isFav ? originalNode.shortLabel : originalNode.label; @@ -160,9 +161,9 @@ export async function renameUSSNode(originalNode: ZoweUSSNode, ussFileProvider: await zowe.Utilities.renameUSSFile(originalNode.getSession(), originalNode.fullPath, newNamePath); ussFileProvider.refresh(); if (oldFavorite) { - ussFileProvider.removeUSSFavorite(oldFavorite); + ussFileProvider.removeFavorite(oldFavorite); oldFavorite.rename(newNamePath); - ussFileProvider.addUSSFavorite(oldFavorite); + ussFileProvider.addFavorite(oldFavorite); } } catch (err) { vscode.window.showErrorMessage(localize("renameUSSNode.error", "Unable to rename node: ") + err.message); @@ -177,7 +178,7 @@ export async function renameUSSNode(originalNode: ZoweUSSNode, ussFileProvider: * * @param {ZoweUSSNode} node */ -export async function deleteFromDisk(node: ZoweUSSNode, filePath: string) { +export async function deleteFromDisk(node: IZoweTreeNode, filePath: string) { try { if (fs.existsSync(filePath)) { fs.unlinkSync(filePath); diff --git a/src/utils.ts b/src/utils.ts index 57abebb55b..aafb9d24e1 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -10,14 +10,10 @@ */ import * as path from "path"; -import * as os from "os"; -import * as zowe from "@brightside/core"; -import { CliProfileManager } from "@brightside/imperative"; import { TreeItem, QuickPickItem, QuickPick } from "vscode"; import * as extension from "../src/extension"; import * as nls from "vscode-nls"; -import { ZoweUSSNode } from "./ZoweUSSNode"; -import { ZoweNode } from "./ZoweNode"; +import { IZoweTreeNode } from "./api/ZoweTree"; const localize = nls.config({ messageFormat: nls.MessageFormat.file })(); /* @@ -148,22 +144,8 @@ export class JobIdFilterDescriptor extends FilterDescriptor { /************************************************************************************************************* * Returns array of all subnodes of given node *************************************************************************************************************/ -export function concatUSSChildNodes(nodes: ZoweUSSNode[]) { - let allNodes = new Array(); - - for (const node of nodes) { - allNodes = allNodes.concat(concatUSSChildNodes(node.children)); - allNodes.push(node); - } - - return allNodes; -} - -/************************************************************************************************************* - * Returns array of all subnodes of given node - *************************************************************************************************************/ -export function concatChildNodes(nodes: ZoweNode[]) { - let allNodes = new Array(); +export function concatChildNodes(nodes: IZoweTreeNode[]) { + let allNodes = new Array(); for (const node of nodes) { allNodes = allNodes.concat(concatChildNodes(node.children)); From 1b193dbeb766ecc5d17b768ae3ca9b41f4d449c6 Mon Sep 17 00:00:00 2001 From: Colin Stone <30794003+Colin-Stone@users.noreply.github.com> Date: Tue, 24 Dec 2019 14:52:49 +0000 Subject: [PATCH 02/19] clean up mProfileName on USS Signed-off-by: Colin Stone <30794003+Colin-Stone@users.noreply.github.com> --- __tests__/__unit__/extension.unit.test.ts | 8 ++++---- i18n/sample/src/DatasetTree.i18n.json | 2 +- i18n/sample/src/Profiles.i18n.json | 4 ++-- i18n/sample/src/ZosJobsProvider.i18n.json | 2 +- i18n/sample/src/extension.i18n.json | 10 +++------- src/ZoweUSSNode.ts | 2 +- src/api/ZoweTree.ts | 4 ++++ src/extension.ts | 3 +-- src/jobs/jobNodeActions.ts | 2 +- 9 files changed, 18 insertions(+), 19 deletions(-) diff --git a/__tests__/__unit__/extension.unit.test.ts b/__tests__/__unit__/extension.unit.test.ts index 1ffd8a01c0..bd5ced5ece 100644 --- a/__tests__/__unit__/extension.unit.test.ts +++ b/__tests__/__unit__/extension.unit.test.ts @@ -101,7 +101,7 @@ describe("Extension Unit Tests", () => { sessNode.contextValue = extension.DS_SESSION_CONTEXT; sessNode.pattern = "test hlq"; - const ussNode = new ZoweUSSNode("usstest", vscode.TreeItemCollapsibleState.Expanded, null, session, null, null, null, "123"); + const ussNode = new ZoweUSSNode("usstest", vscode.TreeItemCollapsibleState.Expanded, null, session, null, null, "aProfile", "123"); ussNode.contextValue = extension.USS_SESSION_CONTEXT; ussNode.fullPath = "/u/myuser"; @@ -2300,7 +2300,7 @@ describe("Extension Unit Tests", () => { existsSync.mockReset(); withProgress.mockReset(); - const node = new ZoweUSSNode("node", vscode.TreeItemCollapsibleState.None, ussNode, null, "/", false, "aProfileName"); + const node = new ZoweUSSNode("node", vscode.TreeItemCollapsibleState.None, ussNode, null, "/"); const parent = new ZoweUSSNode("parent", vscode.TreeItemCollapsibleState.Collapsed, ussNode, null, "/"); const child = new ZoweUSSNode("child", vscode.TreeItemCollapsibleState.None, parent, null, "/parent"); @@ -2320,7 +2320,7 @@ describe("Extension Unit Tests", () => { await extension.openUSS(node, false, true); expect(existsSync.mock.calls.length).toBe(1); - expect(existsSync.mock.calls[0][0]).toBe(path.join(extension.USS_DIR, "/" + node.getProfileName() + "/", node.fullPath)); + expect(existsSync.mock.calls[0][0]).toBe(path.join(extension.USS_DIR, "/" + extension.getUSSProfile(node) + "/", node.fullPath)); expect(isFileTagBinOrAscii.mock.calls.length).toBe(1); expect(isFileTagBinOrAscii.mock.calls[0][0]).toBe(session); expect(isFileTagBinOrAscii.mock.calls[0][1]).toBe(node.fullPath); @@ -2428,7 +2428,7 @@ describe("Extension Unit Tests", () => { existsSync.mockReset(); withProgress.mockReset(); - const node = new ZoweUSSNode("node", vscode.TreeItemCollapsibleState.None, ussNode, null, "/", false, "aProfileName"); + const node = new ZoweUSSNode("node", vscode.TreeItemCollapsibleState.None, ussNode, null, "/", false, ussNode.getProfileName()); const parent = new ZoweUSSNode("parent", vscode.TreeItemCollapsibleState.Collapsed, ussNode, null, "/"); const child = new ZoweUSSNode("child", vscode.TreeItemCollapsibleState.None, parent, null, "/parent"); diff --git a/i18n/sample/src/DatasetTree.i18n.json b/i18n/sample/src/DatasetTree.i18n.json index ea2959c31b..08544f98a9 100644 --- a/i18n/sample/src/DatasetTree.i18n.json +++ b/i18n/sample/src/DatasetTree.i18n.json @@ -1,5 +1,5 @@ { - "FavoriteSession": "Favorites", + "Favorites": "Favorites", "initializeFavorites.log.debug": "initializing favorites", "initializeFavorites.error.profile1": "Error: You have Zowe Data Set favorites that refer to a non-existent CLI profile named: ", "intializeFavorites.error.profile2": ". To resolve this, you can create a profile with this name, ", diff --git a/i18n/sample/src/Profiles.i18n.json b/i18n/sample/src/Profiles.i18n.json index 6923ea8ecc..01ccbd77f1 100644 --- a/i18n/sample/src/Profiles.i18n.json +++ b/i18n/sample/src/Profiles.i18n.json @@ -10,14 +10,14 @@ "createNewConnection.undefined.username": "Operation Cancelled", "createNewConnection.option.prompt.password.placeholder": "Optional: Password", "createNewConnection.option.prompt.password": "Enter the password for the connection. Leave blank to not store.", - "createNewConnection.undefined.password": "Operation Cancelled", + "createNewConnection.undefined.passWord": "Operation Cancelled", "createNewConnection.option.prompt.ru.placeholder": "Reject Unauthorized Connections", "createNewConnection.rejectUnauthorize": "Operation Cancelled", "createNewConnection.duplicateProfileName": "Profile name already exists. Please create a profile using a different name", "promptcredentials.option.prompt.username.placeholder": "User Name", "promptcredentials.option.prompt.username": "Enter the user name for the connection", "promptcredentials.invalidusername": "Please enter your z/OS username. Operation Cancelled", - "promptcredentials.option.prompt.password.placeholder": "Password", + "promptcredentials.option.prompt.passWord.placeholder": "Password", "promptcredentials.option.prompt.password": "Enter a password for the connection", "promptcredentials.invalidpassword": "Please enter your z/OS password. Operation Cancelled" } \ No newline at end of file diff --git a/i18n/sample/src/ZosJobsProvider.i18n.json b/i18n/sample/src/ZosJobsProvider.i18n.json index c8b1d0a3c4..4d4389b4d1 100644 --- a/i18n/sample/src/ZosJobsProvider.i18n.json +++ b/i18n/sample/src/ZosJobsProvider.i18n.json @@ -1,5 +1,5 @@ { - "FavoriteSession": "Favorites", + "Favorites": "Favorites", "deleteJob.job": "Job ", "deleteJob.delete": " deleted", "initializeFavorites.log.debug": "initializing favorites", diff --git a/i18n/sample/src/extension.i18n.json b/i18n/sample/src/extension.i18n.json index 828e39df27..ad91ec109a 100644 --- a/i18n/sample/src/extension.i18n.json +++ b/i18n/sample/src/extension.i18n.json @@ -22,13 +22,12 @@ "submitMember.error.invalidNode": "submitMember() called from invalid node.", "submitMember.jobSubmitted": "Job submitted ", "submitMember.jobSubmissionFailed": "Job submission failed\n", - "addSession.quickPickOption": "Choose \"Create new...\" to define a new profile or select an existing profile to Add to the Jobs Explorer", + "addSession.quickPickOption": "Choose \"Create new...\" to define a new profile or select an existing profile to Add to the USS Explorer", + "enterPattern.pattern": "You must enter a pattern.", "createNewConnection.option.prompt.profileName.placeholder": "Connection Name", "createNewConnection.option.prompt.profileName": "Enter a name for the connection", "createNewConnection.enterprofileName": "Profile Name was not supplied. Operation Cancelled", "addSession.log.debug.createNewProfile": "User created a new profile", - "addSession.log.debug.selectedProfile": "User selected profile ", - "addSession.log.debug.cancelledSelection": "Operation Cancelled", "addZoweSession.log.debug.selectProfile": "User selected profile ", "addZoweSession.log.debug.cancelledSelection": "User cancelled profile selection", "createFile.quickPickOption.dataSetType": "Type of Data Set to be Created", @@ -67,7 +66,6 @@ "deleteDataSet.notFound.error2": " was probably already deleted.", "enterPattern.log.debug.prompt": "Prompting the user for a data set pattern", "enterPattern.options.prompt": "Search data sets by entering patterns: use a comma to separate multiple patterns", - "enterPattern.pattern": "You must enter a pattern.", "openPS.invalidNode": "openPS() called from invalid node.", "openPS.error.invalidNode": "openPS() called from invalid node.", "openPS.log.debug.openDataSet": "opening physical sequential data set from label ", @@ -103,7 +101,5 @@ "modifyCommand.response": "Command response: ", "stopCommand.response": "Command response: ", "setOwner.newOwner.prompt.owner": "Owner", - "setOwner.newOwner.prompt.prefix": "Prefix", - "addJobsSession.log.debug.selectedProfile": "User selected profile ", - "addJobsSession.log.debug.cancelledProfile": "User cancelled profile selection" + "setOwner.newOwner.prompt.prefix": "Prefix" } \ No newline at end of file diff --git a/src/ZoweUSSNode.ts b/src/ZoweUSSNode.ts index 7bdb5e0915..cd9d48a960 100644 --- a/src/ZoweUSSNode.ts +++ b/src/ZoweUSSNode.ts @@ -85,7 +85,7 @@ export class ZoweUSSNode extends ZoweTreeNode implements IZoweUSSTreeNode { /** * Implements access to profile name - * for {IZoweTreeNode}. + * for {IZoweUSSTreeNode}. * * @returns {string} */ diff --git a/src/api/ZoweTree.ts b/src/api/ZoweTree.ts index f8c7f8b5ce..1e2f6d8307 100644 --- a/src/api/ZoweTree.ts +++ b/src/api/ZoweTree.ts @@ -174,6 +174,10 @@ export interface IZoweUSSTreeNode extends IZoweTreeNode { * Binary indicator. Default false (text) */ binary?: boolean; + /** + * Specific profile name in use with this node + */ + mProfileName?: string; /** * Retrieves child nodes of this IZoweUSSTreeNode diff --git a/src/extension.ts b/src/extension.ts index ca581b6971..891d80465c 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -1279,8 +1279,7 @@ export function getProfile(node: IZoweTreeNode) { * @param {ZoweUSSNode} node */ export function getUSSProfile(node: IZoweUSSTreeNode) { - const profile = node.getSessionNode().getProfileName(); - return profile; + return node.getSessionNode().getProfileName(); } /** diff --git a/src/jobs/jobNodeActions.ts b/src/jobs/jobNodeActions.ts index 0623a159e7..9c3c93b5df 100644 --- a/src/jobs/jobNodeActions.ts +++ b/src/jobs/jobNodeActions.ts @@ -17,7 +17,7 @@ const localize = nls.config({ messageFormat: nls.MessageFormat.file })(); export async function deleteJob(node: Job) { try { - await DeleteJobs.deleteJob(node.getSession(), node.job.jobname, node.job.jobid); + await DeleteJobs.deleteJob(node.getSession(), node.job.jobname, node.job.jobid); vscode.window.showInformationMessage(localize("deleteJob.job", "Job ") + node.job.jobname + "(" + node.job.jobid + ")" + localize("deleteJob.delete", " deleted")); } catch (error) { From 769b8e40a209d2057ab30bdfacc3435a1a7ee4f8 Mon Sep 17 00:00:00 2001 From: Colin Stone <30794003+Colin-Stone@users.noreply.github.com> Date: Mon, 6 Jan 2020 11:07:39 +0000 Subject: [PATCH 03/19] Code merge updates Signed-off-by: Colin Stone <30794003+Colin-Stone@users.noreply.github.com> --- src/DatasetTree.ts | 18 ++++++++---------- src/api/ZoweTree.ts | 5 +++++ src/extension.ts | 6 +++--- 3 files changed, 16 insertions(+), 13 deletions(-) diff --git a/src/DatasetTree.ts b/src/DatasetTree.ts index 37cea56408..7b630ddb6b 100644 --- a/src/DatasetTree.ts +++ b/src/DatasetTree.ts @@ -45,9 +45,7 @@ export class DatasetTree extends ZoweTreeProvider implements IZoweTree extends vscode.TreeDataProvider { * Refreshes the tree */ refresh(): void; + /** + * Refreshes an element of the tree + * @param favorite Node to refresh + */ + refreshElement(node: IZoweTreeNode): void; } /** * The base interface for Zowe tree nodes. diff --git a/src/extension.ts b/src/extension.ts index 2834537f12..775af928e6 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -1391,7 +1391,7 @@ export function getUSSDocumentFilePath(node: IZoweUSSTreeNode) { * * @param {IZoweDatasetTreeNode} node */ -export async function openPS(node: IZoweDatasetTreeNode, previewMember: boolean, datasetProvider?: IZoweDatasetTree) { +export async function openPS(node: IZoweDatasetTreeNode, previewMember: boolean, datasetProvider?: IZoweTree) { let sesNamePrompt: string; if (node.contextValue.endsWith(FAV_SUFFIX)) { sesNamePrompt = node.getLabel().substring(1, node.getLabel().indexOf("]")); @@ -1826,7 +1826,7 @@ export async function saveUSSFile(doc: vscode.TextDocument, ussFileProvider: USS * * @param {IZoweTreeNode} node */ -export async function openUSS(node: IZoweUSSTreeNode, download = false, previewFile: boolean, ussFileProvider?: IZoweUSSTree) { +export async function openUSS(node: IZoweUSSTreeNode, download = false, previewFile: boolean, ussFileProvider?: IZoweTree) { if ((!node.getSession().ISession.user) || (!node.getSession().ISession.password)) { try { const values = await Profiles.getInstance().promptCredentials(node.getProfileName()); @@ -1970,7 +1970,7 @@ export async function setPrefix(job: IZoweJobTreeNode, jobsProvider: ZosJobsProv jobsProvider.refreshElement(job); } -export async function refreshJobsServer(node: IZoweJobTreeNode, jobsProvider: IZoweJobTree) { +export async function refreshJobsServer(node: IZoweJobTreeNode, jobsProvider: IZoweTree) { let sesNamePrompt: string; if (node.contextValue.endsWith(FAV_SUFFIX)) { sesNamePrompt = node.label.substring(1, node.label.indexOf("]")); From 79cc428e0da8fce0a6a3aaa6867e5691424283b6 Mon Sep 17 00:00:00 2001 From: Colin Stone <30794003+Colin-Stone@users.noreply.github.com> Date: Mon, 6 Jan 2020 11:45:50 +0000 Subject: [PATCH 04/19] Profile name ambiguity Signed-off-by: Colin Stone <30794003+Colin-Stone@users.noreply.github.com> --- src/ZoweJobNode.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ZoweJobNode.ts b/src/ZoweJobNode.ts index f81c888098..74ee45eb45 100644 --- a/src/ZoweJobNode.ts +++ b/src/ZoweJobNode.ts @@ -54,7 +54,7 @@ export class Job extends ZoweTreeNode implements IZoweJobTreeNode { * @returns {string} */ public getProfileName(): string { - return this.getLabel(); + return this.getSessionNode().getLabel(); } /** From c3d6b4aeccea855d65c0c2fcffc75b215cbb5b9c Mon Sep 17 00:00:00 2001 From: Colin Stone <30794003+Colin-Stone@users.noreply.github.com> Date: Tue, 21 Jan 2020 09:49:20 +0000 Subject: [PATCH 05/19] Implemented new files Signed-off-by: Colin Stone <30794003+Colin-Stone@users.noreply.github.com> --- .../DatasetTree.integration.test.ts | 42 ++-- .../ZoweNode.integration.test.ts | 56 ++--- .../extension.integration.test.ts | 52 ++--- __tests__/__unit__/DatasetTree.unit.test.ts | 118 +++++----- __tests__/__unit__/ZoweNode.unit.test.ts | 78 +++---- __tests__/__unit__/extension.unit.test.ts | 202 +++++++++--------- .../__unit__/mvs/mvsNodeActions.unit.test.ts | 10 +- .../__unit__/uss/ussNodeActions.unit.test.ts | 31 --- i18n/sample/src/ZoweDatasetNode.i18n.json | 7 + i18n/sample/src/uss/ussNodeActions.i18n.json | 6 +- src/DatasetTree.ts | 82 ++----- src/USSTree.ts | 5 +- src/ZosJobsProvider.ts | 58 +---- src/{ZoweNode.ts => ZoweDatasetNode.ts} | 43 ++-- src/ZoweJobNode.ts | 2 +- src/ZoweUSSNode.ts | 2 +- src/__mocks__/DatasetTree.ts | 36 ++-- src/abstract/ZoweTreeNode.ts | 6 +- src/abstract/ZoweTreeProvider.ts | 2 +- src/api/IZoweTree.ts | 62 ++++++ src/api/{ZoweTree.ts => IZoweTreeNode.ts} | 50 +---- src/extension.ts | 42 ++-- src/jobs/jobNodeActions.ts | 27 --- src/mvs/mvsNodeActions.ts | 8 +- src/uss/ussNodeActions.ts | 31 +-- src/utils.ts | 2 +- stringUpdateScript.js | 4 +- 27 files changed, 449 insertions(+), 615 deletions(-) create mode 100644 i18n/sample/src/ZoweDatasetNode.i18n.json rename src/{ZoweNode.ts => ZoweDatasetNode.ts} (79%) create mode 100644 src/api/IZoweTree.ts rename src/api/{ZoweTree.ts => IZoweTreeNode.ts} (81%) delete mode 100644 src/jobs/jobNodeActions.ts diff --git a/__tests__/__integration__/DatasetTree.integration.test.ts b/__tests__/__integration__/DatasetTree.integration.test.ts index efb9ea1f29..686ddebf91 100644 --- a/__tests__/__integration__/DatasetTree.integration.test.ts +++ b/__tests__/__integration__/DatasetTree.integration.test.ts @@ -15,7 +15,7 @@ import * as zowe from "@brightside/core"; import * as expect from "expect"; import * as vscode from "vscode"; import { DatasetTree } from "../../src/DatasetTree"; -import { ZoweNode } from "../../src/ZoweNode"; +import { ZoweDatasetNode } from "../../src/ZoweDatasetNode"; import * as testConst from "../../resources/testProfileData"; import * as sinon from "sinon"; import * as chai from "chai"; @@ -29,7 +29,7 @@ describe("DatasetTree Integration Tests", async () => { chai.use(chaiAsPromised); // Uses loaded profile to create a zosmf session with brightside const session = zowe.ZosmfSession.createBasicZosmfSession(testConst.profile); - const sessNode = new ZoweNode(testConst.profile.name, vscode.TreeItemCollapsibleState.Expanded, null, session); + const sessNode = new ZoweDatasetNode(testConst.profile.name, vscode.TreeItemCollapsibleState.Expanded, null, session); sessNode.contextValue = extension.DS_SESSION_CONTEXT; const pattern = testConst.normalPattern.toUpperCase(); sessNode.pattern = pattern + ".PUBLIC"; @@ -61,7 +61,7 @@ describe("DatasetTree Integration Tests", async () => { * Calls getTreeItem with sample element and checks the return is vscode.TreeItem *************************************************************************************************************/ it("Tests the getTreeItem method", async () => { - const sampleElement = new ZoweNode("testValue", vscode.TreeItemCollapsibleState.None, null, null); + const sampleElement = new ZoweDatasetNode("testValue", vscode.TreeItemCollapsibleState.None, null, null); chai.expect(testTree.getTreeItem(sampleElement)).to.be.instanceOf(vscode.TreeItem); }); @@ -76,23 +76,23 @@ describe("DatasetTree Integration Tests", async () => { sessChildren[2].dirty = true; const PDSChildren = await testTree.getChildren(sessChildren[2]); - const sampleRChildren: ZoweNode[] = [ - new ZoweNode(pattern + ".PUBLIC.BIN", vscode.TreeItemCollapsibleState.None, sessNode, null), - new ZoweNode(pattern + ".PUBLIC.TCLASSIC", vscode.TreeItemCollapsibleState.Collapsed, sessNode, null), - new ZoweNode(pattern + ".PUBLIC.TPDS", vscode.TreeItemCollapsibleState.Collapsed, sessNode, null), - new ZoweNode(pattern + ".PUBLIC.TPS", vscode.TreeItemCollapsibleState.None, sessNode, null), + const sampleRChildren: ZoweDatasetNode[] = [ + new ZoweDatasetNode(pattern + ".PUBLIC.BIN", vscode.TreeItemCollapsibleState.None, sessNode, null), + new ZoweDatasetNode(pattern + ".PUBLIC.TCLASSIC", vscode.TreeItemCollapsibleState.Collapsed, sessNode, null), + new ZoweDatasetNode(pattern + ".PUBLIC.TPDS", vscode.TreeItemCollapsibleState.Collapsed, sessNode, null), + new ZoweDatasetNode(pattern + ".PUBLIC.TPS", vscode.TreeItemCollapsibleState.None, sessNode, null), ]; - sampleRChildren[0].command = {command: "zowe.ZoweNode.openPS", title: "", arguments: [sampleRChildren[0]]}; - sampleRChildren[3].command = {command: "zowe.ZoweNode.openPS", title: "", arguments: [sampleRChildren[3]]}; + sampleRChildren[0].command = {command: "zowe.ZoweDatasetNode.openPS", title: "", arguments: [sampleRChildren[0]]}; + sampleRChildren[3].command = {command: "zowe.ZoweDatasetNode.openPS", title: "", arguments: [sampleRChildren[3]]}; - const samplePChildren: ZoweNode[] = [ - new ZoweNode("TCHILD1", vscode.TreeItemCollapsibleState.None, sampleRChildren[2], null), - new ZoweNode("TCHILD2", vscode.TreeItemCollapsibleState.None, sampleRChildren[2], null), + const samplePChildren: ZoweDatasetNode[] = [ + new ZoweDatasetNode("TCHILD1", vscode.TreeItemCollapsibleState.None, sampleRChildren[2], null), + new ZoweDatasetNode("TCHILD2", vscode.TreeItemCollapsibleState.None, sampleRChildren[2], null), ]; - samplePChildren[0].command = {command: "zowe.ZoweNode.openPS", title: "", arguments: [samplePChildren[0]]}; - samplePChildren[1].command = {command: "zowe.ZoweNode.openPS", title: "", arguments: [samplePChildren[1]]}; + samplePChildren[0].command = {command: "zowe.ZoweDatasetNode.openPS", title: "", arguments: [samplePChildren[0]]}; + samplePChildren[1].command = {command: "zowe.ZoweDatasetNode.openPS", title: "", arguments: [samplePChildren[1]]}; sampleRChildren[2].children = samplePChildren; // Checking that the rootChildren are what they are expected to be @@ -136,18 +136,18 @@ describe("DatasetTree Integration Tests", async () => { /************************************************************************************************************* * Creates a child with a rootNode as parent and checks that a getParent() call returns null. - * Also creates a child with a non-rootNode parent and checks that getParent() returns the correct ZoweNode + * Also creates a child with a non-rootNode parent and checks that getParent() returns the correct ZoweDatasetNode *************************************************************************************************************/ - it("Tests that getParent returns the correct ZoweNode when called on a non-rootNode ZoweNode", async () => { + it("Tests that getParent returns the correct ZoweDatasetNode when called on a non-rootNode ZoweDatasetNode", async () => { // Creating structure of files and folders under BRTVS99 profile - const sampleChild1: ZoweNode = new ZoweNode(pattern + ".TPDS", vscode.TreeItemCollapsibleState.None, sessNode, null); + const sampleChild1: ZoweDatasetNode = new ZoweDatasetNode(pattern + ".TPDS", vscode.TreeItemCollapsibleState.None, sessNode, null); const parent1 = testTree.getParent(sampleChild1); // It's expected that parent is null because when getParent() is called on a child // of the rootNode, it should return null expect(parent1).toBe(sessNode); - const sampleChild2: ZoweNode = new ZoweNode(pattern + ".TPDS(TCHILD1)", + const sampleChild2: ZoweDatasetNode = new ZoweDatasetNode(pattern + ".TPDS(TCHILD1)", vscode.TreeItemCollapsibleState.None, sampleChild1, null); const parent2 = testTree.getParent(sampleChild2); @@ -186,7 +186,7 @@ describe("DatasetTree Integration Tests", async () => { describe("addFavorite()", () => { it("should add the selected data set to the treeView", async () => { - const favoriteNode = new ZoweNode(pattern + ".TPDS", vscode.TreeItemCollapsibleState.Collapsed, sessNode, null); + const favoriteNode = new ZoweDatasetNode(pattern + ".TPDS", vscode.TreeItemCollapsibleState.Collapsed, sessNode, null); const len = testTree.mFavorites.length; await testTree.addFavorite(favoriteNode); const filtered = testTree.mFavorites.filter((temp) => temp.label === @@ -208,7 +208,7 @@ describe("DatasetTree Integration Tests", async () => { describe("removeFavorite()", () => { it("should remove the selected favorite data set from the treeView", () => { - const favoriteNode = new ZoweNode(pattern + ".TPDS", + const favoriteNode = new ZoweDatasetNode(pattern + ".TPDS", vscode.TreeItemCollapsibleState.Collapsed, sessNode, null); testTree.addFavorite(favoriteNode); const len = testTree.mFavorites.length; diff --git a/__tests__/__integration__/ZoweNode.integration.test.ts b/__tests__/__integration__/ZoweNode.integration.test.ts index 52fd13eac2..82d83e851a 100644 --- a/__tests__/__integration__/ZoweNode.integration.test.ts +++ b/__tests__/__integration__/ZoweNode.integration.test.ts @@ -15,35 +15,35 @@ import * as chaiAsPromised from "chai-as-promised"; // tslint:disable-next-line:no-implicit-dependencies import * as expect from "expect"; import * as vscode from "vscode"; -import { ZoweNode } from "../../src/ZoweNode"; +import { ZoweDatasetNode } from "../../src/ZoweDatasetNode"; import * as testConst from "../../resources/testProfileData"; import * as extension from "../../src/extension"; declare var it: any; -describe("ZoweNode Integration Tests", async () => { +describe("ZoweDatasetNode Integration Tests", async () => { const TIMEOUT = 120000; chai.use(chaiAsPromised); // Uses loaded profile to create a zosmf session with brightside const session = zowe.ZosmfSession.createBasicZosmfSession(testConst.profile); - const sessNode = new ZoweNode(testConst.profile.name, vscode.TreeItemCollapsibleState.Expanded, null, session); + const sessNode = new ZoweDatasetNode(testConst.profile.name, vscode.TreeItemCollapsibleState.Expanded, null, session); sessNode.contextValue = extension.DS_SESSION_CONTEXT; sessNode.dirty = true; const pattern = testConst.normalPattern.toUpperCase(); sessNode.pattern = pattern + ".PUBLIC"; /************************************************************************************************************* - * Creates an ZoweNode and checks that its members are all initialized by the constructor + * Creates an ZoweDatasetNode and checks that its members are all initialized by the constructor *************************************************************************************************************/ - it("Testing that the ZoweNode is defined", async () => { + it("Testing that the ZoweDatasetNode is defined", async () => { // Tests empty PO node - const emptyPONode = new ZoweNode(pattern + ".TCLASSIC", vscode.TreeItemCollapsibleState.Collapsed, sessNode, null); + const emptyPONode = new ZoweDatasetNode(pattern + ".TCLASSIC", vscode.TreeItemCollapsibleState.Collapsed, sessNode, null); expect(emptyPONode.label).toBeDefined(); expect(emptyPONode.collapsibleState).toBeDefined(); expect(emptyPONode.getParent()).toBeDefined(); // Tests PS node - const PSNode = new ZoweNode(pattern + ".TPS", vscode.TreeItemCollapsibleState.None, sessNode, null); + const PSNode = new ZoweDatasetNode(pattern + ".TPS", vscode.TreeItemCollapsibleState.None, sessNode, null); expect(PSNode.label).toBeDefined(); expect(PSNode.collapsibleState).toBeDefined(); @@ -51,11 +51,11 @@ describe("ZoweNode Integration Tests", async () => { }); /************************************************************************************************************* - * Checks that the ZoweNode constructor works as expected when the label parameter is the empty string + * Checks that the ZoweDatasetNode constructor works as expected when the label parameter is the empty string *************************************************************************************************************/ - it("Testing that the ZoweNode constructor works as expected when the label parameter is the empty string", async () => { - // The ZoweNode should still be constructed, and should not throw an error. - const edgeNode = new ZoweNode("", vscode.TreeItemCollapsibleState.None, sessNode, null); + it("Testing that the ZoweDatasetNode constructor works as expected when the label parameter is the empty string", async () => { + // The ZoweDatasetNode should still be constructed, and should not throw an error. + const edgeNode = new ZoweDatasetNode("", vscode.TreeItemCollapsibleState.None, sessNode, null); expect(edgeNode.label).toBeDefined(); expect(edgeNode.collapsibleState).toBeDefined(); @@ -63,9 +63,9 @@ describe("ZoweNode Integration Tests", async () => { }); /************************************************************************************************************* - * Creates sample ZoweNode list and checks that getChildren() returns the correct array + * Creates sample ZoweDatasetNode list and checks that getChildren() returns the correct array *************************************************************************************************************/ - it("Testing that getChildren returns the correct Thenable", async () => { + it("Testing that getChildren returns the correct Thenable", async () => { let sessChildren; try { sessChildren = await sessNode.getChildren(); @@ -75,44 +75,44 @@ describe("ZoweNode Integration Tests", async () => { } // Creating structure of files and folders under BRTVS99 profile - const sampleChildren: ZoweNode[] = [ - new ZoweNode(pattern + ".PUBLIC.BIN", vscode.TreeItemCollapsibleState.None, sessNode, null), - new ZoweNode(pattern + ".PUBLIC.TCLASSIC", vscode.TreeItemCollapsibleState.Collapsed, sessNode, null), - new ZoweNode(pattern + ".PUBLIC.TPDS", vscode.TreeItemCollapsibleState.Collapsed, sessNode, null), - new ZoweNode(pattern + ".PUBLIC.TPS", vscode.TreeItemCollapsibleState.None, sessNode, null) + const sampleChildren: ZoweDatasetNode[] = [ + new ZoweDatasetNode(pattern + ".PUBLIC.BIN", vscode.TreeItemCollapsibleState.None, sessNode, null), + new ZoweDatasetNode(pattern + ".PUBLIC.TCLASSIC", vscode.TreeItemCollapsibleState.Collapsed, sessNode, null), + new ZoweDatasetNode(pattern + ".PUBLIC.TPDS", vscode.TreeItemCollapsibleState.Collapsed, sessNode, null), + new ZoweDatasetNode(pattern + ".PUBLIC.TPS", vscode.TreeItemCollapsibleState.None, sessNode, null) ]; - sampleChildren[0].command = { command: "zowe.ZoweNode.openPS", title: "", arguments: [sampleChildren[0]] }; + sampleChildren[0].command = { command: "zowe.ZoweDatasetNode.openPS", title: "", arguments: [sampleChildren[0]] }; // tslint:disable-next-line:no-magic-numbers - sampleChildren[3].command = { command: "zowe.ZoweNode.openPS", title: "", arguments: [sampleChildren[3]] }; + sampleChildren[3].command = { command: "zowe.ZoweDatasetNode.openPS", title: "", arguments: [sampleChildren[3]] }; // Checking that the rootChildren are what they are expected to be expect(sessChildren).toEqual(sampleChildren); }).timeout(TIMEOUT); /************************************************************************************************************* - * Checks that getChildren() returns the expected value when passed an ZoweNode with all null parameters + * Checks that getChildren() returns the expected value when passed an ZoweDatasetNode with all null parameters *************************************************************************************************************/ it("Testing that getChildren works as expected on the null value", async () => { const expectChai = chai.expect; chai.use(chaiAsPromised); // The method should throw an error. - const nullNode = new ZoweNode(null, null, null, null); + const nullNode = new ZoweDatasetNode(null, null, null, null); nullNode.contextValue = extension.DS_PDS_CONTEXT; nullNode.dirty = true; await expectChai(nullNode.getChildren()).to.eventually.be.rejectedWith("Invalid node"); }).timeout(TIMEOUT); /************************************************************************************************************* - * Checks that getChildren() returns the expected value when passed an ZoweNode with all undefined parameters + * Checks that getChildren() returns the expected value when passed an ZoweDatasetNode with all undefined parameters *************************************************************************************************************/ it("Testing that getChildren works as expected on an undefined value", async () => { const expectChai = chai.expect; chai.use(chaiAsPromised); // The method should throw an error. - const undefinedNode = new ZoweNode(undefined, undefined, undefined, undefined); + const undefinedNode = new ZoweDatasetNode(undefined, undefined, undefined, undefined); undefinedNode.contextValue = extension.DS_PDS_CONTEXT; undefinedNode.dirty = true; // tslint:disable-next-line:max-line-length @@ -125,7 +125,7 @@ describe("ZoweNode Integration Tests", async () => { *************************************************************************************************************/ it("Testing that getChildren works as expected on a PS node", async () => { // The method should return an empty array. - const PSNode = new ZoweNode(pattern + ".TPS", vscode.TreeItemCollapsibleState.None, sessNode, null); + const PSNode = new ZoweDatasetNode(pattern + ".TPS", vscode.TreeItemCollapsibleState.None, sessNode, null); let PSNodeChildren; try { PSNodeChildren = await PSNode.getChildren(); @@ -142,9 +142,9 @@ describe("ZoweNode Integration Tests", async () => { * Checks that getSession() returns the expected value *************************************************************************************************************/ it("Testing that getSession() works as expected", async () => { - const PDSNode = new ZoweNode(pattern + ".TPDS", vscode.TreeItemCollapsibleState.Collapsed, sessNode, null); - const PSNode = new ZoweNode(pattern + ".TPS", vscode.TreeItemCollapsibleState.None, sessNode, null); - const MemNode = new ZoweNode(pattern + ".TPDS(TCHILD1)", vscode.TreeItemCollapsibleState.None, PDSNode, null); + const PDSNode = new ZoweDatasetNode(pattern + ".TPDS", vscode.TreeItemCollapsibleState.Collapsed, sessNode, null); + const PSNode = new ZoweDatasetNode(pattern + ".TPS", vscode.TreeItemCollapsibleState.None, sessNode, null); + const MemNode = new ZoweDatasetNode(pattern + ".TPDS(TCHILD1)", vscode.TreeItemCollapsibleState.None, PDSNode, null); expect(sessNode.getSession()).toEqual(session); expect(PDSNode.getSession()).toEqual(session); diff --git a/__tests__/__integration__/extension.integration.test.ts b/__tests__/__integration__/extension.integration.test.ts index 0f064e2147..449a12cd99 100644 --- a/__tests__/__integration__/extension.integration.test.ts +++ b/__tests__/__integration__/extension.integration.test.ts @@ -23,10 +23,10 @@ import * as testConst from "../../resources/testProfileData"; import * as vscode from "vscode"; import * as utils from "../../src/utils"; import { DatasetTree, createDatasetTree } from "../../src/DatasetTree"; -import { ZoweNode } from "../../src/ZoweNode"; +import { ZoweDatasetNode } from "../../src/ZoweDatasetNode"; import { USSTree } from "../../src/USSTree"; import { ZoweUSSNode } from "../../src/ZoweUSSNode"; -import { IZoweTreeNode } from "../../src/api/ZoweTree"; +import { IZoweTreeNode } from "../../src/api/IZoweTreeNode"; const TIMEOUT = 45000; declare var it: Mocha.ITestDefinition; @@ -37,7 +37,7 @@ describe("Extension Integration Tests", () => { chai.use(chaiAsPromised); const session = zowe.ZosmfSession.createBasicZosmfSession(testConst.profile); - const sessionNode = new ZoweNode(testConst.profile.name, vscode.TreeItemCollapsibleState.Expanded, null, session); + const sessionNode = new ZoweDatasetNode(testConst.profile.name, vscode.TreeItemCollapsibleState.Expanded, null, session); sessionNode.contextValue = extension.DS_SESSION_CONTEXT; const pattern = testConst.normalPattern.toUpperCase(); sessionNode.pattern = pattern; @@ -141,7 +141,7 @@ describe("Extension Integration Tests", () => { inputBoxStub.returns(testFileName); const testParentName = pattern + ".EXT.SAMPLE.PDS"; - const testParentNode = new ZoweNode(testParentName, vscode.TreeItemCollapsibleState.Collapsed, sessionNode, session); + const testParentNode = new ZoweDatasetNode(testParentName, vscode.TreeItemCollapsibleState.Collapsed, sessionNode, session); await extension.createMember(testParentNode, testTree); const allMembers = await zowe.List.allMembers(session, testParentName); @@ -184,7 +184,7 @@ describe("Extension Integration Tests", () => { }); it("should delete a data set if user verified", async () => { await zowe.Create.dataSet(sessionNode.getSession(), zowe.CreateDataSetTypeEnum.DATA_SET_SEQUENTIAL, dataSetName); - const testNode = new ZoweNode(dataSetName, vscode.TreeItemCollapsibleState.None, sessionNode, session); + const testNode = new ZoweDatasetNode(dataSetName, vscode.TreeItemCollapsibleState.None, sessionNode, session); // Mock user selecting first option from list const quickPickStub = sandbox.stub(vscode.window, "showQuickPick"); @@ -197,7 +197,7 @@ describe("Extension Integration Tests", () => { }).timeout(TIMEOUT); it("should not delete a data set if user did not verify", async () => { await zowe.Create.dataSet(sessionNode.getSession(), zowe.CreateDataSetTypeEnum.DATA_SET_SEQUENTIAL, dataSetName); - const testNode = new ZoweNode(dataSetName, vscode.TreeItemCollapsibleState.None, sessionNode, session); + const testNode = new ZoweDatasetNode(dataSetName, vscode.TreeItemCollapsibleState.None, sessionNode, session); // Mock user selecting second option from list const quickPickStub = sandbox.stub(vscode.window, "showQuickPick"); @@ -213,7 +213,7 @@ describe("Extension Integration Tests", () => { }).timeout(TIMEOUT); it("should delete a data set if user cancelled", async () => { await zowe.Create.dataSet(sessionNode.getSession(), zowe.CreateDataSetTypeEnum.DATA_SET_SEQUENTIAL, dataSetName); - const testNode = new ZoweNode(dataSetName, vscode.TreeItemCollapsibleState.None, sessionNode, session); + const testNode = new ZoweDatasetNode(dataSetName, vscode.TreeItemCollapsibleState.None, sessionNode, session); // Mock user not selecting any option from list const quickPickStub = sandbox.stub(vscode.window, "showQuickPick"); @@ -284,7 +284,7 @@ describe("Extension Integration Tests", () => { it("should work when called from a saved search", async () => { const searchPattern = pattern + ".search"; - const favoriteSearch = new ZoweNode("[" + testConst.profile.name + "]: " + searchPattern, + const favoriteSearch = new ZoweDatasetNode("[" + testConst.profile.name + "]: " + searchPattern, vscode.TreeItemCollapsibleState.None, testTree.mFavoriteSession, null); favoriteSearch.contextValue = extension.DS_SESSION_CONTEXT + extension.FAV_SUFFIX; await extension.enterPattern(favoriteSearch, testTree); @@ -307,7 +307,7 @@ describe("Extension Integration Tests", () => { describe("Opening a PS", () => { it("should open a PS", async () => { - const node = new ZoweNode(pattern + ".EXT.PS", vscode.TreeItemCollapsibleState.None, sessionNode, null); + const node = new ZoweDatasetNode(pattern + ".EXT.PS", vscode.TreeItemCollapsibleState.None, sessionNode, null); await extension.openPS(node, true); expect(path.relative(vscode.window.activeTextEditor.document.fileName, extension.getDocumentFilePath(pattern + ".EXT.PS", node))).to.equal(""); @@ -315,7 +315,7 @@ describe("Extension Integration Tests", () => { }).timeout(TIMEOUT); it("should display an error message when openPS is passed an invalid node", async () => { - const node = new ZoweNode(pattern + ".GARBAGE", vscode.TreeItemCollapsibleState.None, sessionNode, null); + const node = new ZoweDatasetNode(pattern + ".GARBAGE", vscode.TreeItemCollapsibleState.None, sessionNode, null); const errorMessageStub = sandbox.spy(vscode.window, "showErrorMessage"); await expect(extension.openPS(node, true)).to.eventually.be.rejectedWith(Error); @@ -410,7 +410,7 @@ describe("Extension Integration Tests", () => { let afterList; try { - const testNode = new ZoweNode(beforeDataSetName, vscode.TreeItemCollapsibleState.None, sessionNode, session); + const testNode = new ZoweDatasetNode(beforeDataSetName, vscode.TreeItemCollapsibleState.None, sessionNode, session); const inputBoxStub = sandbox.stub(vscode.window, "showInputBox"); inputBoxStub.returns(afterDataSetName); @@ -445,8 +445,8 @@ describe("Extension Integration Tests", () => { let list; try { - const parentNode = new ZoweNode(beforeDataSetName, vscode.TreeItemCollapsibleState.None, sessionNode, session); - const childNode = new ZoweNode("mem1", vscode.TreeItemCollapsibleState.None, parentNode, session); + const parentNode = new ZoweDatasetNode(beforeDataSetName, vscode.TreeItemCollapsibleState.None, sessionNode, session); + const childNode = new ZoweDatasetNode("mem1", vscode.TreeItemCollapsibleState.None, parentNode, session); const inputBoxStub = sandbox.stub(vscode.window, "showInputBox"); inputBoxStub.returns("mem2"); @@ -476,7 +476,7 @@ describe("Extension Integration Tests", () => { let afterList; try { - const testNode = new ZoweNode(beforeDataSetName, vscode.TreeItemCollapsibleState.None, sessionNode, session); + const testNode = new ZoweDatasetNode(beforeDataSetName, vscode.TreeItemCollapsibleState.None, sessionNode, session); const inputBoxStub = sandbox.stub(vscode.window, "showInputBox"); inputBoxStub.returns(afterDataSetName); @@ -501,7 +501,7 @@ describe("Extension Integration Tests", () => { let error; try { - const testNode = new ZoweNode(beforeDataSetName, vscode.TreeItemCollapsibleState.None, sessionNode, session); + const testNode = new ZoweDatasetNode(beforeDataSetName, vscode.TreeItemCollapsibleState.None, sessionNode, session); const inputBoxStub = sandbox.stub(vscode.window, "showInputBox"); inputBoxStub.returns("MISSING.DATA.SET"); @@ -518,8 +518,8 @@ describe("Extension Integration Tests", () => { let error; try { - const parentNode = new ZoweNode(beforeDataSetName, vscode.TreeItemCollapsibleState.None, sessionNode, session); - const childNode = new ZoweNode("mem1", vscode.TreeItemCollapsibleState.None, parentNode, session); + const parentNode = new ZoweDatasetNode(beforeDataSetName, vscode.TreeItemCollapsibleState.None, sessionNode, session); + const childNode = new ZoweDatasetNode("mem1", vscode.TreeItemCollapsibleState.None, parentNode, session); const inputBoxStub = sandbox.stub(vscode.window, "showInputBox"); inputBoxStub.returns("mem2"); @@ -568,8 +568,8 @@ describe("Extension Integration Tests", () => { let contents; try { - const fromNode = new ZoweNode(fromDataSetName, vscode.TreeItemCollapsibleState.None, sessionNode, session); - const toNode = new ZoweNode(toDataSetName, vscode.TreeItemCollapsibleState.None, sessionNode, session); + const fromNode = new ZoweDatasetNode(fromDataSetName, vscode.TreeItemCollapsibleState.None, sessionNode, session); + const toNode = new ZoweDatasetNode(toDataSetName, vscode.TreeItemCollapsibleState.None, sessionNode, session); await extension.copyDataSet(fromNode); await extension.pasteDataSet(toNode, testTree); @@ -606,8 +606,8 @@ describe("Extension Integration Tests", () => { let contents; try { - const parentNode = new ZoweNode(dataSetName, vscode.TreeItemCollapsibleState.None, sessionNode, session); - const fromNode = new ZoweNode(fromMemberName, vscode.TreeItemCollapsibleState.None, parentNode, session); + const parentNode = new ZoweDatasetNode(dataSetName, vscode.TreeItemCollapsibleState.None, sessionNode, session); + const fromNode = new ZoweDatasetNode(fromMemberName, vscode.TreeItemCollapsibleState.None, parentNode, session); parentNode.contextValue = extension.DS_PDS_CONTEXT; fromNode.contextValue = extension.DS_MEMBER_CONTEXT; @@ -660,8 +660,8 @@ describe("Extension Integration Tests", () => { let contents; try { - const fromNode = new ZoweNode(fromDataSetName, vscode.TreeItemCollapsibleState.None, sessionNode, session); - const toNode = new ZoweNode(toDataSetName, vscode.TreeItemCollapsibleState.None, sessionNode, session); + const fromNode = new ZoweDatasetNode(fromDataSetName, vscode.TreeItemCollapsibleState.None, sessionNode, session); + const toNode = new ZoweDatasetNode(toDataSetName, vscode.TreeItemCollapsibleState.None, sessionNode, session); fromNode.contextValue = extension.DS_DS_CONTEXT; toNode.contextValue = extension.DS_PDS_CONTEXT; @@ -718,9 +718,9 @@ describe("Extension Integration Tests", () => { let contents; try { - const fromParentNode = new ZoweNode(fromDataSetName, vscode.TreeItemCollapsibleState.None, sessionNode, session); - const fromMemberNode = new ZoweNode(fromMemberName, vscode.TreeItemCollapsibleState.None, fromParentNode, session); - const toNode = new ZoweNode(toDataSetName, vscode.TreeItemCollapsibleState.None, sessionNode, session); + const fromParentNode = new ZoweDatasetNode(fromDataSetName, vscode.TreeItemCollapsibleState.None, sessionNode, session); + const fromMemberNode = new ZoweDatasetNode(fromMemberName, vscode.TreeItemCollapsibleState.None, fromParentNode, session); + const toNode = new ZoweDatasetNode(toDataSetName, vscode.TreeItemCollapsibleState.None, sessionNode, session); fromParentNode.contextValue = extension.DS_PDS_CONTEXT; fromMemberNode.contextValue = extension.DS_MEMBER_CONTEXT; toNode.contextValue = extension.DS_DS_CONTEXT; diff --git a/__tests__/__unit__/DatasetTree.unit.test.ts b/__tests__/__unit__/DatasetTree.unit.test.ts index 14b8f09141..19a3f2b68f 100644 --- a/__tests__/__unit__/DatasetTree.unit.test.ts +++ b/__tests__/__unit__/DatasetTree.unit.test.ts @@ -17,7 +17,7 @@ jest.mock("@brightside/imperative"); jest.mock("../../src/Profiles"); import * as vscode from "vscode"; import { DatasetTree } from "../../src/DatasetTree"; -import { ZoweNode } from "../../src/ZoweNode"; +import { ZoweDatasetNode } from "../../src/ZoweDatasetNode"; import { Session, Logger } from "@brightside/imperative"; import * as zowe from "@brightside/core"; import * as utils from "../../src/utils"; @@ -108,7 +108,7 @@ describe("DatasetTree Unit Tests", () => { }); Profiles.createInstance(Logger.getAppLogger()); const testTree = new DatasetTree(); - testTree.mSessionNodes.push(new ZoweNode("testSess", vscode.TreeItemCollapsibleState.Collapsed, null, session)); + testTree.mSessionNodes.push(new ZoweDatasetNode("testSess", vscode.TreeItemCollapsibleState.Collapsed, null, session)); testTree.mSessionNodes[1].contextValue = extension.DS_SESSION_CONTEXT; testTree.mSessionNodes[1].pattern = "test"; testTree.mSessionNodes[1].iconPath = utils.applyIcons(testTree.mSessionNodes[1]); @@ -131,7 +131,7 @@ describe("DatasetTree Unit Tests", () => { * Calls getTreeItem with sample element and checks the return is vscode.TreeItem *************************************************************************************************************/ it("Testing the getTreeItem method", async () => { - const sampleElement = new ZoweNode("BRTVS99", vscode.TreeItemCollapsibleState.None, + const sampleElement = new ZoweDatasetNode("BRTVS99", vscode.TreeItemCollapsibleState.None, null, null); expect(testTree.getTreeItem(sampleElement)).toBeInstanceOf(vscode.TreeItem); }); @@ -145,8 +145,8 @@ describe("DatasetTree Unit Tests", () => { // Creating a rootNode const sessNode = [ - new ZoweNode("Favorites", vscode.TreeItemCollapsibleState.Collapsed, null, null), - new ZoweNode("testSess", vscode.TreeItemCollapsibleState.Collapsed, null, session), + new ZoweDatasetNode("Favorites", vscode.TreeItemCollapsibleState.Collapsed, null, null), + new ZoweDatasetNode("testSess", vscode.TreeItemCollapsibleState.Collapsed, null, session), ]; sessNode[0].contextValue = extension.FAVORITE_CONTEXT; sessNode[1].contextValue = extension.DS_SESSION_CONTEXT; @@ -173,16 +173,16 @@ describe("DatasetTree Unit Tests", () => { /************************************************************************************************************* * Creates a child with a rootNode as parent and checks that a getParent() call returns null. - * Also creates a child with a non-rootNode parent and checks that getParent() returns the correct ZoweNode + * Also creates a child with a non-rootNode parent and checks that getParent() returns the correct ZoweDatasetNode *************************************************************************************************************/ - it("Tests that getParent returns the correct ZoweNode when called on a non-rootNode ZoweNode", async () => { + it("Tests that getParent returns the correct ZoweDatasetNode when called on a non-rootNode ZoweDatasetNode", async () => { // Creating fake datasets and dataset members to test - const sampleChild1: ZoweNode = new ZoweNode("BRTVS99.DDIR", vscode.TreeItemCollapsibleState.None, + const sampleChild1: ZoweDatasetNode = new ZoweDatasetNode("BRTVS99.DDIR", vscode.TreeItemCollapsibleState.None, testTree.mSessionNodes[0], session); const parent1 = testTree.getParent(sampleChild1); // Creating fake datasets and dataset members to test - const sampleChild2: ZoweNode = new ZoweNode("BRTVS99.PUBLIC.TEST", vscode.TreeItemCollapsibleState.None, + const sampleChild2: ZoweDatasetNode = new ZoweDatasetNode("BRTVS99.PUBLIC.TEST", vscode.TreeItemCollapsibleState.None, sampleChild1, null); const parent2 = testTree.getParent(sampleChild2); @@ -195,38 +195,39 @@ describe("DatasetTree Unit Tests", () => { }); /************************************************************************************************************* - * Tests that getChildren() method returns an array of all child nodes of passed ZoweNode + * Tests that getChildren() method returns an array of all child nodes of passed ZoweDatasetNode *************************************************************************************************************/ - it("Testing that getChildren returns the correct ZoweNodes when called and passed an element of type ZoweNode", async () => { + it("Testing that getChildren returns the correct ZoweNodes when called and passed an element of type ZoweDatasetNode", async () => { testTree.mSessionNodes[1].dirty = true; // Waiting until we populate rootChildren with what getChildren return const sessChildren = await testTree.getChildren(testTree.mSessionNodes[1]); // Creating fake datasets and dataset members to test - const sampleChildren: ZoweNode[] = [ - new ZoweNode("BRTVS99", vscode.TreeItemCollapsibleState.None, testTree.mSessionNodes[1], null), - new ZoweNode("BRTVS99.CA10", vscode.TreeItemCollapsibleState.None, testTree.mSessionNodes[1], null, extension.DS_MIGRATED_FILE_CONTEXT), - new ZoweNode("BRTVS99.CA11.SPFTEMP0.CNTL", vscode.TreeItemCollapsibleState.Collapsed, testTree.mSessionNodes[1], null), - new ZoweNode("BRTVS99.DDIR", vscode.TreeItemCollapsibleState.Collapsed, testTree.mSessionNodes[1], null), + const sampleChildren: ZoweDatasetNode[] = [ + new ZoweDatasetNode("BRTVS99", vscode.TreeItemCollapsibleState.None, testTree.mSessionNodes[1], null), + new ZoweDatasetNode("BRTVS99.CA10", vscode.TreeItemCollapsibleState.None, + testTree.mSessionNodes[1], null, extension.DS_MIGRATED_FILE_CONTEXT), + new ZoweDatasetNode("BRTVS99.CA11.SPFTEMP0.CNTL", vscode.TreeItemCollapsibleState.Collapsed, testTree.mSessionNodes[1], null), + new ZoweDatasetNode("BRTVS99.DDIR", vscode.TreeItemCollapsibleState.Collapsed, testTree.mSessionNodes[1], null), ]; - sampleChildren[0].command = { command: "zowe.ZoweNode.openPS", title: "", arguments: [sampleChildren[0]] }; + sampleChildren[0].command = { command: "zowe.ZoweDatasetNode.openPS", title: "", arguments: [sampleChildren[0]] }; // Checking that the rootChildren are what they are expected to be expect(sessChildren).toEqual(sampleChildren); }); /************************************************************************************************************* - * Tests that getChildren() method returns an array of all child nodes of passed ZoweNode + * Tests that getChildren() method returns an array of all child nodes of passed ZoweDatasetNode *************************************************************************************************************/ - it("Testing that getChildren returns the correct ZoweNodes when called and passed an element of type ZoweNode", async () => { + it("Testing that getChildren returns the correct ZoweNodes when called and passed an element of type ZoweDatasetNode", async () => { // Waiting until we populate rootChildren with what getChildren return - testTree.mFavorites.push(new ZoweNode("BRTVS99", vscode.TreeItemCollapsibleState.None, testTree.mSessionNodes[0], null)); + testTree.mFavorites.push(new ZoweDatasetNode("BRTVS99", vscode.TreeItemCollapsibleState.None, testTree.mSessionNodes[0], null)); const favChildren = await testTree.getChildren(testTree.mSessionNodes[0]); // Creating fake datasets and dataset members to test - const sampleChildren: ZoweNode[] = [ - new ZoweNode("BRTVS99", vscode.TreeItemCollapsibleState.None, testTree.mSessionNodes[0], null) + const sampleChildren: ZoweDatasetNode[] = [ + new ZoweDatasetNode("BRTVS99", vscode.TreeItemCollapsibleState.None, testTree.mSessionNodes[0], null) ]; // Checking that the rootChildren are what they are expected to be @@ -234,21 +235,21 @@ describe("DatasetTree Unit Tests", () => { }); /************************************************************************************************************* - * Tests that getChildren() method returns an array of all child nodes of passed ZoweNode + * Tests that getChildren() method returns an array of all child nodes of passed ZoweDatasetNode *************************************************************************************************************/ - it("Testing that getChildren returns the correct ZoweNodes when called and passed an element of type ZoweNode", async () => { - const pds = new ZoweNode("BRTVS99.PUBLIC", vscode.TreeItemCollapsibleState.Collapsed, testTree.mSessionNodes[1], null); + it("Testing that getChildren returns the correct ZoweNodes when called and passed an element of type ZoweDatasetNode", async () => { + const pds = new ZoweDatasetNode("BRTVS99.PUBLIC", vscode.TreeItemCollapsibleState.Collapsed, testTree.mSessionNodes[1], null); pds.dirty = true; // Waiting until we populate rootChildren with what getChildren return const pdsChildren = await testTree.getChildren(pds); // Creating fake datasets and dataset members to test - const sampleChildren: ZoweNode[] = [ - new ZoweNode("BRTVS99", vscode.TreeItemCollapsibleState.None, pds, null), - new ZoweNode("BRTVS99.DDIR", vscode.TreeItemCollapsibleState.None, pds, null), + const sampleChildren: ZoweDatasetNode[] = [ + new ZoweDatasetNode("BRTVS99", vscode.TreeItemCollapsibleState.None, pds, null), + new ZoweDatasetNode("BRTVS99.DDIR", vscode.TreeItemCollapsibleState.None, pds, null), ]; - sampleChildren[0].command = { command: "zowe.ZoweNode.openPS", title: "", arguments: [sampleChildren[0]] }; - sampleChildren[1].command = { command: "zowe.ZoweNode.openPS", title: "", arguments: [sampleChildren[1]] }; + sampleChildren[0].command = { command: "zowe.ZoweDatasetNode.openPS", title: "", arguments: [sampleChildren[0]] }; + sampleChildren[1].command = { command: "zowe.ZoweDatasetNode.openPS", title: "", arguments: [sampleChildren[1]] }; // Checking that the rootChildren are what they are expected to be expect(pdsChildren).toEqual(sampleChildren); @@ -259,7 +260,7 @@ describe("DatasetTree Unit Tests", () => { *************************************************************************************************************/ it("Tests the getHistory command", async () => { testTree.addHistory("testHistory"); - const sampleElement = new ZoweNode("testValue", vscode.TreeItemCollapsibleState.None, null, null); + const sampleElement = new ZoweDatasetNode("testValue", vscode.TreeItemCollapsibleState.None, null, null); expect(testTree.getHistory()[0]).toEqual("testHistory"); }); @@ -286,9 +287,9 @@ describe("DatasetTree Unit Tests", () => { *************************************************************************************************************/ it("Testing that addFavorite works properly", async () => { testTree.mFavorites = []; - const parent = new ZoweNode("Parent", vscode.TreeItemCollapsibleState.Collapsed, + const parent = new ZoweDatasetNode("Parent", vscode.TreeItemCollapsibleState.Collapsed, testTree.mSessionNodes[1], null); - const member = new ZoweNode("Child", vscode.TreeItemCollapsibleState.None, + const member = new ZoweDatasetNode("Child", vscode.TreeItemCollapsibleState.None, parent, null); getConfiguration.mockReturnValue({ @@ -307,13 +308,13 @@ describe("DatasetTree Unit Tests", () => { await testTree.addFavorite(member); // Check adding duplicates - const pds = new ZoweNode("Parent", vscode.TreeItemCollapsibleState.Collapsed, + const pds = new ZoweDatasetNode("Parent", vscode.TreeItemCollapsibleState.Collapsed, testTree.mSessionNodes[1], null); await testTree.addFavorite(pds); // Check adding ps - const ps = new ZoweNode("Dataset", vscode.TreeItemCollapsibleState.None, + const ps = new ZoweDatasetNode("Dataset", vscode.TreeItemCollapsibleState.None, testTree.mSessionNodes[1], null); testTree.addFavorite(ps); @@ -369,7 +370,7 @@ describe("DatasetTree Unit Tests", () => { *************************************************************************************************************/ it("Testing that deleteSession works properly", async () => { const startLength = testTree.mSessionNodes.length; - testTree.mSessionNodes.push(new ZoweNode("testSess2", vscode.TreeItemCollapsibleState.Collapsed, null, session)); + testTree.mSessionNodes.push(new ZoweDatasetNode("testSess2", vscode.TreeItemCollapsibleState.Collapsed, null, session)); testTree.addSession("testSess2"); testTree.mSessionNodes[startLength].contextValue = extension.DS_SESSION_CONTEXT; testTree.mSessionNodes[startLength].pattern = "test"; @@ -387,7 +388,7 @@ describe("DatasetTree Unit Tests", () => { createBasicZosmfSession.mockReturnValue(session); Object.defineProperty(testTree, "refresh", {value: refresh}); refresh.mockReset(); - const pds = new ZoweNode("BRTVS99.PUBLIC", vscode.TreeItemCollapsibleState.Collapsed, testTree.mSessionNodes[1], session); + const pds = new ZoweDatasetNode("BRTVS99.PUBLIC", vscode.TreeItemCollapsibleState.Collapsed, testTree.mSessionNodes[1], session); await testTree.flipState(pds, true); expect(JSON.stringify(pds.iconPath)).toContain("folder-open.svg"); await testTree.flipState(pds, false); @@ -397,7 +398,7 @@ describe("DatasetTree Unit Tests", () => { }); it("Testing that expand tree is executed for favorites", async () => { - const pds = new ZoweNode("Favorites", vscode.TreeItemCollapsibleState.Collapsed, testTree.mSessionNodes[1], session); + const pds = new ZoweDatasetNode("Favorites", vscode.TreeItemCollapsibleState.Collapsed, testTree.mSessionNodes[1], session); await testTree.flipState(pds, true); expect(JSON.stringify(pds.iconPath)).toContain("folder-open.svg"); await testTree.flipState(pds, false); @@ -427,7 +428,7 @@ describe("DatasetTree Unit Tests", () => { }; }) }); - const pds = new ZoweNode("BRTVS99.PUBLIC", vscode.TreeItemCollapsibleState.Collapsed, testTree.mSessionNodes[1], sessionwocred); + const pds = new ZoweDatasetNode("BRTVS99.PUBLIC", vscode.TreeItemCollapsibleState.Collapsed, testTree.mSessionNodes[1], sessionwocred); await testTree.flipState(pds, true); expect(JSON.stringify(pds.iconPath)).toContain("folder-open.svg"); await testTree.flipState(pds, false); @@ -457,7 +458,8 @@ describe("DatasetTree Unit Tests", () => { }; }) }); - const pds = new ZoweNode("[test]: BRTVS99.PUBLIC", vscode.TreeItemCollapsibleState.Collapsed, testTree.mSessionNodes[1], sessionwocred); + const pds = new ZoweDatasetNode("[test]: BRTVS99.PUBLIC", vscode.TreeItemCollapsibleState.Collapsed, + testTree.mSessionNodes[1], sessionwocred); pds.contextValue = extension.DS_SESSION_CONTEXT + extension.FAV_SUFFIX; await testTree.flipState(pds, true); expect(JSON.stringify(pds.iconPath)).toContain("pattern.svg"); @@ -481,7 +483,7 @@ describe("DatasetTree Unit Tests", () => { }; }) }); - const pds = new ZoweNode("BRTVS99.PUBLIC", vscode.TreeItemCollapsibleState.Collapsed, testTree.mSessionNodes[1], sessionwocred); + const pds = new ZoweDatasetNode("BRTVS99.PUBLIC", vscode.TreeItemCollapsibleState.Collapsed, testTree.mSessionNodes[1], sessionwocred); await testTree.flipState(pds, true); expect(JSON.stringify(pds.iconPath)).not.toEqual("folder-open.svg"); await testTree.flipState(pds, false); @@ -535,7 +537,7 @@ describe("DatasetTree Unit Tests", () => { it("Testing that user filter prompts are executed successfully for favorites", async () => { // Executing from favorites - const favoriteSearch = new ZoweNode("[aProfile]: HLQ.PROD1.STUFF", + const favoriteSearch = new ZoweDatasetNode("[aProfile]: HLQ.PROD1.STUFF", vscode.TreeItemCollapsibleState.None, testTree.mSessionNodes[1], session); favoriteSearch.contextValue = extension.DS_SESSION_CONTEXT + extension.FAV_SUFFIX; const checkSession = jest.spyOn(testTree, "addSession"); @@ -669,7 +671,7 @@ describe("DatasetTree Unit Tests", () => { const sessionNode = testTree.mSessionNodes[1]; const newLabel = "USER.NEW.LABEL"; testTree.mFavorites = []; - const node = new ZoweNode("node", vscode.TreeItemCollapsibleState.Collapsed, sessionNode, null); + const node = new ZoweDatasetNode("node", vscode.TreeItemCollapsibleState.Collapsed, sessionNode, null); testTree.addFavorite(node); node.label = `[${sessionNode.label.trim()}]: ${node.label}`; @@ -682,7 +684,7 @@ describe("DatasetTree Unit Tests", () => { it("Should rename a node", async () => { const sessionNode = testTree.mSessionNodes[1]; const newLabel = "USER.NEW.LABEL"; - const node = new ZoweNode("node", vscode.TreeItemCollapsibleState.Collapsed, sessionNode, null); + const node = new ZoweDatasetNode("node", vscode.TreeItemCollapsibleState.Collapsed, sessionNode, null); sessionNode.children.push(node); testTree.renameNode(sessionNode.label.trim(), "node", newLabel); @@ -701,9 +703,9 @@ describe("DatasetTree Unit Tests", () => { protocol: "https", type: "basic", }); - const sessNode = new ZoweNode("sestest", vscode.TreeItemCollapsibleState.Expanded, null, session); + const sessNode = new ZoweDatasetNode("sestest", vscode.TreeItemCollapsibleState.Expanded, null, session); sessNode.contextValue = extension.DS_SESSION_CONTEXT; - const dsNode = new ZoweNode("testSess", vscode.TreeItemCollapsibleState.Expanded, sessNode, sessionwocred); + const dsNode = new ZoweDatasetNode("testSess", vscode.TreeItemCollapsibleState.Expanded, sessNode, sessionwocred); dsNode.contextValue = extension.DS_SESSION_CONTEXT; Object.defineProperty(Profiles, "getInstance", { value: jest.fn(() => { @@ -738,12 +740,12 @@ describe("DatasetTree Unit Tests", () => { protocol: "https", type: "basic", }); - const sessNode = new ZoweNode("sestest", vscode.TreeItemCollapsibleState.Expanded, null, session); + const sessNode = new ZoweDatasetNode("sestest", vscode.TreeItemCollapsibleState.Expanded, null, session); sessNode.contextValue = extension.DS_SESSION_CONTEXT + extension.FAV_SUFFIX; - const dsNode = new ZoweNode("[testSess2]: node", vscode.TreeItemCollapsibleState.Expanded, sessNode, sessionwocred); + const dsNode = new ZoweDatasetNode("[testSess2]: node", vscode.TreeItemCollapsibleState.Expanded, sessNode, sessionwocred); dsNode.contextValue = extension.DS_SESSION_CONTEXT + extension.FAV_SUFFIX; testTree.mSessionNodes.push(dsNode); - const dsNode2 = new ZoweNode("testSess2", vscode.TreeItemCollapsibleState.Expanded, sessNode, sessionwocred); + const dsNode2 = new ZoweDatasetNode("testSess2", vscode.TreeItemCollapsibleState.Expanded, sessNode, sessionwocred); dsNode2.contextValue = extension.DS_SESSION_CONTEXT + extension.FAV_SUFFIX; testTree.mSessionNodes.push(dsNode2); Object.defineProperty(Profiles, "getInstance", { @@ -786,12 +788,12 @@ describe("DatasetTree Unit Tests", () => { protocol: "https", type: "basic", }); - const sessNode = new ZoweNode("sestest", vscode.TreeItemCollapsibleState.Expanded, null, session); + const sessNode = new ZoweDatasetNode("sestest", vscode.TreeItemCollapsibleState.Expanded, null, session); sessNode.contextValue = extension.DS_SESSION_CONTEXT + extension.FAV_SUFFIX; - const dsNode = new ZoweNode("[testSess2]: node", vscode.TreeItemCollapsibleState.Expanded, sessNode, sessionwocred); + const dsNode = new ZoweDatasetNode("[testSess2]: node", vscode.TreeItemCollapsibleState.Expanded, sessNode, sessionwocred); dsNode.contextValue = extension.DS_SESSION_CONTEXT + extension.FAV_SUFFIX; testTree.mSessionNodes.push(dsNode); - const dsNode2 = new ZoweNode("testSess2", vscode.TreeItemCollapsibleState.Expanded, sessNode, sessionwocred); + const dsNode2 = new ZoweDatasetNode("testSess2", vscode.TreeItemCollapsibleState.Expanded, sessNode, sessionwocred); dsNode2.contextValue = extension.DS_SESSION_CONTEXT + extension.FAV_SUFFIX; testTree.mSessionNodes.push(dsNode2); getConfiguration.mockReturnValue({ @@ -850,9 +852,9 @@ describe("DatasetTree Unit Tests", () => { protocol: "https", type: "basic", }); - const sessNode = new ZoweNode("sestest", vscode.TreeItemCollapsibleState.Expanded, null, session); + const sessNode = new ZoweDatasetNode("sestest", vscode.TreeItemCollapsibleState.Expanded, null, session); sessNode.contextValue = extension.DS_SESSION_CONTEXT; - const dsNode = new ZoweNode("testSess", vscode.TreeItemCollapsibleState.Expanded, sessNode, sessionwocred); + const dsNode = new ZoweDatasetNode("testSess", vscode.TreeItemCollapsibleState.Expanded, sessNode, sessionwocred); dsNode.contextValue = extension.DS_SESSION_CONTEXT; Object.defineProperty(Profiles, "getInstance", { value: jest.fn(() => { @@ -872,8 +874,8 @@ describe("DatasetTree Unit Tests", () => { it("Should find a favorited node", async () => { testTree.mFavorites = []; const sessionNode = testTree.mSessionNodes[1]; - const nonFavoritedNode = new ZoweNode("node", vscode.TreeItemCollapsibleState.Collapsed, sessionNode, null); - const favoritedNode = new ZoweNode("[testSess]: node", vscode.TreeItemCollapsibleState.Collapsed, sessionNode, null); + const nonFavoritedNode = new ZoweDatasetNode("node", vscode.TreeItemCollapsibleState.Collapsed, sessionNode, null); + const favoritedNode = new ZoweDatasetNode("[testSess]: node", vscode.TreeItemCollapsibleState.Collapsed, sessionNode, null); favoritedNode.contextValue = extension.DS_PDS_CONTEXT + extension.FAV_SUFFIX; testTree.mFavorites.push(favoritedNode); @@ -885,8 +887,8 @@ describe("DatasetTree Unit Tests", () => { it("Should find a non-favorited node", async () => { const sessionNode = testTree.mSessionNodes[1]; - const nonFavoritedNode = new ZoweNode("node", vscode.TreeItemCollapsibleState.Collapsed, sessionNode, null); - const favoritedNode = new ZoweNode("[testSess]: node", vscode.TreeItemCollapsibleState.Collapsed, sessionNode, null); + const nonFavoritedNode = new ZoweDatasetNode("node", vscode.TreeItemCollapsibleState.Collapsed, sessionNode, null); + const favoritedNode = new ZoweDatasetNode("[testSess]: node", vscode.TreeItemCollapsibleState.Collapsed, sessionNode, null); sessionNode.children.push(nonFavoritedNode); diff --git a/__tests__/__unit__/ZoweNode.unit.test.ts b/__tests__/__unit__/ZoweNode.unit.test.ts index 5ce311635e..3db54be95b 100644 --- a/__tests__/__unit__/ZoweNode.unit.test.ts +++ b/__tests__/__unit__/ZoweNode.unit.test.ts @@ -16,7 +16,7 @@ jest.mock("@brightside/core/lib/zosfiles/src/api/methods/list/doc/IListOptions") jest.mock("Session"); jest.mock("../../src/ProfileLoader"); import * as vscode from "vscode"; -import { ZoweNode } from "../../src/ZoweNode"; +import { ZoweDatasetNode } from "../../src/ZoweDatasetNode"; import { Session } from "@brightside/imperative"; import * as extension from "../../src/extension"; import * as profileLoader from "../../src/ProfileLoader"; @@ -44,10 +44,10 @@ describe("Unit Tests (Jest)", () => { jest.resetAllMocks(); }); /************************************************************************************************************* - * Creates an ZoweNode and checks that its members are all initialized by the constructor + * Creates an ZoweDatasetNode and checks that its members are all initialized by the constructor *************************************************************************************************************/ - it("Testing that the ZoweNode is defined", async () => { - const testNode = new ZoweNode("BRTVS99", vscode.TreeItemCollapsibleState.None, null, session); + it("Testing that the ZoweDatasetNode is defined", async () => { + const testNode = new ZoweDatasetNode("BRTVS99", vscode.TreeItemCollapsibleState.None, null, session); testNode.contextValue = extension.DS_SESSION_CONTEXT; expect(testNode.label).toBeDefined(); @@ -58,24 +58,24 @@ describe("Unit Tests (Jest)", () => { }); /************************************************************************************************************* - * Creates sample ZoweNode list and checks that getChildren() returns the correct array + * Creates sample ZoweDatasetNode list and checks that getChildren() returns the correct array *************************************************************************************************************/ - it("Testing that getChildren returns the correct Thenable", async () => { + it("Testing that getChildren returns the correct Thenable", async () => { // Creating a rootNode - const rootNode = new ZoweNode("root", vscode.TreeItemCollapsibleState.Collapsed, null, session); + const rootNode = new ZoweDatasetNode("root", vscode.TreeItemCollapsibleState.Collapsed, null, session); rootNode.dirty = true; rootNode.contextValue = extension.DS_SESSION_CONTEXT; rootNode.pattern = "SAMPLE, SAMPLE.PUBLIC, SAMPLE"; let rootChildren = await rootNode.getChildren(); // Creating structure of files and folders under BRTVS99 profile - const sampleChildren: ZoweNode[] = [ - new ZoweNode("BRTVS99", vscode.TreeItemCollapsibleState.None, rootNode, null), - new ZoweNode("BRTVS99.CA10", vscode.TreeItemCollapsibleState.None, rootNode, null, extension.DS_MIGRATED_FILE_CONTEXT), - new ZoweNode("BRTVS99.CA11.SPFTEMP0.CNTL", vscode.TreeItemCollapsibleState.Collapsed, rootNode, null), - new ZoweNode("BRTVS99.DDIR", vscode.TreeItemCollapsibleState.Collapsed, rootNode, null), + const sampleChildren: ZoweDatasetNode[] = [ + new ZoweDatasetNode("BRTVS99", vscode.TreeItemCollapsibleState.None, rootNode, null), + new ZoweDatasetNode("BRTVS99.CA10", vscode.TreeItemCollapsibleState.None, rootNode, null, extension.DS_MIGRATED_FILE_CONTEXT), + new ZoweDatasetNode("BRTVS99.CA11.SPFTEMP0.CNTL", vscode.TreeItemCollapsibleState.Collapsed, rootNode, null), + new ZoweDatasetNode("BRTVS99.DDIR", vscode.TreeItemCollapsibleState.Collapsed, rootNode, null), ]; - sampleChildren[0].command = { command: "zowe.ZoweNode.openPS", title: "", arguments: [sampleChildren[0]] }; + sampleChildren[0].command = { command: "zowe.ZoweDatasetNode.openPS", title: "", arguments: [sampleChildren[0]] }; // Checking that the rootChildren are what they are expected to be expect(rootChildren).toEqual(sampleChildren); @@ -88,36 +88,36 @@ describe("Unit Tests (Jest)", () => { expect(rootChildren).toEqual(sampleChildren); // Check that error is thrown when label is blank - const errorNode = new ZoweNode("", vscode.TreeItemCollapsibleState.Collapsed, null, session); + const errorNode = new ZoweDatasetNode("", vscode.TreeItemCollapsibleState.Collapsed, null, session); errorNode.dirty = true; await expect(errorNode.getChildren()).rejects.toEqual(Error("Invalid node")); // Check that label is different when label contains a [] - const rootNode2 = new ZoweNode("root[test]", vscode.TreeItemCollapsibleState.Collapsed, null, session); + const rootNode2 = new ZoweDatasetNode("root[test]", vscode.TreeItemCollapsibleState.Collapsed, null, session); rootNode2.dirty = true; rootChildren = await rootNode2.getChildren(); }); /************************************************************************************************************* - * Creates sample ZoweNode list and checks that getChildren() returns the correct array for a PO + * Creates sample ZoweDatasetNode list and checks that getChildren() returns the correct array for a PO *************************************************************************************************************/ - it("Testing that getChildren returns the correct Thenable for a PO", async () => { + it("Testing that getChildren returns the correct Thenable for a PO", async () => { // Creating a rootNode - const rootNode = new ZoweNode("root", vscode.TreeItemCollapsibleState.None, null, session); + const rootNode = new ZoweDatasetNode("root", vscode.TreeItemCollapsibleState.None, null, session); rootNode.contextValue = extension.DS_SESSION_CONTEXT; rootNode.dirty = true; - const subNode = new ZoweNode("sub", vscode.TreeItemCollapsibleState.Collapsed, rootNode, null); + const subNode = new ZoweDatasetNode("sub", vscode.TreeItemCollapsibleState.Collapsed, rootNode, null); subNode.dirty = true; const subChildren = await subNode.getChildren(); // Creating structure of files and folders under BRTVS99 profile - const sampleChildren: ZoweNode[] = [ - new ZoweNode("BRTVS99", vscode.TreeItemCollapsibleState.None, subNode, null), - new ZoweNode("BRTVS99.DDIR", vscode.TreeItemCollapsibleState.None, subNode, null), + const sampleChildren: ZoweDatasetNode[] = [ + new ZoweDatasetNode("BRTVS99", vscode.TreeItemCollapsibleState.None, subNode, null), + new ZoweDatasetNode("BRTVS99.DDIR", vscode.TreeItemCollapsibleState.None, subNode, null), ]; - sampleChildren[0].command = { command: "zowe.ZoweNode.openPS", title: "", arguments: [sampleChildren[0]] }; - sampleChildren[1].command = { command: "zowe.ZoweNode.openPS", title: "", arguments: [sampleChildren[1]] }; + sampleChildren[0].command = { command: "zowe.ZoweDatasetNode.openPS", title: "", arguments: [sampleChildren[0]] }; + sampleChildren[1].command = { command: "zowe.ZoweDatasetNode.openPS", title: "", arguments: [sampleChildren[1]] }; // Checking that the rootChildren are what they are expected to be expect(subChildren).toEqual(sampleChildren); }); @@ -128,7 +128,7 @@ describe("Unit Tests (Jest)", () => { it("Checks that when bright.List.dataSet/allMembers() causes an error on the brightside call, " + "it throws an error and the catch block is reached", async () => { // Creating a rootNode - const rootNode = new ZoweNode("root", vscode.TreeItemCollapsibleState.Collapsed, null, session); + const rootNode = new ZoweDatasetNode("root", vscode.TreeItemCollapsibleState.Collapsed, null, session); rootNode.contextValue = extension.DS_SESSION_CONTEXT; rootNode.pattern = "THROW ERROR"; rootNode.dirty = true; @@ -142,10 +142,10 @@ describe("Unit Tests (Jest)", () => { it("Checks that when bright.List.dataSet/allMembers() returns an unsuccessful response, " + "it throws an error and the catch block is reached", async () => { // Creating a rootNode - const rootNode = new ZoweNode("root", vscode.TreeItemCollapsibleState.Collapsed, null, session); + const rootNode = new ZoweDatasetNode("root", vscode.TreeItemCollapsibleState.Collapsed, null, session); rootNode.contextValue = extension.DS_SESSION_CONTEXT; rootNode.dirty = true; - const subNode = new ZoweNode("Response Fail", vscode.TreeItemCollapsibleState.Collapsed, rootNode, null); + const subNode = new ZoweDatasetNode("Response Fail", vscode.TreeItemCollapsibleState.Collapsed, rootNode, null); subNode.dirty = true; await expect(subNode.getChildren()).rejects.toEqual(Error("The response from Zowe CLI was not successful")); }); @@ -155,8 +155,8 @@ describe("Unit Tests (Jest)", () => { *************************************************************************************************************/ it("Checks that passing a session node that is not dirty the getChildren() method is exited early", async () => { // Creating a rootNode - const rootNode = new ZoweNode("root", vscode.TreeItemCollapsibleState.Collapsed, null, session); - const infoChild = new ZoweNode("Use the search button to display datasets", vscode.TreeItemCollapsibleState.None, rootNode, null, + const rootNode = new ZoweDatasetNode("root", vscode.TreeItemCollapsibleState.Collapsed, null, session); + const infoChild = new ZoweDatasetNode("Use the search button to display datasets", vscode.TreeItemCollapsibleState.None, rootNode, null, extension.INFORMATION_CONTEXT); rootNode.contextValue = extension.DS_SESSION_CONTEXT; rootNode.dirty = false; @@ -168,8 +168,8 @@ describe("Unit Tests (Jest)", () => { *************************************************************************************************************/ it("Checks that passing a session node with no hlq the getChildren() method is exited early", async () => { // Creating a rootNode - const rootNode = new ZoweNode("root", vscode.TreeItemCollapsibleState.Collapsed, null, session); - const infoChild = new ZoweNode("Use the search button to display datasets", vscode.TreeItemCollapsibleState.None, rootNode, null, + const rootNode = new ZoweDatasetNode("root", vscode.TreeItemCollapsibleState.Collapsed, null, session); + const infoChild = new ZoweDatasetNode("Use the search button to display datasets", vscode.TreeItemCollapsibleState.None, rootNode, null, extension.INFORMATION_CONTEXT); rootNode.contextValue = extension.DS_SESSION_CONTEXT; await expect(await rootNode.getChildren()).toEqual([infoChild]); @@ -180,10 +180,10 @@ describe("Unit Tests (Jest)", () => { *************************************************************************************************************/ it("Checks that a member can reach its session properly", async () => { // Creating a rootNode - const rootNode = new ZoweNode("root", vscode.TreeItemCollapsibleState.Collapsed, null, session); + const rootNode = new ZoweDatasetNode("root", vscode.TreeItemCollapsibleState.Collapsed, null, session); rootNode.contextValue = extension.DS_SESSION_CONTEXT; - const subNode = new ZoweNode(extension.DS_PDS_CONTEXT, vscode.TreeItemCollapsibleState.Collapsed, rootNode, null); - const member = new ZoweNode(extension.DS_MEMBER_CONTEXT, vscode.TreeItemCollapsibleState.None, subNode, null); + const subNode = new ZoweDatasetNode(extension.DS_PDS_CONTEXT, vscode.TreeItemCollapsibleState.Collapsed, rootNode, null); + const member = new ZoweDatasetNode(extension.DS_MEMBER_CONTEXT, vscode.TreeItemCollapsibleState.None, subNode, null); await expect(member.getSession()).toBeDefined(); }); /************************************************************************************************************* @@ -191,7 +191,7 @@ describe("Unit Tests (Jest)", () => { *************************************************************************************************************/ it("Testing that certain types can't have children", async () => { // Creating a rootNode - const rootNode = new ZoweNode("root", vscode.TreeItemCollapsibleState.Collapsed, null, session); + const rootNode = new ZoweDatasetNode("root", vscode.TreeItemCollapsibleState.Collapsed, null, session); rootNode.dirty = true; rootNode.contextValue = extension.DS_DS_CONTEXT; expect(await rootNode.getChildren()).toHaveLength(0); @@ -205,8 +205,8 @@ describe("Unit Tests (Jest)", () => { *************************************************************************************************************/ it("Tests that we shouldn't be updating children", async () => { // Creating a rootNode - const rootNode = new ZoweNode("root", vscode.TreeItemCollapsibleState.Collapsed, null, session); - rootNode.children = [new ZoweNode("onestep", vscode.TreeItemCollapsibleState.Collapsed, null, session)]; + const rootNode = new ZoweDatasetNode("root", vscode.TreeItemCollapsibleState.Collapsed, null, session); + rootNode.children = [new ZoweDatasetNode("onestep", vscode.TreeItemCollapsibleState.Collapsed, null, session)]; rootNode.dirty = false; rootNode.contextValue = extension.DS_PDS_CONTEXT; expect((await rootNode.getChildren())[0].label).toEqual("onestep"); @@ -217,7 +217,7 @@ describe("Unit Tests (Jest)", () => { *************************************************************************************************************/ it("Testing Run with a favorite", async () => { // Creating a rootNode - const pds = new ZoweNode("[root]: something", vscode.TreeItemCollapsibleState.Collapsed, null, session); + const pds = new ZoweDatasetNode("[root]: something", vscode.TreeItemCollapsibleState.Collapsed, null, session); pds.dirty = true; pds.contextValue = extension.DS_PDS_CONTEXT; expect((await pds.getChildren())[0].label).toEqual("BRTVS99"); @@ -228,7 +228,7 @@ describe("Unit Tests (Jest)", () => { *************************************************************************************************************/ it("Testing what happens when response is zero", async () => { // Creating a rootNode - const pds = new ZoweNode("[root]: something", vscode.TreeItemCollapsibleState.Collapsed, null, session); + const pds = new ZoweDatasetNode("[root]: something", vscode.TreeItemCollapsibleState.Collapsed, null, session); pds.dirty = true; pds.contextValue = extension.DS_PDS_CONTEXT; const allMembers = jest.fn(); diff --git a/__tests__/__unit__/extension.unit.test.ts b/__tests__/__unit__/extension.unit.test.ts index bba7765d49..044e511027 100644 --- a/__tests__/__unit__/extension.unit.test.ts +++ b/__tests__/__unit__/extension.unit.test.ts @@ -13,7 +13,7 @@ import * as vscode from "vscode"; import * as treeMock from "../../src/DatasetTree"; import * as treeUSSMock from "../../src/USSTree"; import { ZoweUSSNode } from "../../src/ZoweUSSNode"; -import { ZoweNode } from "../../src/ZoweNode"; +import { ZoweDatasetNode } from "../../src/ZoweDatasetNode"; import * as brtimperative from "@brightside/imperative"; import * as extension from "../../src/extension"; import * as path from "path"; @@ -87,7 +87,7 @@ describe("Extension Unit Tests", () => { "subsystem": "" }; - const sessNode = new ZoweNode("sestest", vscode.TreeItemCollapsibleState.Expanded, null, session); + const sessNode = new ZoweDatasetNode("sestest", vscode.TreeItemCollapsibleState.Expanded, null, session); sessNode.contextValue = extension.DS_SESSION_CONTEXT; sessNode.pattern = "test hlq"; @@ -496,15 +496,15 @@ describe("Extension Unit Tests", () => { await extension.activate(mock); const sampleFavorites = [ - new ZoweNode("[test]: brtvs99.public.test", vscode.TreeItemCollapsibleState.Collapsed, undefined, undefined), - new ZoweNode("[test]: brtvs99.test", vscode.TreeItemCollapsibleState.None, undefined, undefined), - new ZoweNode("[test]: brtvs99.test.search", vscode.TreeItemCollapsibleState.None, undefined, null) + new ZoweDatasetNode("[test]: brtvs99.public.test", vscode.TreeItemCollapsibleState.Collapsed, undefined, undefined), + new ZoweDatasetNode("[test]: brtvs99.test", vscode.TreeItemCollapsibleState.None, undefined, undefined), + new ZoweDatasetNode("[test]: brtvs99.test.search", vscode.TreeItemCollapsibleState.None, undefined, null) ]; sampleFavorites[0].contextValue = extension.DS_PDS_CONTEXT + extension.FAV_SUFFIX; sampleFavorites[1].contextValue = extension.DS_PDS_CONTEXT + extension.FAV_SUFFIX; sampleFavorites[2].contextValue = extension.DS_SESSION_CONTEXT + extension.FAV_SUFFIX; sampleFavorites[1].command = { - command: "zowe.ZoweNode.openPS", + command: "zowe.ZoweDatasetNode.openPS", title: "", arguments: [sampleFavorites[1]] }; @@ -537,7 +537,7 @@ describe("Extension Unit Tests", () => { "zowe.refreshAll", "zowe.refreshNode", "zowe.pattern", - "zowe.ZoweNode.openPS", + "zowe.ZoweDatasetNode.openPS", "zowe.createDataset", "zowe.createMember", "zowe.deleteDataset", @@ -696,7 +696,7 @@ describe("Extension Unit Tests", () => { }); it("Testing that createMember correctly executes", async () => { - const parent = new ZoweNode("parent", vscode.TreeItemCollapsibleState.Collapsed, sessNode, null); + const parent = new ZoweDatasetNode("parent", vscode.TreeItemCollapsibleState.Collapsed, sessNode, null); showInputBox.mockResolvedValue("testMember"); @@ -734,9 +734,9 @@ describe("Extension Unit Tests", () => { }); it("Testing that refreshPS correctly executes with and without error", async () => { - const node = new ZoweNode("HLQ.TEST.AFILE7", vscode.TreeItemCollapsibleState.None, sessNode, null); - const parent = new ZoweNode("parent", vscode.TreeItemCollapsibleState.Collapsed, sessNode, null); - const child = new ZoweNode("child", vscode.TreeItemCollapsibleState.None, parent, null); + const node = new ZoweDatasetNode("HLQ.TEST.AFILE7", vscode.TreeItemCollapsibleState.None, sessNode, null); + const parent = new ZoweDatasetNode("parent", vscode.TreeItemCollapsibleState.Collapsed, sessNode, null); + const child = new ZoweDatasetNode("child", vscode.TreeItemCollapsibleState.None, parent, null); showErrorMessage.mockReset(); openTextDocument.mockReset(); @@ -838,7 +838,7 @@ describe("Extension Unit Tests", () => { }); it("Test Get Profile", async () => { - const ProfNode = new ZoweNode("[sestest1,sestest2]", vscode.TreeItemCollapsibleState.Expanded, null, session); + const ProfNode = new ZoweDatasetNode("[sestest1,sestest2]", vscode.TreeItemCollapsibleState.Expanded, null, session); await extension.getProfile(ProfNode); expect(ProfNode).not.toBeUndefined(); }); @@ -1096,10 +1096,10 @@ describe("Extension Unit Tests", () => { }); it("Testing that createFile is executed successfully", async () => { - const sessNode2 = new ZoweNode("sestest", vscode.TreeItemCollapsibleState.Expanded, null, session); + const sessNode2 = new ZoweDatasetNode("sestest", vscode.TreeItemCollapsibleState.Expanded, null, session); sessNode2.contextValue = extension.DS_SESSION_CONTEXT; sessNode2.pattern = "test hlq"; - const childNode = new ZoweNode("NODE", vscode.TreeItemCollapsibleState.None, sessNode2, null); + const childNode = new ZoweDatasetNode("NODE", vscode.TreeItemCollapsibleState.None, sessNode2, null); sessNode2.children.push(childNode); const uploadResponse: brightside.IZosFilesResponse = { @@ -1239,7 +1239,7 @@ describe("Extension Unit Tests", () => { }; createBasicZosmfSession.mockReturnValue(sessionwocred); - const newsessNode = new ZoweNode("sestest", vscode.TreeItemCollapsibleState.Expanded, null, sessionwocred); + const newsessNode = new ZoweDatasetNode("sestest", vscode.TreeItemCollapsibleState.Expanded, null, sessionwocred); newsessNode.contextValue = extension.DS_SESSION_CONTEXT; showQuickPick.mockReset(); @@ -1319,7 +1319,7 @@ describe("Extension Unit Tests", () => { }; createBasicZosmfSession.mockReturnValue(sessionwocred); - const newsessNode = new ZoweNode("sestest", vscode.TreeItemCollapsibleState.Expanded, null, sessionwocred); + const newsessNode = new ZoweDatasetNode("sestest", vscode.TreeItemCollapsibleState.Expanded, null, sessionwocred); newsessNode.contextValue = extension.DS_SESSION_CONTEXT + extension.FAV_SUFFIX; showQuickPick.mockReset(); @@ -1333,7 +1333,7 @@ describe("Extension Unit Tests", () => { getConfiguration.mockReturnValue("FakeConfig"); showInputBox.mockReturnValue("FakeName"); - testTree.getChildren.mockReturnValue([new ZoweNode("node", vscode.TreeItemCollapsibleState.None, sessNode, null), sessNode]); + testTree.getChildren.mockReturnValue([new ZoweDatasetNode("node", vscode.TreeItemCollapsibleState.None, sessNode, null), sessNode]); allMembers.mockReturnValue(uploadResponse); dataSet.mockReturnValue(uploadResponse); mockGetHistory.mockReturnValue(["mockHistory1"]); @@ -1398,7 +1398,7 @@ describe("Extension Unit Tests", () => { }); const createFile = jest.spyOn(extension, "createFile"); createBasicZosmfSession.mockReturnValue(sessionwocred); - const newsessNode = new ZoweNode("sestest", vscode.TreeItemCollapsibleState.Expanded, null, sessionwocred); + const newsessNode = new ZoweDatasetNode("sestest", vscode.TreeItemCollapsibleState.Expanded, null, sessionwocred); newsessNode.contextValue = extension.DS_SESSION_CONTEXT; newsessNode.pattern = "sestest"; @@ -1428,9 +1428,9 @@ describe("Extension Unit Tests", () => { unlinkSync.mockReset(); showQuickPick.mockReset(); - let node = new ZoweNode("HLQ.TEST.NODE", vscode.TreeItemCollapsibleState.None, sessNode, null); - const parent = new ZoweNode("parent", vscode.TreeItemCollapsibleState.Collapsed, sessNode, null); - let child = new ZoweNode("child", vscode.TreeItemCollapsibleState.None, parent, null); + let node = new ZoweDatasetNode("HLQ.TEST.NODE", vscode.TreeItemCollapsibleState.None, sessNode, null); + const parent = new ZoweDatasetNode("parent", vscode.TreeItemCollapsibleState.Collapsed, sessNode, null); + let child = new ZoweDatasetNode("child", vscode.TreeItemCollapsibleState.None, parent, null); existsSync.mockReturnValueOnce(true); showQuickPick.mockResolvedValueOnce("Yes"); @@ -1478,13 +1478,13 @@ describe("Extension Unit Tests", () => { await extension.deleteDataset(child, testTree); existsSync.mockReturnValueOnce(true); - node = new ZoweNode("HLQ.TEST.NODE", vscode.TreeItemCollapsibleState.None, sessNode, null); + node = new ZoweDatasetNode("HLQ.TEST.NODE", vscode.TreeItemCollapsibleState.None, sessNode, null); node.contextValue = extension.DS_PDS_CONTEXT + extension.FAV_SUFFIX; await extension.deleteDataset(node, testTree); existsSync.mockReturnValueOnce(true); node.contextValue = extension.DS_PDS_CONTEXT + extension.FAV_SUFFIX; - child = new ZoweNode("child", vscode.TreeItemCollapsibleState.None, node, null); + child = new ZoweDatasetNode("child", vscode.TreeItemCollapsibleState.None, node, null); await extension.deleteDataset(child, testTree); }); @@ -1495,8 +1495,8 @@ describe("Extension Unit Tests", () => { delDataset.mockReset(); mockRemoveFavorite.mockReset(); - const node = new ZoweNode("[sestest]: HLQ.TEST.DELETE.PARENT", vscode.TreeItemCollapsibleState.None, sessNode, null); - const child = new ZoweNode("[sestest]: HLQ.TEST.DELETE.NODE", vscode.TreeItemCollapsibleState.None, node, null); + const node = new ZoweDatasetNode("[sestest]: HLQ.TEST.DELETE.PARENT", vscode.TreeItemCollapsibleState.None, sessNode, null); + const child = new ZoweDatasetNode("[sestest]: HLQ.TEST.DELETE.NODE", vscode.TreeItemCollapsibleState.None, node, null); node.contextValue = extension.FAVORITE_CONTEXT; existsSync.mockReturnValueOnce(true); @@ -1523,8 +1523,8 @@ describe("Extension Unit Tests", () => { delDataset.mockReset(); mockRemoveFavorite.mockReset(); - const node = new ZoweNode("[sestest]: HLQ.TEST.DELETE.PDS", vscode.TreeItemCollapsibleState.None, sessNode, null); - const child = new ZoweNode("[sestest]: HLQ.TEST.DELETE.PDS(MEMBER)", vscode.TreeItemCollapsibleState.None, node, null); + const node = new ZoweDatasetNode("[sestest]: HLQ.TEST.DELETE.PDS", vscode.TreeItemCollapsibleState.None, sessNode, null); + const child = new ZoweDatasetNode("[sestest]: HLQ.TEST.DELETE.PDS(MEMBER)", vscode.TreeItemCollapsibleState.None, node, null); node.contextValue = extension.DS_PDS_CONTEXT + extension.FAV_SUFFIX; existsSync.mockReturnValueOnce(true); @@ -1552,9 +1552,9 @@ describe("Extension Unit Tests", () => { mockRemoveFavorite.mockReset(); showErrorMessage.mockReset(); - const node = new ZoweNode("[sestest]: HLQ.TEST.DELETE.PARENT", vscode.TreeItemCollapsibleState.None, sessNode, null); - const parent = new ZoweNode("sestest", vscode.TreeItemCollapsibleState.Collapsed, sessNode, null); - const child = new ZoweNode("[sestest]: HLQ.TEST.DELETE.NODE", vscode.TreeItemCollapsibleState.None, node, null); + const node = new ZoweDatasetNode("[sestest]: HLQ.TEST.DELETE.PARENT", vscode.TreeItemCollapsibleState.None, sessNode, null); + const parent = new ZoweDatasetNode("sestest", vscode.TreeItemCollapsibleState.Collapsed, sessNode, null); + const child = new ZoweDatasetNode("[sestest]: HLQ.TEST.DELETE.NODE", vscode.TreeItemCollapsibleState.None, node, null); node.contextValue = "junk"; existsSync.mockReturnValueOnce(true); @@ -1568,7 +1568,7 @@ describe("Extension Unit Tests", () => { showInformationMessage.mockReset(); showInputBox.mockReset(); - const node = new ZoweNode("node", vscode.TreeItemCollapsibleState.None, sessNode, null); + const node = new ZoweDatasetNode("node", vscode.TreeItemCollapsibleState.None, sessNode, null); node.pattern = "TEST"; node.contextValue = extension.DS_SESSION_CONTEXT; @@ -1593,7 +1593,7 @@ describe("Extension Unit Tests", () => { it("Testing that enterPattern is executed successfully for search favorite", async () => { mockAddZoweSession.mockReset(); - const favoriteSample = new ZoweNode("[sestest]: HLQ.TEST", vscode.TreeItemCollapsibleState.None, undefined, null); + const favoriteSample = new ZoweDatasetNode("[sestest]: HLQ.TEST", vscode.TreeItemCollapsibleState.None, undefined, null); await extension.enterPattern(favoriteSample, testTree); @@ -1658,7 +1658,7 @@ describe("Extension Unit Tests", () => { type: "basic", }); // testing if no session is defined (can happen while saving from favorites) - const nodeWitoutSession = new ZoweNode("HLQ.TEST.AFILE", vscode.TreeItemCollapsibleState.None, null, null); + const nodeWitoutSession = new ZoweDatasetNode("HLQ.TEST.AFILE", vscode.TreeItemCollapsibleState.None, null, null); testTree.getChildren.mockReturnValueOnce([nodeWitoutSession]); concatChildNodes.mockReturnValueOnce([nodeWitoutSession]); createBasicZosmfSession.mockReturnValueOnce(sessionwocred); @@ -1679,7 +1679,7 @@ describe("Extension Unit Tests", () => { testTree.getChildren.mockReset(); createBasicZosmfSession.mockReset(); - testTree.getChildren.mockReturnValueOnce([new ZoweNode("node", vscode.TreeItemCollapsibleState.None, sessNode, null), sessNode]); + testTree.getChildren.mockReturnValueOnce([new ZoweDatasetNode("node", vscode.TreeItemCollapsibleState.None, sessNode, null), sessNode]); dataSetList.mockReset(); showErrorMessage.mockReset(); dataSetList.mockResolvedValueOnce(testResponse); @@ -1691,7 +1691,7 @@ describe("Extension Unit Tests", () => { expect(showErrorMessage.mock.calls.length).toBe(1); expect(showErrorMessage.mock.calls[0][0]).toBe("Data set failed to save. Data set may have been deleted on mainframe."); - const node = new ZoweNode("HLQ.TEST.AFILE", vscode.TreeItemCollapsibleState.None, sessNode, null); + const node = new ZoweDatasetNode("HLQ.TEST.AFILE", vscode.TreeItemCollapsibleState.None, sessNode, null); sessNode.children.push(node); testResponse.apiResponse.items = [{dsname: "HLQ.TEST.AFILE"}, {dsname: "HLQ.TEST.AFILE(mem)"}]; dataSetList.mockReset(); @@ -1782,7 +1782,7 @@ describe("Extension Unit Tests", () => { dataSetList.mockReset(); showErrorMessage.mockReset(); - sessNode.children.push(new ZoweNode("HLQ.TEST.AFILE(mem)", vscode.TreeItemCollapsibleState.None, sessNode, null)); + sessNode.children.push(new ZoweDatasetNode("HLQ.TEST.AFILE(mem)", vscode.TreeItemCollapsibleState.None, sessNode, null)); testTree.getChildren.mockReturnValueOnce([sessNode]); dataSetList.mockResolvedValueOnce(testResponse); testResponse.success = true; @@ -1792,7 +1792,7 @@ describe("Extension Unit Tests", () => { await extension.saveFile(testDoc3, testTree); expect(concatChildNodes.mock.calls.length).toBe(1); - testTree.getChildren.mockReturnValueOnce([new ZoweNode("node", vscode.TreeItemCollapsibleState.None, sessNode, null), sessNode]); + testTree.getChildren.mockReturnValueOnce([new ZoweDatasetNode("node", vscode.TreeItemCollapsibleState.None, sessNode, null), sessNode]); dataSetList.mockReset(); showErrorMessage.mockReset(); @@ -1830,9 +1830,9 @@ describe("Extension Unit Tests", () => { existsSync.mockReset(); withProgress.mockReset(); - const node = new ZoweNode("node", vscode.TreeItemCollapsibleState.None, sessNode, null); - const parent = new ZoweNode("parent", vscode.TreeItemCollapsibleState.Collapsed, sessNode, null); - const child = new ZoweNode("child", vscode.TreeItemCollapsibleState.None, parent, null); + const node = new ZoweDatasetNode("node", vscode.TreeItemCollapsibleState.None, sessNode, null); + const parent = new ZoweDatasetNode("parent", vscode.TreeItemCollapsibleState.Collapsed, sessNode, null); + const child = new ZoweDatasetNode("child", vscode.TreeItemCollapsibleState.None, parent, null); existsSync.mockReturnValue(null); const response: brightside.IZosFilesResponse = { @@ -1868,7 +1868,7 @@ describe("Extension Unit Tests", () => { expect(showTextDocument.mock.calls[0][0]).toBe("test doc"); openTextDocument.mockResolvedValueOnce("test doc"); - const node2 = new ZoweNode("HLQ.TEST.NODE", vscode.TreeItemCollapsibleState.None, sessNode, null); + const node2 = new ZoweDatasetNode("HLQ.TEST.NODE", vscode.TreeItemCollapsibleState.None, sessNode, null); await extension.openPS(node2, true); @@ -1893,7 +1893,7 @@ describe("Extension Unit Tests", () => { expect(showErrorMessage.mock.calls.length).toBe(1); expect(showErrorMessage.mock.calls[0][0]).toBe("testError"); - const child2 = new ZoweNode("child", vscode.TreeItemCollapsibleState.None, node2, null); + const child2 = new ZoweDatasetNode("child", vscode.TreeItemCollapsibleState.None, node2, null); try { await extension.openPS(child2, true); } catch (err) { @@ -1931,7 +1931,7 @@ describe("Extension Unit Tests", () => { protocol: "https", type: "basic", }); - const dsNode = new ZoweNode("testSess", vscode.TreeItemCollapsibleState.Expanded, sessNode, sessionwocred); + const dsNode = new ZoweDatasetNode("testSess", vscode.TreeItemCollapsibleState.Expanded, sessNode, sessionwocred); dsNode.contextValue = extension.DS_SESSION_CONTEXT; Object.defineProperty(profileLoader.Profiles, "getInstance", { value: jest.fn(() => { @@ -1966,7 +1966,7 @@ describe("Extension Unit Tests", () => { protocol: "https", type: "basic", }); - const dsNode = new ZoweNode("[test]: TEST.JCL", vscode.TreeItemCollapsibleState.Expanded, sessNode, sessionwocred); + const dsNode = new ZoweDatasetNode("[test]: TEST.JCL", vscode.TreeItemCollapsibleState.Expanded, sessNode, sessionwocred); dsNode.contextValue = extension.DS_PDS_CONTEXT + extension.FAV_SUFFIX; Object.defineProperty(profileLoader.Profiles, "getInstance", { value: jest.fn(() => { @@ -2001,7 +2001,7 @@ describe("Extension Unit Tests", () => { protocol: "https", type: "basic", }); - const dsNode = new ZoweNode("testSess", vscode.TreeItemCollapsibleState.Expanded, sessNode, sessionwocred); + const dsNode = new ZoweDatasetNode("testSess", vscode.TreeItemCollapsibleState.Expanded, sessNode, sessionwocred); dsNode.contextValue = extension.DS_SESSION_CONTEXT; Object.defineProperty(profileLoader.Profiles, "getInstance", { value: jest.fn(() => { @@ -2033,7 +2033,7 @@ describe("Extension Unit Tests", () => { protocol: "https", type: "basic", }); - const dsNode = new ZoweNode("[test]: TEST.JCL", vscode.TreeItemCollapsibleState.Expanded, sessNode, sessionwocred); + const dsNode = new ZoweDatasetNode("[test]: TEST.JCL", vscode.TreeItemCollapsibleState.Expanded, sessNode, sessionwocred); dsNode.contextValue = extension.DS_PDS_CONTEXT + extension.FAV_SUFFIX; Object.defineProperty(profileLoader.Profiles, "getInstance", { value: jest.fn(() => { @@ -3424,7 +3424,7 @@ describe("Extension Unit Tests", () => { showInformationMessage.mockReset(); createBasicZosmfSession.mockReturnValue(session); submitJcl.mockReturnValue(iJob); - testTree.getChildren.mockReturnValueOnce([new ZoweNode("node", vscode.TreeItemCollapsibleState.None, sessNode, null), sessNode]); + testTree.getChildren.mockReturnValueOnce([new ZoweDatasetNode("node", vscode.TreeItemCollapsibleState.None, sessNode, null), sessNode]); await extension.submitJcl(testTree); expect(submitJcl).toBeCalled(); expect(showInformationMessage).toBeCalled(); @@ -3434,21 +3434,21 @@ describe("Extension Unit Tests", () => { it("tests that a pds member is submitted", async () => { showErrorMessage.mockReset(); - const rootNode = new ZoweNode("sessionRoot", vscode.TreeItemCollapsibleState.Collapsed, null, session); + const rootNode = new ZoweDatasetNode("sessionRoot", vscode.TreeItemCollapsibleState.Collapsed, null, session); rootNode.contextValue = extension.DS_SESSION_CONTEXT; - const file = new ZoweNode("file", vscode.TreeItemCollapsibleState.Collapsed, rootNode, null); + const file = new ZoweDatasetNode("file", vscode.TreeItemCollapsibleState.Collapsed, rootNode, null); file.contextValue = "file"; - const subNode = new ZoweNode(extension.DS_PDS_CONTEXT, vscode.TreeItemCollapsibleState.Collapsed, rootNode, null); - const member = new ZoweNode(extension.DS_MEMBER_CONTEXT, vscode.TreeItemCollapsibleState.None, subNode, null); - const favorite = new ZoweNode("Favorites", vscode.TreeItemCollapsibleState.Collapsed, rootNode, null); + const subNode = new ZoweDatasetNode(extension.DS_PDS_CONTEXT, vscode.TreeItemCollapsibleState.Collapsed, rootNode, null); + const member = new ZoweDatasetNode(extension.DS_MEMBER_CONTEXT, vscode.TreeItemCollapsibleState.None, subNode, null); + const favorite = new ZoweDatasetNode("Favorites", vscode.TreeItemCollapsibleState.Collapsed, rootNode, null); favorite.contextValue = extension.FAVORITE_CONTEXT; - const favoriteSubNode = new ZoweNode("[test]: TEST.JCL", vscode.TreeItemCollapsibleState.Collapsed, favorite, null); + const favoriteSubNode = new ZoweDatasetNode("[test]: TEST.JCL", vscode.TreeItemCollapsibleState.Collapsed, favorite, null); favoriteSubNode.contextValue = extension.DS_PDS_CONTEXT + extension.FAV_SUFFIX; - const favoritemember = new ZoweNode(extension.DS_PDS_CONTEXT, vscode.TreeItemCollapsibleState.Collapsed, favoriteSubNode, null); + const favoritemember = new ZoweDatasetNode(extension.DS_PDS_CONTEXT, vscode.TreeItemCollapsibleState.Collapsed, favoriteSubNode, null); favoritemember.contextValue = extension.DS_MEMBER_CONTEXT; - const gibberish = new ZoweNode("gibberish", vscode.TreeItemCollapsibleState.Collapsed, rootNode, null); + const gibberish = new ZoweDatasetNode("gibberish", vscode.TreeItemCollapsibleState.Collapsed, rootNode, null); gibberish.contextValue = "gibberish"; - const gibberishSubNode = new ZoweNode("gibberishmember", vscode.TreeItemCollapsibleState.Collapsed, gibberish, null); + const gibberishSubNode = new ZoweDatasetNode("gibberishmember", vscode.TreeItemCollapsibleState.Collapsed, gibberish, null); submitJob.mockReturnValue(iJob); // pds member @@ -3586,72 +3586,72 @@ describe("Extension Unit Tests", () => { it("Testing that the add Suffix for datasets works", async () => { extension.defineGlobals("/test/path/"); - let node = new ZoweNode("AUSER.TEST.JCL(member)", vscode.TreeItemCollapsibleState.None, sessNode, null); + let node = new ZoweDatasetNode("AUSER.TEST.JCL(member)", vscode.TreeItemCollapsibleState.None, sessNode, null); expect(extension.getDocumentFilePath(node.label, node)).toBe(path.join(path.sep, "test", "path", "temp", "_D_", "sestest", "AUSER.TEST.JCL(member).jcl")); - node = new ZoweNode("AUSER.TEST.ASM(member)", vscode.TreeItemCollapsibleState.None, sessNode, null); + node = new ZoweDatasetNode("AUSER.TEST.ASM(member)", vscode.TreeItemCollapsibleState.None, sessNode, null); expect(extension.getDocumentFilePath(node.label, node)).toBe(path.join(path.sep, "test", "path", "temp", "_D_", "sestest", "AUSER.TEST.ASM(member).asm")); - node = new ZoweNode("AUSER.COBOL.TEST(member)", vscode.TreeItemCollapsibleState.None, sessNode, null); + node = new ZoweDatasetNode("AUSER.COBOL.TEST(member)", vscode.TreeItemCollapsibleState.None, sessNode, null); expect(extension.getDocumentFilePath(node.label, node)).toBe(path.join(path.sep, "test", "path", "temp", "_D_", "sestest", "AUSER.COBOL.TEST(member).cbl")); - node = new ZoweNode("AUSER.PROD.PLI(member)", vscode.TreeItemCollapsibleState.None, sessNode, null); + node = new ZoweDatasetNode("AUSER.PROD.PLI(member)", vscode.TreeItemCollapsibleState.None, sessNode, null); expect(extension.getDocumentFilePath(node.label, node)).toBe(path.join(path.sep, "test", "path", "temp", "_D_", "sestest", "AUSER.PROD.PLI(member).pli")); - node = new ZoweNode("AUSER.PROD.PLX(member)", vscode.TreeItemCollapsibleState.None, sessNode, null); + node = new ZoweDatasetNode("AUSER.PROD.PLX(member)", vscode.TreeItemCollapsibleState.None, sessNode, null); expect(extension.getDocumentFilePath(node.label, node)).toBe(path.join(path.sep, "test", "path", "temp", "_D_", "sestest", "AUSER.PROD.PLX(member).pli")); - node = new ZoweNode("AUSER.PROD.SH(member)", vscode.TreeItemCollapsibleState.None, sessNode, null); + node = new ZoweDatasetNode("AUSER.PROD.SH(member)", vscode.TreeItemCollapsibleState.None, sessNode, null); expect(extension.getDocumentFilePath(node.label, node)).toBe(path.join(path.sep, "test", "path", "temp", "_D_", "sestest", "AUSER.PROD.SH(member).sh")); - node = new ZoweNode("AUSER.REXX.EXEC(member)", vscode.TreeItemCollapsibleState.None, sessNode, null); + node = new ZoweDatasetNode("AUSER.REXX.EXEC(member)", vscode.TreeItemCollapsibleState.None, sessNode, null); expect(extension.getDocumentFilePath(node.label, node)).toBe(path.join(path.sep, "test", "path", "temp", "_D_", "sestest", "AUSER.REXX.EXEC(member).rexx")); - node = new ZoweNode("AUSER.TEST.XML(member)", vscode.TreeItemCollapsibleState.None, sessNode, null); + node = new ZoweDatasetNode("AUSER.TEST.XML(member)", vscode.TreeItemCollapsibleState.None, sessNode, null); expect(extension.getDocumentFilePath(node.label, node)).toBe(path.join(path.sep, "test", "path", "temp", "_D_", "sestest", "AUSER.TEST.XML(member).xml")); - node = new ZoweNode("AUSER.TEST.XML", vscode.TreeItemCollapsibleState.None, sessNode, null); + node = new ZoweDatasetNode("AUSER.TEST.XML", vscode.TreeItemCollapsibleState.None, sessNode, null); expect(extension.getDocumentFilePath(node.label, node)).toBe(path.join(path.sep, "test", "path", "temp", "_D_", "sestest", "AUSER.TEST.XML.xml")); - node = new ZoweNode("AUSER.TEST.TXML", vscode.TreeItemCollapsibleState.None, sessNode, null); + node = new ZoweDatasetNode("AUSER.TEST.TXML", vscode.TreeItemCollapsibleState.None, sessNode, null); expect(extension.getDocumentFilePath(node.label, node)).toBe(path.join(path.sep, "test", "path", "temp", "_D_", "sestest", "AUSER.TEST.TXML")); - node = new ZoweNode("AUSER.XML.TGML", vscode.TreeItemCollapsibleState.None, sessNode, null); + node = new ZoweDatasetNode("AUSER.XML.TGML", vscode.TreeItemCollapsibleState.None, sessNode, null); expect(extension.getDocumentFilePath(node.label, node)).toBe(path.join(path.sep, "test", "path", "temp", "_D_", "sestest", "AUSER.XML.TGML.xml")); - node = new ZoweNode("AUSER.XML.ASM", vscode.TreeItemCollapsibleState.None, sessNode, null); + node = new ZoweDatasetNode("AUSER.XML.ASM", vscode.TreeItemCollapsibleState.None, sessNode, null); expect(extension.getDocumentFilePath(node.label, node)).toBe(path.join(path.sep, "test", "path", "temp", "_D_", "sestest", "AUSER.XML.ASM.asm")); - node = new ZoweNode("AUSER", vscode.TreeItemCollapsibleState.None, sessNode, null); + node = new ZoweDatasetNode("AUSER", vscode.TreeItemCollapsibleState.None, sessNode, null); expect(extension.getDocumentFilePath(node.label, node)).toBe(path.join(path.sep, "test", "path", "temp", "_D_", "sestest", "AUSER")); - node = new ZoweNode("AUSER.XML.TEST(member)", vscode.TreeItemCollapsibleState.None, sessNode, null); + node = new ZoweDatasetNode("AUSER.XML.TEST(member)", vscode.TreeItemCollapsibleState.None, sessNode, null); expect(extension.getDocumentFilePath(node.label, node)).toBe(path.join(path.sep, "test", "path", "temp", "_D_", "sestest", "AUSER.XML.TEST(member).xml")); - node = new ZoweNode("XML.AUSER.TEST(member)", vscode.TreeItemCollapsibleState.None, sessNode, null); + node = new ZoweDatasetNode("XML.AUSER.TEST(member)", vscode.TreeItemCollapsibleState.None, sessNode, null); expect(extension.getDocumentFilePath(node.label, node)).toBe(path.join(path.sep, "test", "path", "temp", "_D_", "sestest", "XML.AUSER.TEST(member)")); - node = new ZoweNode("AUSER.COBOL.PL1.XML.TEST(member)", vscode.TreeItemCollapsibleState.None, sessNode, null); + node = new ZoweDatasetNode("AUSER.COBOL.PL1.XML.TEST(member)", vscode.TreeItemCollapsibleState.None, sessNode, null); expect(extension.getDocumentFilePath(node.label, node)).toBe(path.join(path.sep, "test", "path", "temp", "_D_", "sestest", "AUSER.COBOL.PL1.XML.TEST(member).xml")); - node = new ZoweNode("AUSER.COBOL.PL1.XML.ASSEMBLER.TEST(member)", vscode.TreeItemCollapsibleState.None, sessNode, null); + node = new ZoweDatasetNode("AUSER.COBOL.PL1.XML.ASSEMBLER.TEST(member)", vscode.TreeItemCollapsibleState.None, sessNode, null); expect(extension.getDocumentFilePath(node.label, node)).toBe( path.join(path.sep, "test", "path", "temp", "_D_", "sestest", "AUSER.COBOL.PL1.XML.ASSEMBLER.TEST(member).asm")); - node = new ZoweNode("AUSER.TEST.COPYBOOK", vscode.TreeItemCollapsibleState.None, sessNode, null); + node = new ZoweDatasetNode("AUSER.TEST.COPYBOOK", vscode.TreeItemCollapsibleState.None, sessNode, null); expect(extension.getDocumentFilePath(node.label, node)).toBe(path.join(path.sep, "test", "path", "temp", "_D_", "sestest", "AUSER.TEST.COPYBOOK.cpy")); - node = new ZoweNode("AUSER.TEST.PLINC", vscode.TreeItemCollapsibleState.None, sessNode, null); + node = new ZoweDatasetNode("AUSER.TEST.PLINC", vscode.TreeItemCollapsibleState.None, sessNode, null); expect(extension.getDocumentFilePath(node.label, node)).toBe(path.join(path.sep, "test", "path", "temp", "_D_", "sestest", "AUSER.TEST.PLINC.inc")); - node = new ZoweNode("AUSER.TEST.SPFLOG1", vscode.TreeItemCollapsibleState.None, sessNode, null); + node = new ZoweDatasetNode("AUSER.TEST.SPFLOG1", vscode.TreeItemCollapsibleState.None, sessNode, null); expect(extension.getDocumentFilePath(node.label, node)).toEqual(path.join(path.sep, "test", "path", "temp", "_D_", "sestest", "AUSER.TEST.SPFLOG1.log")); }); it("Tests the showDSAttributes function", async () => { dataSetList.mockReset(); - const node = new ZoweNode("AUSER.A1557332.A996850.TEST1", vscode.TreeItemCollapsibleState.None, sessNode, null); + const node = new ZoweDatasetNode("AUSER.A1557332.A996850.TEST1", vscode.TreeItemCollapsibleState.None, sessNode, null); const testResponse = { success: true, commandResponse: "", @@ -3701,7 +3701,7 @@ describe("Extension Unit Tests", () => { // mock a partitioned data set favorite dataSetList.mockReset(); dataSetList.mockReturnValueOnce(testResponse); - const node1 = new ZoweNode("[session]: AUSER.A1557332.A996850.TEST1", vscode.TreeItemCollapsibleState.None, sessNode, null); + const node1 = new ZoweDatasetNode("[session]: AUSER.A1557332.A996850.TEST1", vscode.TreeItemCollapsibleState.None, sessNode, null); node1.contextValue = extension.DS_PDS_CONTEXT + extension.FAV_SUFFIX; await extension.showDSAttributes(node1, testTree); expect(dataSetList.mock.calls.length).toBe(1); @@ -3709,7 +3709,7 @@ describe("Extension Unit Tests", () => { // mock a classic data set favorite dataSetList.mockReset(); dataSetList.mockReturnValueOnce(testResponse); - const node2 = new ZoweNode("[session]: AUSER.A1557332.A996850.TEST1", vscode.TreeItemCollapsibleState.None, sessNode, null); + const node2 = new ZoweDatasetNode("[session]: AUSER.A1557332.A996850.TEST1", vscode.TreeItemCollapsibleState.None, sessNode, null); node2.contextValue = extension.DS_DS_CONTEXT + extension.FAV_SUFFIX; await extension.showDSAttributes(node2, testTree); expect(dataSetList.mock.calls.length).toBe(1); @@ -3730,7 +3730,7 @@ describe("Extension Unit Tests", () => { showInputBox.mockReset(); renameDataSet.mockReset(); - const child = new ZoweNode("HLQ.TEST.RENAME.NODE", vscode.TreeItemCollapsibleState.None, sessNode, null); + const child = new ZoweDatasetNode("HLQ.TEST.RENAME.NODE", vscode.TreeItemCollapsibleState.None, sessNode, null); showInputBox.mockResolvedValueOnce("HLQ.TEST.RENAME.NODE.NEW"); await extension.renameDataSet(child, testTree); @@ -3742,7 +3742,7 @@ describe("Extension Unit Tests", () => { showInputBox.mockReset(); renameDataSet.mockReset(); - const child = new ZoweNode("[sessNode]: HLQ.TEST.RENAME.NODE", vscode.TreeItemCollapsibleState.None, sessNode, null); + const child = new ZoweDatasetNode("[sessNode]: HLQ.TEST.RENAME.NODE", vscode.TreeItemCollapsibleState.None, sessNode, null); child.contextValue = "ds_fav"; showInputBox.mockResolvedValueOnce("HLQ.TEST.RENAME.NODE.NEW"); await extension.renameDataSet(child, testTree); @@ -3758,7 +3758,7 @@ describe("Extension Unit Tests", () => { renameDataSet.mockReset(); renameDataSet.mockImplementation(() => { throw defaultError; }); - const child = new ZoweNode("[sessNode]: HLQ.TEST.RENAME.NODE", vscode.TreeItemCollapsibleState.None, sessNode, null); + const child = new ZoweDatasetNode("[sessNode]: HLQ.TEST.RENAME.NODE", vscode.TreeItemCollapsibleState.None, sessNode, null); child.contextValue = "ds_fav"; showInputBox.mockResolvedValueOnce("HLQ.TEST.RENAME.NODE.NEW"); try { @@ -3775,8 +3775,8 @@ describe("Extension Unit Tests", () => { showInputBox.mockReset(); renameDataSet.mockReset(); - const parent = new ZoweNode("HLQ.TEST.RENAME.NODE", vscode.TreeItemCollapsibleState.None, sessNode, null); - const child = new ZoweNode("mem1", vscode.TreeItemCollapsibleState.None, parent, null); + const parent = new ZoweDatasetNode("HLQ.TEST.RENAME.NODE", vscode.TreeItemCollapsibleState.None, sessNode, null); + const child = new ZoweDatasetNode("mem1", vscode.TreeItemCollapsibleState.None, parent, null); showInputBox.mockResolvedValueOnce("mem2"); await extension.renameDataSetMember(child, testTree); @@ -3788,8 +3788,8 @@ describe("Extension Unit Tests", () => { showInputBox.mockReset(); renameDataSet.mockReset(); - const parent = new ZoweNode("[sesstest]: HLQ.TEST.RENAME.NODE", vscode.TreeItemCollapsibleState.None, sessNode, null); - const child = new ZoweNode("mem1", vscode.TreeItemCollapsibleState.None, parent, null); + const parent = new ZoweDatasetNode("[sesstest]: HLQ.TEST.RENAME.NODE", vscode.TreeItemCollapsibleState.None, sessNode, null); + const child = new ZoweDatasetNode("mem1", vscode.TreeItemCollapsibleState.None, parent, null); parent.contextValue = extension.DS_PDS_CONTEXT + extension.FAV_SUFFIX; child.contextValue = extension.DS_MEMBER_CONTEXT; @@ -3808,8 +3808,8 @@ describe("Extension Unit Tests", () => { renameDataSetMember.mockReset(); renameDataSetMember.mockImplementation(() => { throw defaultError; }); - const parent = new ZoweNode("HLQ.TEST.RENAME.NODE", vscode.TreeItemCollapsibleState.None, sessNode, null); - const child = new ZoweNode("mem1", vscode.TreeItemCollapsibleState.None, parent, null); + const parent = new ZoweDatasetNode("HLQ.TEST.RENAME.NODE", vscode.TreeItemCollapsibleState.None, sessNode, null); + const child = new ZoweDatasetNode("mem1", vscode.TreeItemCollapsibleState.None, parent, null); child.contextValue = extension.DS_MEMBER_CONTEXT; @@ -3829,7 +3829,7 @@ describe("Extension Unit Tests", () => { it("Should copy the label of a node to the clipboard", async () => { renameDataSet.mockReset(); - const node = new ZoweNode("HLQ.TEST.DELETE.NODE", vscode.TreeItemCollapsibleState.None, sessNode, null); + const node = new ZoweDatasetNode("HLQ.TEST.DELETE.NODE", vscode.TreeItemCollapsibleState.None, sessNode, null); node.contextValue = extension.DS_SESSION_CONTEXT; await extension.copyDataSet(node); @@ -3838,7 +3838,7 @@ describe("Extension Unit Tests", () => { it("Should copy the label of a favourited node to the clipboard", async () => { renameDataSet.mockReset(); - const node = new ZoweNode("[sestest]: HLQ.TEST.DELETE.NODE", vscode.TreeItemCollapsibleState.None, sessNode, null); + const node = new ZoweDatasetNode("[sestest]: HLQ.TEST.DELETE.NODE", vscode.TreeItemCollapsibleState.None, sessNode, null); node.contextValue = "ds_fav"; await extension.copyDataSet(node); @@ -3847,8 +3847,8 @@ describe("Extension Unit Tests", () => { it("Should copy the label of a member to the clipboard", async () => { renameDataSet.mockReset(); - const parent = new ZoweNode("HLQ.TEST.PARENT.NODE", vscode.TreeItemCollapsibleState.None, sessNode, null); - const child = new ZoweNode("child", vscode.TreeItemCollapsibleState.None, parent, null); + const parent = new ZoweDatasetNode("HLQ.TEST.PARENT.NODE", vscode.TreeItemCollapsibleState.None, sessNode, null); + const child = new ZoweDatasetNode("child", vscode.TreeItemCollapsibleState.None, parent, null); parent.contextValue = extension.DS_PDS_CONTEXT; child.contextValue = extension.DS_MEMBER_CONTEXT; await extension.copyDataSet(child); @@ -3857,8 +3857,8 @@ describe("Extension Unit Tests", () => { it("Should copy the label of a favourited member to the clipboard", async () => { renameDataSet.mockReset(); - const parent = new ZoweNode("[sestest]: HLQ.TEST.PARENT.NODE", vscode.TreeItemCollapsibleState.None, sessNode, null); - const child = new ZoweNode("child", vscode.TreeItemCollapsibleState.None, parent, null); + const parent = new ZoweDatasetNode("[sestest]: HLQ.TEST.PARENT.NODE", vscode.TreeItemCollapsibleState.None, sessNode, null); + const child = new ZoweDatasetNode("child", vscode.TreeItemCollapsibleState.None, parent, null); parent.contextValue = extension.DS_PDS_CONTEXT + extension.FAV_SUFFIX; child.contextValue = extension.DS_MEMBER_CONTEXT; await extension.copyDataSet(child); @@ -3867,7 +3867,7 @@ describe("Extension Unit Tests", () => { }); describe("Pasting Data Sets", () => { it("Should call zowe.Copy.dataSet when pasting to sequential data set", async () => { - const node = new ZoweNode("HLQ.TEST.TO.NODE", vscode.TreeItemCollapsibleState.None, sessNode, null); + const node = new ZoweDatasetNode("HLQ.TEST.TO.NODE", vscode.TreeItemCollapsibleState.None, sessNode, null); node.contextValue = extension.DS_SESSION_CONTEXT; clipboard.writeText(JSON.stringify({ dataSetName: "HLQ.TEST.BEFORE.NODE", profileName: "sestest" })); @@ -3882,7 +3882,7 @@ describe("Extension Unit Tests", () => { }); it("Should throw an error if invalid clipboard data is supplied when pasting to sequential data set", async () => { let error; - const node = new ZoweNode("HLQ.TEST.TO.NODE", vscode.TreeItemCollapsibleState.None, sessNode, null); + const node = new ZoweDatasetNode("HLQ.TEST.TO.NODE", vscode.TreeItemCollapsibleState.None, sessNode, null); node.contextValue = extension.DS_SESSION_CONTEXT; clipboard.writeText("INVALID"); try { @@ -3899,7 +3899,7 @@ describe("Extension Unit Tests", () => { dataSetGet.mockImplementation(() => { throw Error("Member not found"); }); - const node = new ZoweNode("HLQ.TEST.TO.NODE", vscode.TreeItemCollapsibleState.None, sessNode, null); + const node = new ZoweDatasetNode("HLQ.TEST.TO.NODE", vscode.TreeItemCollapsibleState.None, sessNode, null); node.contextValue = extension.DS_PDS_CONTEXT; clipboard.writeText(JSON.stringify({ dataSetName: "HLQ.TEST.BEFORE.NODE", profileName: "sestest" })); @@ -3911,7 +3911,7 @@ describe("Extension Unit Tests", () => { dataSetGet.mockImplementation(() => { throw Error("Member not found"); }); - const node = new ZoweNode("HLQ.TEST.TO.NODE", vscode.TreeItemCollapsibleState.None, sessNode, null); + const node = new ZoweDatasetNode("HLQ.TEST.TO.NODE", vscode.TreeItemCollapsibleState.None, sessNode, null); node.contextValue = extension.DS_PDS_CONTEXT; showInputBox.mockResolvedValueOnce("mem1"); @@ -3931,7 +3931,7 @@ describe("Extension Unit Tests", () => { it("Should throw an error when pasting to a member that already exists", async () => { let error; dataSetGet.mockImplementation(() => "DATA"); - const node = new ZoweNode("HLQ.TEST.TO.NODE", vscode.TreeItemCollapsibleState.None, sessNode, null); + const node = new ZoweDatasetNode("HLQ.TEST.TO.NODE", vscode.TreeItemCollapsibleState.None, sessNode, null); node.contextValue = extension.DS_PDS_CONTEXT; showInputBox.mockResolvedValueOnce("mem1"); @@ -3952,9 +3952,9 @@ describe("Extension Unit Tests", () => { dataSetGet.mockImplementation(() => { throw Error("Member not found"); }); - const favoritedNode = new ZoweNode("[sestest]: HLQ.TEST.TO.NODE", vscode.TreeItemCollapsibleState.None, sessNode, null); + const favoritedNode = new ZoweDatasetNode("[sestest]: HLQ.TEST.TO.NODE", vscode.TreeItemCollapsibleState.None, sessNode, null); favoritedNode.contextValue = extension.DS_PDS_CONTEXT + extension.FAV_SUFFIX; - const nonFavoritedNode = new ZoweNode("HLQ.TEST.TO.NODE", vscode.TreeItemCollapsibleState.None, sessNode, null); + const nonFavoritedNode = new ZoweDatasetNode("HLQ.TEST.TO.NODE", vscode.TreeItemCollapsibleState.None, sessNode, null); findNonFavoritedNode.mockImplementation(() => nonFavoritedNode); showInputBox.mockResolvedValueOnce("mem1"); diff --git a/__tests__/__unit__/mvs/mvsNodeActions.unit.test.ts b/__tests__/__unit__/mvs/mvsNodeActions.unit.test.ts index 0dcc39b360..6e1855bc6e 100644 --- a/__tests__/__unit__/mvs/mvsNodeActions.unit.test.ts +++ b/__tests__/__unit__/mvs/mvsNodeActions.unit.test.ts @@ -11,7 +11,7 @@ import * as vscode from "vscode"; import * as mvsNodeActions from "../../../src/mvs/mvsNodeActions"; -import { ZoweNode } from "../../../src/ZoweNode"; +import { ZoweDatasetNode } from "../../../src/ZoweDatasetNode"; import * as extension from "../../../src/extension"; const mockRefresh = jest.fn(); @@ -35,7 +35,7 @@ describe("mvsNodeActions", () => { jest.resetAllMocks(); }); it("should call upload dialog and upload file", async () => { - const node = new ZoweNode("node", vscode.TreeItemCollapsibleState.Collapsed, null, null); + const node = new ZoweDatasetNode("node", vscode.TreeItemCollapsibleState.Collapsed, null, null); const fileUri = {fsPath: "/tmp/foo"}; showOpenDialog.mockReturnValue([fileUri]); openTextDocument.mockReturnValue({}); @@ -50,16 +50,16 @@ describe("mvsNodeActions", () => { }); it("should return default label for dataset", () => { const labelName = "dataset.test"; - const node = new ZoweNode(labelName, vscode.TreeItemCollapsibleState.Collapsed, null, null); + const node = new ZoweDatasetNode(labelName, vscode.TreeItemCollapsibleState.Collapsed, null, null); const label = mvsNodeActions.getDatasetLabel(node); expect(label).toEqual(labelName); }); it("should return default label for dataset", () => { const labelNameWithProfile = "[myProfile123]: dataset.test"; const labelName = "dataset.test"; - const parentNode = new ZoweNode("Favorites", vscode.TreeItemCollapsibleState.Collapsed, null, null); + const parentNode = new ZoweDatasetNode("Favorites", vscode.TreeItemCollapsibleState.Collapsed, null, null); parentNode.contextValue = extension.FAVORITE_CONTEXT; - const node = new ZoweNode(labelNameWithProfile, vscode.TreeItemCollapsibleState.Collapsed, parentNode, null); + const node = new ZoweDatasetNode(labelNameWithProfile, vscode.TreeItemCollapsibleState.Collapsed, parentNode, null); const label = mvsNodeActions.getDatasetLabel(node); expect(label).toEqual(labelName); }); diff --git a/__tests__/__unit__/uss/ussNodeActions.unit.test.ts b/__tests__/__unit__/uss/ussNodeActions.unit.test.ts index f311f086ee..20418997e9 100644 --- a/__tests__/__unit__/uss/ussNodeActions.unit.test.ts +++ b/__tests__/__unit__/uss/ussNodeActions.unit.test.ts @@ -275,37 +275,6 @@ describe("ussNodeActions", () => { expect(testUSSTree.refresh).not.toHaveBeenCalled(); }); }); - describe("deleteUSSNode", () => { - it("should delete node if user verified", async () => { - showQuickPick.mockResolvedValueOnce("Yes"); - await ussNodeActions.deleteUSSNode(ussNode, testUSSTree, ""); - expect(testUSSTree.refresh).toHaveBeenCalled(); - }); - it("should not delete node if user did not verify", async () => { - showQuickPick.mockResolvedValueOnce("No"); - await ussNodeActions.deleteUSSNode(ussNode, testUSSTree, ""); - expect(testUSSTree.refresh).not.toHaveBeenCalled(); - }); - it("should not delete node if user cancelled", async () => { - showQuickPick.mockResolvedValueOnce(undefined); - await ussNodeActions.deleteUSSNode(ussNode, testUSSTree, ""); - expect(testUSSTree.refresh).not.toHaveBeenCalled(); - }); - it("should not delete node if an error thrown", async () => { - showErrorMessage.mockReset(); - showQuickPick.mockResolvedValueOnce("Yes"); - ussFile.mockImplementationOnce(() => { - throw (Error("testError")); - }); - try { - await ussNodeActions.deleteUSSNode(ussNode, testUSSTree, ""); - // tslint:disable-next-line:no-empty - } catch (err) { - } - expect(showErrorMessage.mock.calls.length).toBe(1); - expect(testUSSTree.refresh).not.toHaveBeenCalled(); - }); - }); describe("renameUSSNode", () => { it("should exit if blank input is provided", () => { diff --git a/i18n/sample/src/ZoweDatasetNode.i18n.json b/i18n/sample/src/ZoweDatasetNode.i18n.json new file mode 100644 index 0000000000..c47c41da6c --- /dev/null +++ b/i18n/sample/src/ZoweDatasetNode.i18n.json @@ -0,0 +1,7 @@ +{ + "getChildren.search": "Use the search button to display datasets", + "getChildren.error.invalidNode": "Invalid node", + "getChildren.error.response": "Retrieving response from zowe.List", + "getChildren.responses.error": "The response from Zowe CLI was not successful", + "getChildren.noDataset": "No datasets found" +} \ No newline at end of file diff --git a/i18n/sample/src/uss/ussNodeActions.i18n.json b/i18n/sample/src/uss/ussNodeActions.i18n.json index 676b238cd6..3c4541d98e 100644 --- a/i18n/sample/src/uss/ussNodeActions.i18n.json +++ b/i18n/sample/src/uss/ussNodeActions.i18n.json @@ -1,10 +1,6 @@ { "createUSSNode.name": "Name of file or directory", "createUSSNode.error.create": "Unable to create node: ", - "deleteUSSNode.quickPickOption": "Are you sure you want to delete ", - "deleteUSSNode.showQuickPick.yes": "Yes", - "deleteUSSNode.showQuickPick.no": "No", - "deleteUSSNode.error.node": "Unable to delete node: ", - "renameUSSNode.error": "Unable to rename node: ", + "renameUSSNode.error": "Unable to rename node: ", "copyPath.infoMessage": "Copy Path is not yet supported in Theia." } \ No newline at end of file diff --git a/src/DatasetTree.ts b/src/DatasetTree.ts index 7b630ddb6b..da8bd6048b 100644 --- a/src/DatasetTree.ts +++ b/src/DatasetTree.ts @@ -17,9 +17,10 @@ import * as nls from "vscode-nls"; import * as extension from "../src/extension"; import { Profiles } from "./Profiles"; import { sortTreeItems, applyIcons, FilterDescriptor, FilterItem, getAppName, resolveQuickPickHelper } from "./utils"; -import { IZoweTree, IZoweDatasetTreeNode } from "./api/ZoweTree"; +import { IZoweTree } from "./api/IZoweTree"; +import { IZoweDatasetTreeNode } from "./api/IZoweTreeNode"; import { ZoweTreeProvider } from "./abstract/ZoweTreeProvider"; -import { ZoweNode } from "./ZoweNode"; +import { ZoweDatasetNode } from "./ZoweDatasetNode"; const localize = nls.config({ messageFormat: nls.MessageFormat.file })(); /** @@ -45,13 +46,13 @@ export class DatasetTree extends ZoweTreeProvider implements IZoweTree} + * @returns {Promise} */ - public async getChildren(): Promise { + public async getChildren(): Promise { if ((!this.pattern && this.contextValue === extension.DS_SESSION_CONTEXT)){ - return [new ZoweNode(localize("getChildren.search", "Use the search button to display datasets"), + return [new ZoweDatasetNode(localize("getChildren.search", "Use the search button to display datasets"), vscode.TreeItemCollapsibleState.None, this, null, extension.INFORMATION_CONTEXT)]; } @@ -133,22 +133,23 @@ export class ZoweNode extends ZoweTreeNode implements IZoweDatasetTreeNode { const existing = this.children.find((element) => element.label.trim() === item.dsname ); if (existing) { elementChildren[existing.label] = existing; - // Creates a ZoweNode for a PDS + // Creates a ZoweDatasetNode for a PDS } else if (item.dsorg === "PO" || item.dsorg === "PO-E") { - const temp = new ZoweNode(item.dsname, vscode.TreeItemCollapsibleState.Collapsed, this, null); + const temp = new ZoweDatasetNode(item.dsname, vscode.TreeItemCollapsibleState.Collapsed, this, null); elementChildren[temp.label] = temp; } else if (item.migr && item.migr.toUpperCase() === "YES") { - const temp = new ZoweNode(item.dsname, vscode.TreeItemCollapsibleState.None, this, null, extension.DS_MIGRATED_FILE_CONTEXT); + const temp = new ZoweDatasetNode(item.dsname, vscode.TreeItemCollapsibleState.None, + this, null, extension.DS_MIGRATED_FILE_CONTEXT); elementChildren[temp.label] = temp; } else if (this.contextValue === extension.DS_SESSION_CONTEXT) { - // Creates a ZoweNode for a PS - const temp = new ZoweNode(item.dsname, vscode.TreeItemCollapsibleState.None, this, null); - temp.command = {command: "zowe.ZoweNode.openPS", title: "", arguments: [temp]}; + // Creates a ZoweDatasetNode for a PS + const temp = new ZoweDatasetNode(item.dsname, vscode.TreeItemCollapsibleState.None, this, null); + temp.command = {command: "zowe.ZoweDatasetNode.openPS", title: "", arguments: [temp]}; elementChildren[temp.label] = temp; } else { - // Creates a ZoweNode for a PDS member - const temp = new ZoweNode(item.member, vscode.TreeItemCollapsibleState.None, this, null); - temp.command = {command: "zowe.ZoweNode.openPS", title: "", arguments: [temp]}; + // Creates a ZoweDatasetNode for a PDS member + const temp = new ZoweDatasetNode(item.member, vscode.TreeItemCollapsibleState.None, this, null); + temp.command = {command: "zowe.ZoweDatasetNode.openPS", title: "", arguments: [temp]}; elementChildren[temp.label] = temp; } } @@ -156,7 +157,7 @@ export class ZoweNode extends ZoweTreeNode implements IZoweDatasetTreeNode { this.dirty = false; if (Object.keys(elementChildren).length === 0) { - return this.children = [new ZoweNode(localize("getChildren.noDataset", "No datasets found"), + return this.children = [new ZoweDatasetNode(localize("getChildren.noDataset", "No datasets found"), vscode.TreeItemCollapsibleState.None, this, null, extension.INFORMATION_CONTEXT)]; } else { return this.children = Object.keys(elementChildren).sort().map((labels) => elementChildren[labels]); diff --git a/src/ZoweJobNode.ts b/src/ZoweJobNode.ts index 74ee45eb45..6f0983b309 100644 --- a/src/ZoweJobNode.ts +++ b/src/ZoweJobNode.ts @@ -15,7 +15,7 @@ import { Session } from "@brightside/imperative"; // tslint:disable-next-line: no-duplicate-imports import { IJob, IJobFile } from "@brightside/core"; import * as extension from "./extension"; -import { IZoweJobTreeNode } from "./api/ZoweTree"; +import { IZoweJobTreeNode } from "./api/IZoweTreeNode"; import { ZoweTreeNode } from "./abstract/ZoweTreeNode"; import * as utils from "./utils"; diff --git a/src/ZoweUSSNode.ts b/src/ZoweUSSNode.ts index cd9d48a960..39f93db701 100644 --- a/src/ZoweUSSNode.ts +++ b/src/ZoweUSSNode.ts @@ -13,7 +13,7 @@ import * as zowe from "@brightside/core"; import { Session } from "@brightside/imperative"; import * as vscode from "vscode"; import * as nls from "vscode-nls"; -import { IZoweUSSTreeNode } from "./api/ZoweTree"; +import { IZoweUSSTreeNode } from "./api/IZoweTreeNode"; const localize = nls.config({ messageFormat: nls.MessageFormat.file })(); import * as extension from "../src/extension"; import * as utils from "./utils"; diff --git a/src/__mocks__/DatasetTree.ts b/src/__mocks__/DatasetTree.ts index 756cce261a..423e71468f 100644 --- a/src/__mocks__/DatasetTree.ts +++ b/src/__mocks__/DatasetTree.ts @@ -10,7 +10,7 @@ */ import * as vscode from "vscode"; -import { ZoweNode } from "../ZoweNode"; +import { ZoweDatasetNode } from "../ZoweDatasetNode"; import { MockMethod } from "../decorators/MockMethod"; /** @@ -20,35 +20,35 @@ import { MockMethod } from "../decorators/MockMethod"; * @class DatasetTree * @implements {vscode.TreeDataProvider} */ -export class DatasetTree implements vscode.TreeDataProvider { - public mSessionNodes: ZoweNode[] = []; +export class DatasetTree implements vscode.TreeDataProvider { + public mSessionNodes: ZoweDatasetNode[] = []; // Event Emitters used to notify subscribers that the refresh event has fired - public mOnDidChangeTreeData: vscode.EventEmitter = new vscode.EventEmitter(); - public readonly onDidChangeTreeData: vscode.Event = this.mOnDidChangeTreeData.event; + public mOnDidChangeTreeData: vscode.EventEmitter = new vscode.EventEmitter(); + public readonly onDidChangeTreeData: vscode.Event = this.mOnDidChangeTreeData.event; /** - * Takes argument of type ZoweNode and returns it converted to a general [TreeItem] + * Takes argument of type ZoweDatasetNode and returns it converted to a general [TreeItem] * - * @param {ZoweNode} element - The ZoweNode that is to be converted + * @param {ZoweDatasetNode} element - The ZoweDatasetNode that is to be converted * @returns {vscode.TreeItem} * @memberof DatasetTree */ @MockMethod() - public getTreeItem(element: ZoweNode): vscode.TreeItem { + public getTreeItem(element: ZoweDatasetNode): vscode.TreeItem { return null; } /** - * Takes argument of type ZoweNode and retrieves all of the first level children + * Takes argument of type ZoweDatasetNode and retrieves all of the first level children * - * @param {ZoweNode} [element] - The ZoweNode that is to be converted - * @returns {Thenable} + * @param {ZoweDatasetNode} [element] - The ZoweDatasetNode that is to be converted + * @returns {Thenable} * @memberof DatasetTree */ @MockMethod() - public getChildren(element?: ZoweNode): Promise { - return new Promise((resolve) => { + public getChildren(element?: ZoweDatasetNode): Promise { + return new Promise((resolve) => { return resolve(null); }); } @@ -66,12 +66,12 @@ export class DatasetTree implements vscode.TreeDataProvider { /** * Check if the parent exists, and return null if it has no parent * - * @param {ZoweNode} element - The ZoweNode of which to retrieve the parent - * @returns {vscode.ProviderResult} + * @param {ZoweDatasetNode} element - The ZoweDatasetNode of which to retrieve the parent + * @returns {vscode.ProviderResult} * @memberof DatasetTree */ @MockMethod() - public getParent(element: ZoweNode): vscode.ProviderResult { + public getParent(element: ZoweDatasetNode): vscode.ProviderResult { return null; } @@ -83,14 +83,14 @@ export class DatasetTree implements vscode.TreeDataProvider { } @MockMethod() - public async deleteSession(node?: ZoweNode): Promise { + public async deleteSession(node?: ZoweDatasetNode): Promise { return new Promise((resolve) => { return resolve(); }); } @MockMethod() - public async removeFavorite(node: ZoweNode) { + public async removeFavorite(node: ZoweDatasetNode) { return new Promise((resolve) => { return resolve(); }); diff --git a/src/abstract/ZoweTreeNode.ts b/src/abstract/ZoweTreeNode.ts index 1a714a4b96..b048451a73 100644 --- a/src/abstract/ZoweTreeNode.ts +++ b/src/abstract/ZoweTreeNode.ts @@ -11,7 +11,7 @@ import * as vscode from "vscode"; import { Session } from "@brightside/imperative"; -import { IZoweTreeNode } from "../api/ZoweTree"; +import { IZoweTreeNode } from "../api/IZoweTreeNode"; // import * as extension from "../extension"; /** @@ -19,7 +19,7 @@ import { IZoweTreeNode } from "../api/ZoweTree"; * IZoweTreeNode * * @export - * @class ZoweNode + * @class ZoweDatasetNode * @extends {vscode.TreeItem} */ export class ZoweTreeNode extends vscode.TreeItem { @@ -32,7 +32,7 @@ export class ZoweTreeNode extends vscode.TreeItem { public shortLabel = ""; /** - * Creates an instance of ZoweNode + * Creates an instance of ZoweDatasetNode * * @param {string} label - Displayed in the [TreeView] * @param {vscode.TreeItemCollapsibleState} mCollapsibleState - file/folder diff --git a/src/abstract/ZoweTreeProvider.ts b/src/abstract/ZoweTreeProvider.ts index 6910127141..cb72efb7e0 100644 --- a/src/abstract/ZoweTreeProvider.ts +++ b/src/abstract/ZoweTreeProvider.ts @@ -15,7 +15,7 @@ import { Logger } from "@brightside/imperative"; import { Profiles } from "../Profiles"; import { PersistentFilters } from "../PersistentFilters"; import { OwnerFilterDescriptor, applyIcons } from "../utils"; -import { IZoweTreeNode } from "../api/ZoweTree"; +import { IZoweTreeNode } from "../api/IZoweTreeNode"; import * as extension from "../extension"; // tslint:disable-next-line: max-classes-per-file diff --git a/src/api/IZoweTree.ts b/src/api/IZoweTree.ts new file mode 100644 index 0000000000..8e2bf590a5 --- /dev/null +++ b/src/api/IZoweTree.ts @@ -0,0 +1,62 @@ +/* +* This program and the accompanying materials are made available under the terms of the * +* Eclipse Public License v2.0 which accompanies this distribution, and is available at * +* https://www.eclipse.org/legal/epl-v20.html * +* * +* SPDX-License-Identifier: EPL-2.0 * +* * +* Copyright Contributors to the Zowe Project. * +* * +*/ + +import * as vscode from "vscode"; +import { IZoweTreeNode } from "./IZoweTreeNode"; + +/** + * The base interface for Zowe tree browsers that implement the + * vscode.TreeDataProvider. + * + * @export + * @interface IZoweTree + * @extends {vscode.TreeDataProvider} + * @template T provide a subtype of vscode.TreeItem + */ +export interface IZoweTree extends vscode.TreeDataProvider { + /** + * Root session nodes + */ + mSessionNodes: T[]; + /** + * Root favorites node + */ + mFavoriteSession: T; + /** + * Array of favorite nodes + */ + mFavorites: T[]; + /** + * Adds a session to the container + * @param sessionName + * @param type e.g. zosmf + */ + addSession(sessionName?: string, type?: string): Promise; + /** + * Adds a favorite node + * @param favorite Adds a favorite node + */ + addFavorite(favorite: IZoweTreeNode); + /** + * Removes a favorite node + * @param favorite Adds a favorite node + */ + removeFavorite(node: IZoweTreeNode); + /** + * Refreshes the tree + */ + refresh(): void; + /** + * Refreshes an element of the tree + * @param favorite Node to refresh + */ + refreshElement(node: IZoweTreeNode): void; +} diff --git a/src/api/ZoweTree.ts b/src/api/IZoweTreeNode.ts similarity index 81% rename from src/api/ZoweTree.ts rename to src/api/IZoweTreeNode.ts index 7c2b794cc1..b04a0facb0 100644 --- a/src/api/ZoweTree.ts +++ b/src/api/IZoweTreeNode.ts @@ -14,55 +14,7 @@ import { Session } from "@brightside/imperative"; import { IJob } from "@brightside/core"; /** - * The base interface for Zowe tree browsers that implement the - * vscode.TreeDataProvider. - * - * @export - * @interface IZoweTree - * @extends {vscode.TreeDataProvider} - * @template T provide a subtype of vscode.TreeItem - */ -export interface IZoweTree extends vscode.TreeDataProvider { - /** - * Root session nodes - */ - mSessionNodes: T[]; - /** - * Root favorites node - */ - mFavoriteSession: T; - /** - * Array of favorite nodes - */ - mFavorites: T[]; - /** - * Adds a session to the container - * @param sessionName - * @param type e.g. zosmf - */ - addSession(sessionName?: string, type?: string): Promise; - /** - * Adds a favorite node - * @param favorite Adds a favorite node - */ - addFavorite(favorite: IZoweTreeNode); - /** - * Removes a favorite node - * @param favorite Adds a favorite node - */ - removeFavorite(node: IZoweTreeNode); - /** - * Refreshes the tree - */ - refresh(): void; - /** - * Refreshes an element of the tree - * @param favorite Node to refresh - */ - refreshElement(node: IZoweTreeNode): void; -} -/** - * The base interface for Zowe tree nodes. + * The base interface for Zowe tree nodes that are implemented by vscode.TreeItem. * * @export * @interface IZoweTreeNode diff --git a/src/extension.ts b/src/extension.ts index b0879e74ca..052633b333 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -14,8 +14,9 @@ import * as fs from "fs"; import { moveSync } from "fs-extra"; import * as path from "path"; import * as vscode from "vscode"; -import { IZoweTree, IZoweTreeNode, IZoweJobTreeNode, IZoweUSSTreeNode, IZoweDatasetTreeNode } from "./api/ZoweTree"; -import { ZoweNode } from "./ZoweNode"; +import { IZoweTree } from "./api/IZoweTree"; +import { IZoweTreeNode, IZoweJobTreeNode, IZoweUSSTreeNode, IZoweDatasetTreeNode } from "./api/IZoweTreeNode"; +import { ZoweDatasetNode } from "./ZoweDatasetNode"; import { Logger, TextUtils, IProfileLoaded, ISession, IProfile, Session } from "@brightside/imperative"; import { DatasetTree, createDatasetTree } from "./DatasetTree"; import { ZosJobsProvider, createJobsTree } from "./ZosJobsProvider"; @@ -141,7 +142,7 @@ export async function activate(context: vscode.ExtensionContext) { vscode.commands.registerCommand("zowe.refreshAll", () => refreshAll(datasetProvider)); vscode.commands.registerCommand("zowe.refreshNode", (node) => refreshPS(node)); vscode.commands.registerCommand("zowe.pattern", (node) => datasetProvider.datasetFilterPrompt(node)); - vscode.commands.registerCommand("zowe.ZoweNode.openPS", (node) => openPS(node, true, datasetProvider)); + vscode.commands.registerCommand("zowe.ZoweDatasetNode.openPS", (node) => openPS(node, true, datasetProvider)); vscode.workspace.onDidSaveTextDocument(async (savedFile) => { log.debug(localize("onDidSaveTextDocument1", "File was saved -- determining whether the file is a USS file or Data set.\n Comparing (case insensitive) ") + @@ -214,8 +215,7 @@ export async function activate(context: vscode.ExtensionContext) { vscode.commands.registerCommand("zowe.uss.removeSession", async (node) => ussFileProvider.deleteSession(node)); vscode.commands.registerCommand("zowe.uss.createFile", async (node) => ussActions.createUSSNode(node, ussFileProvider, "file")); vscode.commands.registerCommand("zowe.uss.createFolder", async (node) => ussActions.createUSSNode(node, ussFileProvider, "directory")); - vscode.commands.registerCommand("zowe.uss.deleteNode", - async (node) => ussActions.deleteUSSNode(node, ussFileProvider, getUSSDocumentFilePath(node))); + vscode.commands.registerCommand("zowe.uss.deleteNode", async (node) => node.deleteUSSNode(ussFileProvider, getUSSDocumentFilePath(node))); vscode.commands.registerCommand("zowe.uss.binary", async (node) => changeFileType(node, true, ussFileProvider)); vscode.commands.registerCommand("zowe.uss.text", async (node) => changeFileType(node, false, ussFileProvider)); vscode.commands.registerCommand("zowe.uss.renameNode", @@ -630,10 +630,10 @@ export async function addZoweSession(zoweFileProvider: IZoweTree) * TODO: Consider changing configuration to allow "custom" data set specifications * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! * @export - * @param {ZoweNode} node - Desired Brightside session + * @param {ZoweDatasetNode} node - Desired Brightside session * @param {DatasetTree} datasetProvider - the tree which contains the nodes */ -export async function createFile(node: ZoweNode, datasetProvider: DatasetTree) { +export async function createFile(node: ZoweDatasetNode, datasetProvider: DatasetTree) { const quickPickOptions: vscode.QuickPickOptions = { placeHolder: localize("createFile.quickPickOption.dataSetType", "Type of Data Set to be Created"), ignoreFocusOut: true, @@ -772,10 +772,10 @@ export async function createFile(node: ZoweNode, datasetProvider: DatasetTree) { * Creates a PDS member * * @export - * @param {ZoweNode} parent - The parent Node + * @param {ZoweDatasetNode} parent - The parent Node * @param {DatasetTree} datasetProvider - the tree which contains the nodes */ -export async function createMember(parent: ZoweNode, datasetProvider: DatasetTree) { +export async function createMember(parent: ZoweDatasetNode, datasetProvider: DatasetTree) { const name = await vscode.window.showInputBox({ placeHolder: localize("createMember.inputBox", "Name of Member") }); log.debug(localize("createMember.log.debug.createNewDataSet", "creating new data set member of name ") + name); if (name) { @@ -793,7 +793,7 @@ export async function createMember(parent: ZoweNode, datasetProvider: DatasetTre } parent.dirty = true; datasetProvider.refreshElement(parent); - openPS(new ZoweNode(name, vscode.TreeItemCollapsibleState.None, parent, null), true, datasetProvider); + openPS(new ZoweDatasetNode(name, vscode.TreeItemCollapsibleState.None, parent, null), true, datasetProvider); datasetProvider.refresh(); } } @@ -803,10 +803,10 @@ export async function createMember(parent: ZoweNode, datasetProvider: DatasetTre * Shows data set attributes in a new text editor * * @export - * @param {ZoweNode} parent - The parent Node + * @param {ZoweDatasetNode} parent - The parent Node * @param {DatasetTree} datasetProvider - the tree which contains the nodes */ -export async function showDSAttributes(parent: ZoweNode, datasetProvider: DatasetTree) { +export async function showDSAttributes(parent: ZoweDatasetNode, datasetProvider: DatasetTree) { let label = parent.label.trim(); if (parent.contextValue === DS_PDS_CONTEXT + FAV_SUFFIX || parent.contextValue === DS_DS_CONTEXT + FAV_SUFFIX) { @@ -869,10 +869,10 @@ export async function showDSAttributes(parent: ZoweNode, datasetProvider: Datase * Rename data sets * * @export - * @param {ZoweNode} node - The node + * @param {ZoweDatasetNode} node - The node * @param {DatasetTree} datasetProvider - the tree which contains the nodes */ -export async function renameDataSet(node: ZoweNode, datasetProvider: DatasetTree) { +export async function renameDataSet(node: ZoweDatasetNode, datasetProvider: DatasetTree) { let beforeDataSetName = node.label.trim(); let favPrefix; let isFavourite; @@ -934,9 +934,9 @@ function getNodeLabels(node: IZoweTreeNode) { * Copy data sets * * @export - * @param {ZoweNode} node - The node to copy + * @param {ZoweDatasetNode} node - The node to copy */ -export async function copyDataSet(node: ZoweNode) { +export async function copyDataSet(node: ZoweDatasetNode) { return vscode.env.clipboard.writeText(JSON.stringify(getNodeLabels(node))); } @@ -944,10 +944,10 @@ export async function copyDataSet(node: ZoweNode) { * Paste data sets * * @export - * @param {ZoweNode} node - The node to paste to + * @param {ZoweDatasetNode} node - The node to paste to * @param {DatasetTree} datasetProvider - the tree which contains the nodes */ -export async function pasteDataSet(node: ZoweNode, datasetProvider: DatasetTree) { +export async function pasteDataSet(node: ZoweDatasetNode, datasetProvider: DatasetTree) { const { profileName, dataSetName } = getNodeLabels(node); let memberName; let beforeDataSetName; @@ -1311,7 +1311,7 @@ function appendSuffix(label: string): string { * * @export * @param {string} label - If node is a member, label includes the name of the PDS - * @param {ZoweNode} node + * @param {ZoweDatasetNode} node */ export function getDocumentFilePath(label: string, node: IZoweTreeNode) { return path.join(DS_DIR, "/" + getProfile(node) + "/" + appendSuffix(label) ); @@ -1434,9 +1434,9 @@ export async function refreshAll(datasetProvider: DatasetTree) { /** * Refreshes the passed node with current mainframe data * - * @param {ZoweNode} node - The node which represents the dataset + * @param {ZoweDatasetNode} node - The node which represents the dataset */ -export async function refreshPS(node: ZoweNode) { +export async function refreshPS(node: ZoweDatasetNode) { let label; try { switch (node.getParent().contextValue) { diff --git a/src/jobs/jobNodeActions.ts b/src/jobs/jobNodeActions.ts deleted file mode 100644 index 9c3c93b5df..0000000000 --- a/src/jobs/jobNodeActions.ts +++ /dev/null @@ -1,27 +0,0 @@ -/* -* This program and the accompanying materials are made available under the terms of the * -* Eclipse Public License v2.0 which accompanies this distribution, and is available at * -* https://www.eclipse.org/legal/epl-v20.html * -* * -* SPDX-License-Identifier: EPL-2.0 * -* * -* Copyright Contributors to the Zowe Project. * -* * -*/ - -import * as vscode from "vscode"; -import { DeleteJobs } from "@brightside/core"; -import * as nls from "vscode-nls"; -import { Job } from "../ZoweJobNode"; -const localize = nls.config({ messageFormat: nls.MessageFormat.file })(); - -export async function deleteJob(node: Job) { - try { - await DeleteJobs.deleteJob(node.getSession(), node.job.jobname, node.job.jobid); - vscode.window.showInformationMessage(localize("deleteJob.job", "Job ") + node.job.jobname + "(" + node.job.jobid + ")" + - localize("deleteJob.delete", " deleted")); - } catch (error) { - vscode.window.showErrorMessage(error.message); - } -} - diff --git a/src/mvs/mvsNodeActions.ts b/src/mvs/mvsNodeActions.ts index bbc4395d6e..6728f264ee 100644 --- a/src/mvs/mvsNodeActions.ts +++ b/src/mvs/mvsNodeActions.ts @@ -11,11 +11,11 @@ import * as zowe from "@brightside/core"; import * as vscode from "vscode"; -import { ZoweNode } from "../ZoweNode"; +import { ZoweDatasetNode } from "../ZoweDatasetNode"; import { DatasetTree } from "../DatasetTree"; import * as extension from "../../src/extension"; -export async function uploadDialog(node: ZoweNode, datasetProvider: DatasetTree) { +export async function uploadDialog(node: ZoweDatasetNode, datasetProvider: DatasetTree) { const fileOpenOptions = { canSelectFiles: true, openLabel: "Upload File", @@ -34,7 +34,7 @@ export async function uploadDialog(node: ZoweNode, datasetProvider: DatasetTree) datasetProvider.refresh(); } -export function getDatasetLabel(node: ZoweNode) { +export function getDatasetLabel(node: ZoweDatasetNode) { if (node.getParent() && node.getParent().contextValue === extension.FAVORITE_CONTEXT) { const profileEnd = "]: "; const profileIndex = node.label.indexOf(profileEnd); @@ -43,7 +43,7 @@ export function getDatasetLabel(node: ZoweNode) { return node.label; } -export async function uploadFile(node: ZoweNode, doc: vscode.TextDocument) { +export async function uploadFile(node: ZoweDatasetNode, doc: vscode.TextDocument) { try { const datasetName = getDatasetLabel(node); await zowe.Upload.fileToDataset(node.getSession(), doc.fileName, datasetName); diff --git a/src/uss/ussNodeActions.ts b/src/uss/ussNodeActions.ts index c8eed99db7..5ee29c1fd4 100644 --- a/src/uss/ussNodeActions.ts +++ b/src/uss/ussNodeActions.ts @@ -21,7 +21,8 @@ import * as extension from "../../src/extension"; import * as path from "path"; import { ISTHEIA } from "../extension"; import { Profiles } from "../Profiles"; -import { IZoweTreeNode, IZoweTree, IZoweUSSTreeNode } from "../api/ZoweTree"; +import { IZoweTree } from "../api/IZoweTree"; +import { IZoweTreeNode, IZoweUSSTreeNode } from "../api/IZoweTreeNode"; /** * Prompts the user for a path, and populates the [TreeView]{@link vscode.TreeView} based on the path * @@ -92,34 +93,6 @@ export async function createUSSNodeDialog(node: ZoweUSSNode, ussFileProvider: US } } -export async function deleteUSSNode(node: IZoweTreeNode, ussFileProvider: IZoweTree, filePath: string) { - // handle zosmf api issue with file paths - const nodePath = node.fullPath.startsWith("/") ? node.fullPath.substring(1) : node.fullPath; - const quickPickOptions: vscode.QuickPickOptions = { - placeHolder: localize("deleteUSSNode.quickPickOption", "Are you sure you want to delete ") + node.label, - ignoreFocusOut: true, - canPickMany: false - }; - if (await vscode.window.showQuickPick([localize("deleteUSSNode.showQuickPick.yes","Yes"), - localize("deleteUSSNode.showQuickPick.no", "No")], - quickPickOptions) !== localize("deleteUSSNode.showQuickPick.yes","Yes")) - { - return; - } - try { - const isRecursive = node.contextValue === extension.USS_DIR_CONTEXT ? true : false; - await zowe.Delete.ussFile(node.getSession(), nodePath, isRecursive); - node.getParent().dirty = true; - deleteFromDisk(node, filePath); - } catch (err) { - vscode.window.showErrorMessage(localize("deleteUSSNode.error.node", "Unable to delete node: ") + err.message); - throw (err); - } - - // Remove node from the USS Favorites tree - ussFileProvider.removeFavorite(node); - ussFileProvider.refresh(); -} /** * Refreshes treeView diff --git a/src/utils.ts b/src/utils.ts index aafb9d24e1..b76932a535 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -13,7 +13,7 @@ import * as path from "path"; import { TreeItem, QuickPickItem, QuickPick } from "vscode"; import * as extension from "../src/extension"; import * as nls from "vscode-nls"; -import { IZoweTreeNode } from "./api/ZoweTree"; +import { IZoweTreeNode } from "./api/IZoweTreeNode"; const localize = nls.config({ messageFormat: nls.MessageFormat.file })(); /* diff --git a/stringUpdateScript.js b/stringUpdateScript.js index bdeec70c80..7b384144eb 100644 --- a/stringUpdateScript.js +++ b/stringUpdateScript.js @@ -30,7 +30,7 @@ var parsedUtils = JSON.parse(fs.readFileSync('./out/src/utils.nls.metadata.json' var keysPairsUtils = {}; var parsedZosJobsProvider = JSON.parse(fs.readFileSync('./out/src/ZosJobsProvider.nls.metadata.json').toString()); var keysPairsZosJobsProvider = {}; -var parsedZoweNode = JSON.parse(fs.readFileSync('./out/src/ZoweNode.nls.metadata.json').toString()); +var parsedZoweNode = JSON.parse(fs.readFileSync('./out/src/ZoweDatasetNode.nls.metadata.json').toString()); var keysPairsZoweNode = {}; var parsedZoweUSSNode = JSON.parse(fs.readFileSync('./out/src/ZoweUSSNode.nls.metadata.json').toString()); var keysPairsZoweUSSNode = {}; @@ -57,6 +57,6 @@ fs.writeFileSync('./i18n/sample/src/Profiles.i18n.json', JSON.stringify(keysPair fs.writeFileSync('./i18n/sample/src/USSTree.i18n.json', JSON.stringify(keysPairsUSSTree, null, 4)); fs.writeFileSync('./i18n/sample/src/utils.i18n.json', JSON.stringify(keysPairsUtils, null, 4)); fs.writeFileSync('./i18n/sample/src/ZosJobsProvider.i18n.json', JSON.stringify(keysPairsZosJobsProvider, null, 4)); -fs.writeFileSync('./i18n/sample/src/ZoweNode.i18n.json', JSON.stringify(keysPairsZoweNode, null, 4)); +fs.writeFileSync('./i18n/sample/src/ZoweDatasetNode.i18n.json', JSON.stringify(keysPairsZoweNode, null, 4)); fs.writeFileSync('./i18n/sample/src/ZoweUSSNode.i18n.json', JSON.stringify(keysPairsZoweUSSNode, null, 4)); fs.writeFileSync('./i18n/sample/package.i18n.json', JSON.stringify(keysPairsPackage, null, 4)); \ No newline at end of file From 04bf0cb728ef2eb94b9c82f7419176046bde8bc0 Mon Sep 17 00:00:00 2001 From: Colin Stone <30794003+Colin-Stone@users.noreply.github.com> Date: Tue, 21 Jan 2020 09:49:49 +0000 Subject: [PATCH 06/19] spacing tweak Signed-off-by: Colin Stone <30794003+Colin-Stone@users.noreply.github.com> --- i18n/sample/src/uss/ussNodeActions.i18n.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/i18n/sample/src/uss/ussNodeActions.i18n.json b/i18n/sample/src/uss/ussNodeActions.i18n.json index 3c4541d98e..75394b3c5d 100644 --- a/i18n/sample/src/uss/ussNodeActions.i18n.json +++ b/i18n/sample/src/uss/ussNodeActions.i18n.json @@ -1,6 +1,6 @@ { "createUSSNode.name": "Name of file or directory", "createUSSNode.error.create": "Unable to create node: ", - "renameUSSNode.error": "Unable to rename node: ", + "renameUSSNode.error": "Unable to rename node: ", "copyPath.infoMessage": "Copy Path is not yet supported in Theia." } \ No newline at end of file From 3bffebdd8007756075a3e5b5719ec9c3424c35f5 Mon Sep 17 00:00:00 2001 From: Colin Stone <30794003+Colin-Stone@users.noreply.github.com> Date: Wed, 22 Jan 2020 12:10:17 +0000 Subject: [PATCH 07/19] Realigned the USS files post merge Signed-off-by: Colin Stone <30794003+Colin-Stone@users.noreply.github.com> --- .../__unit__/uss/ussNodeActions.unit.test.ts | 10 ++--- i18n/sample/src/ZoweUSSNode.i18n.json | 6 ++- src/ZoweUSSNode.ts | 33 +++++++++++++++ src/uss/ussNodeActions.ts | 42 ------------------- 4 files changed, 43 insertions(+), 48 deletions(-) diff --git a/__tests__/__unit__/uss/ussNodeActions.unit.test.ts b/__tests__/__unit__/uss/ussNodeActions.unit.test.ts index 9b93efaa84..03f6729d7b 100644 --- a/__tests__/__unit__/uss/ussNodeActions.unit.test.ts +++ b/__tests__/__unit__/uss/ussNodeActions.unit.test.ts @@ -286,21 +286,21 @@ describe("ussNodeActions", () => { expect(testUSSTree.refresh).not.toHaveBeenCalled(); }); }); - + describe("deleteUSSNode", () => { it("should delete node if user verified", async () => { showQuickPick.mockResolvedValueOnce("Yes"); - await ussNodeActions.deleteUSSNode(ussNode, testUSSTree, ""); + await ussNode.deleteUSSNode(testUSSTree, ""); expect(testUSSTree.refresh).toHaveBeenCalled(); }); it("should not delete node if user did not verify", async () => { showQuickPick.mockResolvedValueOnce("No"); - await ussNodeActions.deleteUSSNode(ussNode, testUSSTree, ""); + await ussNode.deleteUSSNode(testUSSTree, ""); expect(testUSSTree.refresh).not.toHaveBeenCalled(); }); it("should not delete node if user cancelled", async () => { showQuickPick.mockResolvedValueOnce(undefined); - await ussNodeActions.deleteUSSNode(ussNode, testUSSTree, ""); + await ussNode.deleteUSSNode(testUSSTree, ""); expect(testUSSTree.refresh).not.toHaveBeenCalled(); }); it("should not delete node if an error thrown", async () => { @@ -310,7 +310,7 @@ describe("ussNodeActions", () => { throw (Error("testError")); }); try { - await ussNodeActions.deleteUSSNode(ussNode, testUSSTree, ""); + await ussNode.deleteUSSNode(testUSSTree, ""); // tslint:disable-next-line:no-empty } catch (err) { } diff --git a/i18n/sample/src/ZoweUSSNode.i18n.json b/i18n/sample/src/ZoweUSSNode.i18n.json index 7f071d8031..af1ae6d4bf 100644 --- a/i18n/sample/src/ZoweUSSNode.i18n.json +++ b/i18n/sample/src/ZoweUSSNode.i18n.json @@ -2,5 +2,9 @@ "getChildren.error.invalidNode": "Invalid node", "getChildren.error.response": "Retrieving response from ", "getChildren.responses.error.response": "The response from Zowe CLI was not successful", - "getChildren.responses.open": "Open" + "getChildren.responses.open": "Open", + "deleteUSSNode.quickPickOption": "Are you sure you want to delete ", + "deleteUSSNode.showQuickPick.yes": "Yes", + "deleteUSSNode.showQuickPick.no": "No", + "deleteUSSNode.error.node": "Unable to delete node: " } \ No newline at end of file diff --git a/src/ZoweUSSNode.ts b/src/ZoweUSSNode.ts index 39f93db701..c8bb84ff7c 100644 --- a/src/ZoweUSSNode.ts +++ b/src/ZoweUSSNode.ts @@ -17,7 +17,9 @@ import { IZoweUSSTreeNode } from "./api/IZoweTreeNode"; const localize = nls.config({ messageFormat: nls.MessageFormat.file })(); import * as extension from "../src/extension"; import * as utils from "./utils"; +import * as fs from "fs"; import { ZoweTreeNode } from "./abstract/ZoweTreeNode"; +import { IZoweTree } from "./api/IZoweTree"; /** * A type of TreeItem used to represent sessions and USS directories and files @@ -219,7 +221,38 @@ export class ZoweUSSNode extends ZoweTreeNode implements IZoweUSSTreeNode { this.label = this.label.replace(oldReference, this.shortLabel); this.tooltip = this.tooltip.replace(oldReference, this.shortLabel); } + public async deleteUSSNode(ussFileProvider: IZoweTree, filePath: string) { + // handle zosmf api issue with file paths + const nodePath = this.fullPath.startsWith("/") ? this.fullPath.substring(1) : this.fullPath; + const quickPickOptions: vscode.QuickPickOptions = { + placeHolder: localize("deleteUSSNode.quickPickOption", "Are you sure you want to delete ") + this.label, + ignoreFocusOut: true, + canPickMany: false + }; + if (await vscode.window.showQuickPick([localize("deleteUSSNode.showQuickPick.yes", "Yes"), + localize("deleteUSSNode.showQuickPick.no", "No")], + quickPickOptions) !== localize("deleteUSSNode.showQuickPick.yes", "Yes")) { + return; + } + try { + const isRecursive = this.contextValue === extension.USS_DIR_CONTEXT ? true : false; + await zowe.Delete.ussFile(this.getSession(), nodePath, isRecursive); + this.getParent().dirty = true; + try { + if (fs.existsSync(filePath)) { + fs.unlinkSync(filePath); + } + // tslint:disable-next-line: no-empty + } catch (err) { } + } catch (err) { + vscode.window.showErrorMessage(localize("deleteUSSNode.error.node", "Unable to delete node: ") + err.message); + throw (err); + } + // Remove node from the USS Favorites tree + ussFileProvider.removeFavorite(this); + ussFileProvider.refresh(); + } /** * Returns the [etag] for this node * diff --git a/src/uss/ussNodeActions.ts b/src/uss/ussNodeActions.ts index 6fbe67fa1b..ce6057f9cf 100644 --- a/src/uss/ussNodeActions.ts +++ b/src/uss/ussNodeActions.ts @@ -97,34 +97,6 @@ export async function createUSSNodeDialog(node: ZoweUSSNode, ussFileProvider: US } } -export async function deleteUSSNode(node: ZoweUSSNode, ussFileProvider: USSTree, filePath: string) { - // handle zosmf api issue with file paths - const nodePath = node.fullPath.startsWith("/") ? node.fullPath.substring(1) : node.fullPath; - const quickPickOptions: vscode.QuickPickOptions = { - placeHolder: localize("deleteUSSNode.quickPickOption", "Are you sure you want to delete ") + node.label, - ignoreFocusOut: true, - canPickMany: false - }; - if (await vscode.window.showQuickPick([localize("deleteUSSNode.showQuickPick.yes", "Yes"), - localize("deleteUSSNode.showQuickPick.no", "No")], - quickPickOptions) !== localize("deleteUSSNode.showQuickPick.yes", "Yes")) { - return; - } - try { - const isRecursive = node.contextValue === extension.USS_DIR_CONTEXT ? true : false; - await zowe.Delete.ussFile(node.getSession(), nodePath, isRecursive); - node.mParent.dirty = true; - deleteFromDisk(node, filePath); - } catch (err) { - vscode.window.showErrorMessage(localize("deleteUSSNode.error.node", "Unable to delete node: ") + err.message); - throw (err); - } - - // Remove node from the USS Favorites tree - ussFileProvider.removeUSSFavorite(node); - ussFileProvider.refresh(); -} - /** * Refreshes treeView * @@ -177,20 +149,6 @@ export async function renameUSSNode(originalNode: IZoweUSSTreeNode, ussFileProvi } -/** - * Marks file as deleted from disk - * - * @param {ZoweUSSNode} node - */ -export async function deleteFromDisk(node: IZoweTreeNode, filePath: string) { - try { - if (fs.existsSync(filePath)) { - fs.unlinkSync(filePath); - } - // tslint:disable-next-line: no-empty - } catch (err) { } -} - export async function uploadDialog(node: ZoweUSSNode, ussFileProvider: USSTree) { const fileOpenOptions = { canSelectFiles: true, From 7aedd15427eb176a859ff6133f09477617544535 Mon Sep 17 00:00:00 2001 From: Colin Stone <30794003+Colin-Stone@users.noreply.github.com> Date: Mon, 27 Jan 2020 08:39:51 +0000 Subject: [PATCH 08/19] cleanup post auto merge Signed-off-by: Colin Stone <30794003+Colin-Stone@users.noreply.github.com> --- src/extension.ts | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/extension.ts b/src/extension.ts index 463b7c14f9..75636eefcf 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -17,9 +17,8 @@ import * as path from "path"; import * as vscode from "vscode"; import { IZoweTreeNode, IZoweJobTreeNode, IZoweUSSTreeNode, IZoweDatasetTreeNode } from "./api/IZoweTreeNode"; import { ZoweDatasetNode } from "./ZoweDatasetNode"; -import { IZoweTree, IZoweTreeNode } from "./api/IZoweTree"; -import { ZoweNode } from "./ZoweNode"; -import { Logger, TextUtils, IProfileLoaded, ImperativeConfig, ISession, IProfile, Session, CredentialManagerFactory, ImperativeError, DefaultCredentialManager } from "@brightside/imperative"; +import { IZoweTree } from "./api/IZoweTree"; +import { Logger, TextUtils, IProfileLoaded, ImperativeConfig, Session, CredentialManagerFactory, ImperativeError, DefaultCredentialManager } from "@brightside/imperative"; import { DatasetTree, createDatasetTree } from "./DatasetTree"; import { ZosJobsProvider, createJobsTree } from "./ZosJobsProvider"; import { Job } from "./ZoweJobNode"; From 938bdfe2c835b4c10742c95bd9497d297880b735 Mon Sep 17 00:00:00 2001 From: Colin Stone <30794003+Colin-Stone@users.noreply.github.com> Date: Mon, 27 Jan 2020 09:23:36 +0000 Subject: [PATCH 09/19] Added more tests, removed redundant code Signed-off-by: Colin Stone <30794003+Colin-Stone@users.noreply.github.com> --- __tests__/__unit__/ZoweJobNode.unit.test.ts | 38 +++++++++++++++++++++ src/ZoweJobNode.ts | 10 ------ 2 files changed, 38 insertions(+), 10 deletions(-) diff --git a/__tests__/__unit__/ZoweJobNode.unit.test.ts b/__tests__/__unit__/ZoweJobNode.unit.test.ts index 6ce92c1f50..cbc75c4454 100644 --- a/__tests__/__unit__/ZoweJobNode.unit.test.ts +++ b/__tests__/__unit__/ZoweJobNode.unit.test.ts @@ -418,6 +418,44 @@ describe("Zos Jobs Unit Tests", () => { expect(newjobNode.searchId).toEqual(""); }); + /************************************************************************************************************* + * Jobs Filter prompts + *************************************************************************************************************/ + it("Testing that prompt credentials is called when searchPrompt is triggered but undefined returned", async () => { + createBasicZosmfSession.mockReturnValue(sessionwocred); + const newjobNode = new Job("jobtest", vscode.TreeItemCollapsibleState.Expanded, jobNode, sessionwocred, iJob); + newjobNode.contextValue = extension.JOBS_SESSION_CONTEXT; + const testJobsProvider = await createJobsTree(Logger.getAppLogger()); + const qpItem: vscode.QuickPickItem = testJobsProvider.createOwner; + const resolveQuickPickHelper = jest.spyOn(utils, "resolveQuickPickHelper").mockImplementation( + () => Promise.resolve(qpItem) + ); + testJobsProvider.initializeJobsTree(Logger.getAppLogger()); + createQuickPick.mockReturnValue({ + placeholder: "Select a filter", + activeItems: [qpItem], + ignoreFocusOut: true, + items: [testJobsProvider.createOwner, testJobsProvider.createId], + value: "", + show: jest.fn(()=>{ + return {}; + }), + hide: jest.fn(()=>{ + return {}; + }), + onDidAccept: jest.fn(()=>{ + return {}; + }) + }); + showInformationMessage.mockReset(); + showInputBox.mockReturnValueOnce("MYHLQ"); + showInputBox.mockReturnValueOnce(""); + showInputBox.mockReturnValueOnce(undefined); + await testJobsProvider.searchPrompt(newjobNode); + expect(showInformationMessage.mock.calls.length).toBe(1); + expect(showInformationMessage.mock.calls[0][0]).toBe("Search Cancelled"); + }); + it("Testing that prompt credentials is called when searchPrompt is triggered for fav", async () => { createBasicZosmfSession.mockReturnValue(sessionwocred); const newjobNode = new Job("[fake]: Owner:fakeUser Prefix:*", vscode.TreeItemCollapsibleState.Expanded, jobNode, sessionwocred, iJob); diff --git a/src/ZoweJobNode.ts b/src/ZoweJobNode.ts index 6f0983b309..a66a89ea96 100644 --- a/src/ZoweJobNode.ts +++ b/src/ZoweJobNode.ts @@ -126,16 +126,6 @@ export class Job extends ZoweTreeNode implements IZoweJobTreeNode { return this.children; } - public reset() { - utils.labelHack(this); - this.children = []; - this.dirty = true; - } - - // tslint:disable-next-line: no-empty - public rename(newNamePath: string) { - } - public getSessionNode(): IZoweJobTreeNode { return this.getParent() ? this.getParent().getSessionNode() : this; } From de6fd865b4f0c48b78afb2201410bdacd8f7e80e Mon Sep 17 00:00:00 2001 From: Colin Stone <30794003+Colin-Stone@users.noreply.github.com> Date: Mon, 27 Jan 2020 14:18:00 +0000 Subject: [PATCH 10/19] Increase coverage Signed-off-by: Colin Stone <30794003+Colin-Stone@users.noreply.github.com> --- __mocks__/@brightside/imperative.ts | 8 ++++---- __tests__/__unit__/extension.unit.test.ts | 4 +--- src/extension.ts | 4 ++-- 3 files changed, 7 insertions(+), 9 deletions(-) diff --git a/__mocks__/@brightside/imperative.ts b/__mocks__/@brightside/imperative.ts index 38277ec8e8..bbf4108915 100644 --- a/__mocks__/@brightside/imperative.ts +++ b/__mocks__/@brightside/imperative.ts @@ -73,14 +73,14 @@ export class CliProfileManager { // tslint:disable-next-line:max-classes-per-file export class ImperativeConfig { public static instance = { - cliHome: "/TestLocation/.zowe", + cliHome: "./__tests__/.zowe", loadedConfig: {} - } + }; public loadedConfig = { - defaultHome: "/TestLocation/.zowe", + defaultHome: "./__tests__/.zowe", envVariablePrefix: "ZOWE" }; - public cliHome: "/TestLocation/.zowe"; + public cliHome: "./__tests__/.zowe"; } diff --git a/__tests__/__unit__/extension.unit.test.ts b/__tests__/__unit__/extension.unit.test.ts index 2954fd4e06..770ae65af1 100644 --- a/__tests__/__unit__/extension.unit.test.ts +++ b/__tests__/__unit__/extension.unit.test.ts @@ -372,9 +372,6 @@ describe("Extension Unit Tests", () => { Object.defineProperty(Copy, "dataSet", { value: copyDataSet }); Object.defineProperty(vscode.env, "clipboard", { value: clipboard }); Object.defineProperty(Rename, "dataSetMember", { value: renameDataSetMember }); - Object.defineProperty(brtimperative, "ImperativeConfig", { value: ImperativeConfig }); - Object.defineProperty(ImperativeConfig, "instance", { value: icInstance }); - Object.defineProperty(icInstance, "cliHome", { value: cliHome }); beforeEach(() => { mockLoadNamedProfile.mockReturnValue({profile: {name:"aProfile", type:"zosmf"}}); @@ -504,6 +501,7 @@ describe("Extension Unit Tests", () => { extensionPath: path.join(__dirname, "..") } as vscode.ExtensionContext)); const mock = new extensionMock(); + readFileSync.mockReturnValueOnce('{ "overrides": { "CredentialManager": "Managed by ANO" }}'); await extension.activate(mock); diff --git a/src/extension.ts b/src/extension.ts index 75636eefcf..d8752a43cc 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -356,7 +356,8 @@ export function getSecurityModules(moduleName): NodeRequire | undefined { let imperativeIsSsecure: boolean = false; try { const fileName = path.join(getZoweDir(), "settings", "imperative.json"); - const settings = JSON.parse(fs.readFileSync(fileName).toString()); + const p = fs.readFileSync(fileName); + const settings = JSON.parse(p.toString()); const value1 = settings.overrides.CredentialManager; const value2 = settings.overrides["credential-manager"]; imperativeIsSsecure = ((typeof value1 === "string") && (value1.length > 0)) || @@ -394,7 +395,6 @@ export function getZoweDir(): string { defaultHome: path.join(os.homedir(), ".zowe"), envVariablePrefix: "ZOWE" }; - const ti = ImperativeConfig.instance; return ImperativeConfig.instance.cliHome; } From 48a9152539ac17a3e18a6e9e77788ce6ac12769a Mon Sep 17 00:00:00 2001 From: Colin Stone <30794003+Colin-Stone@users.noreply.github.com> Date: Mon, 27 Jan 2020 15:27:59 +0000 Subject: [PATCH 11/19] slight more coverage Signed-off-by: Colin Stone <30794003+Colin-Stone@users.noreply.github.com> --- __tests__/__unit__/extension.unit.test.ts | 36 +++++++++++++++++++++++ src/extension.ts | 3 +- 2 files changed, 37 insertions(+), 2 deletions(-) diff --git a/__tests__/__unit__/extension.unit.test.ts b/__tests__/__unit__/extension.unit.test.ts index 770ae65af1..7f858c4bd5 100644 --- a/__tests__/__unit__/extension.unit.test.ts +++ b/__tests__/__unit__/extension.unit.test.ts @@ -3559,6 +3559,42 @@ describe("Extension Unit Tests", () => { expect(moveSync.mock.calls[0][1]).toBe(path.join(path.sep, "new", "test", "path", "temp")); }); + it("Tests that temp folder error thrown 1", () => { + mkdirSync.mockReset(); + moveSync.mockReset(); + existsSync.mockReset(); + showErrorMessage.mockReset(); + existsSync.mockReturnValueOnce(false); + + const originalPreferencePath = "/err/path"; + const updatedPreferencePath = "/err/test/path"; + mkdirSync.mockImplementationOnce(() => { + throw (Error("testAsError 1")); + }); + extension.moveTempFolder(originalPreferencePath, updatedPreferencePath); + expect(showErrorMessage.mock.calls.length).toBe(1); + expect(showErrorMessage.mock.calls[0][0]).toEqual("testAsError 1"); + }); + + it("Tests that temp folder error thrown 2", () => { + mkdirSync.mockReset(); + moveSync.mockReset(); + existsSync.mockReset(); + showErrorMessage.mockReset(); + existsSync.mockReturnValueOnce(true); + existsSync.mockReturnValueOnce(false); + existsSync.mockReturnValueOnce(true); + + const originalPreferencePath = "/err2/path"; + const updatedPreferencePath = "/err2/test/path"; + moveSync.mockImplementationOnce(() => { + throw (Error("testAsError 2")); + }); + extension.moveTempFolder(originalPreferencePath, updatedPreferencePath); + expect(showErrorMessage.mock.calls.length).toBe(1); + expect(showErrorMessage.mock.calls[0][0]).toEqual("testAsError 2"); + }); + it("Tests that temp folder does not update on duplicate preference", () => { mkdirSync.mockReset(); moveSync.mockReset(); diff --git a/src/extension.ts b/src/extension.ts index d8752a43cc..423ed517cd 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -356,8 +356,7 @@ export function getSecurityModules(moduleName): NodeRequire | undefined { let imperativeIsSsecure: boolean = false; try { const fileName = path.join(getZoweDir(), "settings", "imperative.json"); - const p = fs.readFileSync(fileName); - const settings = JSON.parse(p.toString()); + const settings = JSON.parse(fs.readFileSync(fileName).toString()); const value1 = settings.overrides.CredentialManager; const value2 = settings.overrides["credential-manager"]; imperativeIsSsecure = ((typeof value1 === "string") && (value1.length > 0)) || From 3659808d70830126dce4fb545057b95710f07314 Mon Sep 17 00:00:00 2001 From: Colin Stone <30794003+Colin-Stone@users.noreply.github.com> Date: Wed, 29 Jan 2020 11:09:11 +0000 Subject: [PATCH 12/19] Manual merge master into branch Signed-off-by: Colin Stone <30794003+Colin-Stone@users.noreply.github.com> --- __tests__/__unit__/DatasetTree.unit.test.ts | 30 +++-- __tests__/__unit__/USSTree.unit.test.ts | 7 ++ __tests__/__unit__/ZoweJobNode.unit.test.ts | 111 +++++++----------- __tests__/__unit__/ZoweNode.unit.test.ts | 18 +++ __tests__/__unit__/ZoweUSSNode.unit.test.ts | 17 +++ .../command/mvsCommandHandler.unit.test.ts | 21 ++-- __tests__/__unit__/extension.unit.test.ts | 72 +++++------- i18n/sample/src/ZoweNode.i18n.json | 1 + i18n/sample/src/ZoweUSSNode.i18n.json | 1 + src/ZoweDatasetNode.ts | 42 ++++--- src/ZoweJobNode.ts | 34 ++++-- src/ZoweUSSNode.ts | 7 +- src/extension.ts | 12 +- 13 files changed, 202 insertions(+), 171 deletions(-) diff --git a/__tests__/__unit__/DatasetTree.unit.test.ts b/__tests__/__unit__/DatasetTree.unit.test.ts index 95062d1b2e..8e18276501 100644 --- a/__tests__/__unit__/DatasetTree.unit.test.ts +++ b/__tests__/__unit__/DatasetTree.unit.test.ts @@ -37,18 +37,6 @@ describe("DatasetTree Unit Tests", () => { type: "basic", }); - const ProgressLocation = jest.fn().mockImplementation(() => { - return { - Notification: 15 - }; - }); - const withProgress = jest.fn().mockImplementation(() => { - return { - location: 15, - title: "Saving file..." - }; - }); - // Filter prompt const showInformationMessage = jest.fn(); const showInputBox = jest.fn(); @@ -66,6 +54,18 @@ describe("DatasetTree Unit Tests", () => { }; }) }); + const ProgressLocation = jest.fn().mockImplementation(() => { + return { + Notification: 15 + }; + }); + + const withProgress = jest.fn().mockImplementation((progLocation, callback) => { + return callback(); + }); + + Object.defineProperty(vscode, "ProgressLocation", {value: ProgressLocation}); + Object.defineProperty(vscode.window, "withProgress", {value: withProgress}); Object.defineProperty(vscode.window, "showInformationMessage", {value: showInformationMessage}); Object.defineProperty(vscode.window, "showInformationMessage", {value: showInformationMessage}); Object.defineProperty(vscode.window, "showQuickPick", {value: showQuickPick}); @@ -115,6 +115,12 @@ describe("DatasetTree Unit Tests", () => { testTree.mSessionNodes[1].pattern = "test"; testTree.mSessionNodes[1].iconPath = utils.applyIcons(testTree.mSessionNodes[1]); + beforeEach(() => { + withProgress.mockImplementation((progLocation, callback) => { + return callback(); + }); + }); + afterAll(() => { jest.restoreAllMocks(); }); diff --git a/__tests__/__unit__/USSTree.unit.test.ts b/__tests__/__unit__/USSTree.unit.test.ts index 8461659179..754c15a7d6 100644 --- a/__tests__/__unit__/USSTree.unit.test.ts +++ b/__tests__/__unit__/USSTree.unit.test.ts @@ -97,6 +97,13 @@ describe("Unit Tests (Jest)", () => { }; }) }); + + beforeEach(() => { + withProgress.mockImplementation((progLocation, callback) => { + return callback(); + }); + }); + afterEach(async () => { getConfiguration.mockClear(); }); diff --git a/__tests__/__unit__/ZoweJobNode.unit.test.ts b/__tests__/__unit__/ZoweJobNode.unit.test.ts index cbc75c4454..be68a9cde6 100644 --- a/__tests__/__unit__/ZoweJobNode.unit.test.ts +++ b/__tests__/__unit__/ZoweJobNode.unit.test.ts @@ -9,7 +9,6 @@ * * */ -jest.mock("vscode"); jest.mock("Session"); jest.mock("@brightside/core"); jest.mock("@brightside/imperative"); @@ -26,12 +25,10 @@ describe("Zos Jobs Unit Tests", () => { const GetJobs = jest.fn(); const getConfiguration = jest.fn(); - const target = jest.fn(); const showErrorMessage = jest.fn(); Object.defineProperty(vscode.workspace, "getConfiguration", { value: getConfiguration }); Object.defineProperty(vscode.window, "showErrorMessage", {value: showErrorMessage}); getConfiguration.mockReturnValue({ - // persistence: true, get: (setting: string) => [ "[test]: Owner:stonecc Prefix:*{server}", "[test]: USER1(JOB30148){job}", @@ -48,7 +45,6 @@ describe("Zos Jobs Unit Tests", () => { WorkspaceFolder: 3 }; }); - Object.defineProperty(vscode, "ConfigurationTarget", {value: enums}); beforeAll(() => { Object.defineProperty(brightside, "GetJobs", { value: GetJobs }); @@ -58,7 +54,7 @@ describe("Zos Jobs Unit Tests", () => { jest.resetAllMocks(); }); - describe("ZosJobsProvider Unit Test", () => { + describe("ZosJobsProvider/ZoweJobNode Unit Test", () => { const log = new Logger(undefined); const ZosmfSession = jest.fn(); const createBasicZosmfSession = jest.fn(); @@ -66,6 +62,19 @@ describe("Zos Jobs Unit Tests", () => { const getJobsByOwnerAndPrefix = jest.fn(); const getJob = jest.fn(); + const ProgressLocation = jest.fn().mockImplementation(() => { + return { + Notification: 15 + }; + }); + + const withProgress = jest.fn().mockImplementation((progLocation, callback) => { + return callback(); + }); + + Object.defineProperty(vscode, "ProgressLocation", {value: ProgressLocation}); + Object.defineProperty(vscode.window, "withProgress", {value: withProgress}); + Object.defineProperty(vscode, "ConfigurationTarget", {value: enums}); Object.defineProperty(brightside, "ZosmfSession", { value: ZosmfSession }); Object.defineProperty(ZosmfSession, "createBasicZosmfSession", { value: createBasicZosmfSession }); Object.defineProperty(GetJobs, "getJobsByOwnerAndPrefix", { value: getJobsByOwnerAndPrefix }); @@ -165,7 +174,6 @@ describe("Zos Jobs Unit Tests", () => { const DeleteJobs = jest.fn(); const deleteJob = jest.fn(); Object.defineProperty(vscode.window, "showInformationMessage", {value: showInformationMessage}); - Object.defineProperty(vscode.window, "showInformationMessage", {value: showInformationMessage}); Object.defineProperty(vscode.window, "showQuickPick", {value: showQuickPick}); Object.defineProperty(vscode.window, "createQuickPick", {value: createQuickPick}); Object.defineProperty(vscode.window, "showInputBox", {value: showInputBox}); @@ -190,6 +198,9 @@ describe("Zos Jobs Unit Tests", () => { }; }) }); + withProgress.mockImplementation((progLocation, callback) => { + return callback(); + }); }); afterEach(() => { @@ -781,74 +792,34 @@ describe("Zos Jobs Unit Tests", () => { testTree.removeFavorite(testTree.mFavorites[0]); expect(testTree.mFavorites).toEqual([]); }); - }); - - describe("JobSpool Unit Test", () => { - const getSpoolFiles = jest.fn(); - - Object.defineProperty(brightside, "GetJobs", { value: GetJobs }); - Object.defineProperty(GetJobs, "getSpoolFiles", { value: getSpoolFiles }); - - const session = new Session({ - user: "fake", - password: "fake", - hostname: "fake", - protocol: "https", - type: "basic", - }); - - const iJob: brightside.IJob = { - "jobid": "JOB1234", - "jobname": "TESTJOB", - "files-url": "fake/files", - "job-correlator": "correlator", - "phase-name": "PHASE", - "reason-not-running": "", - "step-data": [{ - "proc-step-name": "", - "program-name": "", - "step-name": "", - "step-number": 1, - "active": "", - "smfid": "" - - }], - "class": "A", - "owner": "USER", - "phase": 0, - "retcode": "", - "status": "ACTIVE", - "subsystem": "SYS", - "type": "JOB", - "url": "fake/url" - }; - - const iJobFile: brightside.IJobFile = { - "byte-count": 128, - "job-correlator": "", - "record-count": 1, - "records-url": "fake/records", - "class": "A", - "ddname": "STDOUT", - "id": 100, - "jobid": "100", - "jobname": "TESTJOB", - "lrecl": 80, - "procstep": "", - "recfm": "FB", - "stepname": "STEP", - "subsystem": "" - }; - - const jobNode = new Job("jobtest", vscode.TreeItemCollapsibleState.Expanded, null, session, iJob); - jobNode.contextValue = "job"; it("Tests the children are the spool files", async () => { + const iJobFile: brightside.IJobFile = { + "byte-count": 128, + "job-correlator": "", + "record-count": 1, + "records-url": "fake/records", + "class": "A", + "ddname": "STDOUT", + "id": 101, + "jobid": "101", + "jobname": "TESTJOB", + "lrecl": 80, + "procstep": "", + "recfm": "FB", + "stepname": "STEP", + "subsystem": "" + }; + const jobNodeSpool = new Job("jobtest", vscode.TreeItemCollapsibleState.Expanded, null, session, iJob); + jobNodeSpool.contextValue = "job"; + const getSpoolFiles = jest.fn(); + Object.defineProperty(brightside, "GetJobs", { value: GetJobs }); + Object.defineProperty(GetJobs, "getSpoolFiles", { value: getSpoolFiles }); getSpoolFiles.mockReturnValue([iJobFile]); - jobNode.dirty = true; - const spoolFiles = await jobNode.getChildren(); + jobNodeSpool.dirty = true; + const spoolFiles = await jobNodeSpool.getChildren(); expect(spoolFiles.length).toBe(1); - expect(spoolFiles[0].label).toEqual("STEP:STDOUT(100)"); + expect(spoolFiles[0].label).toEqual("STEP:STDOUT(101)"); expect(spoolFiles[0].owner).toEqual("fake"); }); }); diff --git a/__tests__/__unit__/ZoweNode.unit.test.ts b/__tests__/__unit__/ZoweNode.unit.test.ts index 4e1c43b923..456cfd99cb 100644 --- a/__tests__/__unit__/ZoweNode.unit.test.ts +++ b/__tests__/__unit__/ZoweNode.unit.test.ts @@ -29,6 +29,24 @@ describe("Unit Tests (Jest)", () => { protocol: "https", type: "basic", }); + const ProgressLocation = jest.fn().mockImplementation(() => { + return { + Notification: 15 + }; + }); + + const withProgress = jest.fn().mockImplementation((progLocation, callback) => { + return callback(); + }); + + Object.defineProperty(vscode, "ProgressLocation", {value: ProgressLocation}); + Object.defineProperty(vscode.window, "withProgress", {value: withProgress}); + + beforeEach(() => { + withProgress.mockImplementation((progLocation, callback) => { + return callback(); + }); + }); afterEach(() => { jest.resetAllMocks(); diff --git a/__tests__/__unit__/ZoweUSSNode.unit.test.ts b/__tests__/__unit__/ZoweUSSNode.unit.test.ts index 6565704fc3..de85a5ab45 100644 --- a/__tests__/__unit__/ZoweUSSNode.unit.test.ts +++ b/__tests__/__unit__/ZoweUSSNode.unit.test.ts @@ -30,6 +30,23 @@ describe("Unit Tests (Jest)", () => { type: "basic", }); + const ProgressLocation = jest.fn().mockImplementation(() => { + return { + Notification: 15 + }; + }); + + const withProgress = jest.fn().mockImplementation((progLocation, callback) => { + return callback(); + }); + + Object.defineProperty(vscode, "ProgressLocation", {value: ProgressLocation}); + Object.defineProperty(vscode.window, "withProgress", {value: withProgress}); + beforeEach(() => { + withProgress.mockImplementation((progLocation, callback) => { + return callback(); + }); + }); afterEach(() => { jest.resetAllMocks(); }); diff --git a/__tests__/__unit__/command/mvsCommandHandler.unit.test.ts b/__tests__/__unit__/command/mvsCommandHandler.unit.test.ts index 8037f4ac0e..941a2adcb1 100644 --- a/__tests__/__unit__/command/mvsCommandHandler.unit.test.ts +++ b/__tests__/__unit__/command/mvsCommandHandler.unit.test.ts @@ -73,18 +73,13 @@ describe("mvsCommandActions unit testing", () => { }; }); - const submitResponse = { - success: true, - commandResponse: "d iplinfo.." - }; - const withProgress = jest.fn().mockImplementation((progLocation, callback) => { - callback(); - return submitResponse; + return { + success: true, + commandResponse: callback() + }; }); - issueSimple.mockReturnValueOnce({commandResponse: "fake response"}); - Object.defineProperty(vscode.window, "showErrorMessage", {value: showErrorMessage}); Object.defineProperty(vscode.window, "showInputBox", {value: showInputBox}); Object.defineProperty(vscode.window, "showInformationMessage", {value: showInformationMessage}); @@ -128,7 +123,7 @@ describe("mvsCommandActions unit testing", () => { jest.spyOn(utils, "resolveQuickPickHelper").mockImplementation( () => Promise.resolve(qpItem) ); - issueSimple.mockReturnValueOnce({commandResponse: "fake response"}); + issueSimple.mockReturnValueOnce("iplinfo1"); await mvsActions.issueMvsCommand(); @@ -142,7 +137,7 @@ describe("mvsCommandActions unit testing", () => { expect(showInputBox.mock.calls.length).toBe(1); expect(appendLine.mock.calls.length).toBe(2); expect(appendLine.mock.calls[0][0]).toBe("> d iplinfo1"); - expect(appendLine.mock.calls[1][0]).toBe(submitResponse.commandResponse); + expect(appendLine.mock.calls[1][0]).toBe("iplinfo1"); expect(showInformationMessage.mock.calls.length).toBe(0); }); @@ -161,7 +156,7 @@ describe("mvsCommandActions unit testing", () => { jest.spyOn(utils, "resolveQuickPickHelper").mockImplementation( () => Promise.resolve(qpItem2) ); - issueSimple.mockReturnValueOnce({commandResponse: "fake response"}); + issueSimple.mockReturnValueOnce("iplinfo0"); await mvsActions.issueMvsCommand(); @@ -175,7 +170,7 @@ describe("mvsCommandActions unit testing", () => { expect(showInputBox.mock.calls.length).toBe(0); expect(appendLine.mock.calls.length).toBe(2); expect(appendLine.mock.calls[0][0]).toBe("> d iplinfo0"); - expect(appendLine.mock.calls[1][0]).toBe(submitResponse.commandResponse); + expect(appendLine.mock.calls[1][0]).toBe("iplinfo0"); expect(showInformationMessage.mock.calls.length).toBe(0); }); diff --git a/__tests__/__unit__/extension.unit.test.ts b/__tests__/__unit__/extension.unit.test.ts index 7f858c4bd5..535a5f3a9a 100644 --- a/__tests__/__unit__/extension.unit.test.ts +++ b/__tests__/__unit__/extension.unit.test.ts @@ -200,6 +200,13 @@ describe("Extension Unit Tests", () => { const findNonFavoritedNode = jest.fn(); const concatChildNodes = jest.fn(); let mockClipboardData: string; + const fileResponse: brightside.IZosFilesResponse = { + success: true, + commandResponse: null, + apiResponse: { + etag: "123" + } + }; const cliHome = jest.fn().mockReturnValue(path.join(os.homedir(), ".zowe")); const icInstance = jest.fn(); const ImperativeConfig =jest.fn(); @@ -386,6 +393,9 @@ describe("Extension Unit Tests", () => { }; }) }); + withProgress.mockImplementation((progLocation, callback) => { + return callback(); + }); }); afterEach(() => { @@ -754,14 +764,7 @@ describe("Extension Unit Tests", () => { dataSet.mockReset(); showTextDocument.mockReset(); - const response: brightside.IZosFilesResponse = { - success: true, - commandResponse: null, - apiResponse: { - etag: "123" - } - }; - dataSet.mockReturnValueOnce(response); + dataSet.mockReturnValueOnce(fileResponse); await extension.refreshPS(node); expect(dataSet.mock.calls.length).toBe(1); @@ -810,7 +813,7 @@ describe("Extension Unit Tests", () => { openTextDocument.mockResolvedValueOnce({isDirty: true}); dataSet.mockReset(); showTextDocument.mockReset(); - dataSet.mockReturnValueOnce(response); + dataSet.mockReturnValueOnce(fileResponse); node.contextValue = extension.DS_PDS_CONTEXT + extension.FAV_SUFFIX; await extension.refreshPS(node); @@ -819,7 +822,7 @@ describe("Extension Unit Tests", () => { dataSet.mockReset(); openTextDocument.mockReset(); - dataSet.mockReturnValueOnce(response); + dataSet.mockReturnValueOnce(fileResponse); parent.contextValue = extension.DS_PDS_CONTEXT + extension.FAV_SUFFIX; await extension.refreshPS(child); @@ -828,7 +831,7 @@ describe("Extension Unit Tests", () => { dataSet.mockReset(); openTextDocument.mockReset(); - dataSet.mockReturnValueOnce(response); + dataSet.mockReturnValueOnce(fileResponse); parent.contextValue = extension.FAVORITE_CONTEXT; await extension.refreshPS(child); @@ -1845,14 +1848,8 @@ describe("Extension Unit Tests", () => { const child = new ZoweDatasetNode("child", vscode.TreeItemCollapsibleState.None, parent, null); existsSync.mockReturnValue(null); - const response: brightside.IZosFilesResponse = { - success: true, - commandResponse: null, - apiResponse: { - etag: "123" - } - }; - withProgress.mockReturnValue(response); + + withProgress.mockReturnValue(fileResponse); openTextDocument.mockResolvedValueOnce("test doc"); await extension.openPS(node, true); @@ -2079,14 +2076,8 @@ describe("Extension Unit Tests", () => { ussFile.mockReset(); showTextDocument.mockReset(); executeCommand.mockReset(); - const response: brightside.IZosFilesResponse = { - success: true, - commandResponse: null, - apiResponse: { - etag: "132" - } - }; - ussFile.mockReturnValueOnce(response); + + ussFile.mockReturnValueOnce(fileResponse); await extension.refreshUSS(node); expect(ussFile.mock.calls.length).toBe(1); @@ -2445,14 +2436,8 @@ describe("Extension Unit Tests", () => { existsSync.mockReturnValue(null); openTextDocument.mockResolvedValueOnce("test.doc"); - const response: brightside.IZosFilesResponse = { - success: true, - commandResponse: null, - apiResponse: { - etag: "123" - } - }; - withProgress.mockReturnValue(response); + ussFile.mockReturnValueOnce(fileResponse); + withProgress.mockReturnValue(fileResponse); await extension.openUSS(node, false, true, testUSSTree); @@ -2532,6 +2517,8 @@ describe("Extension Unit Tests", () => { openTextDocument.mockReset(); showTextDocument.mockReset(); + ussFile.mockReturnValueOnce(fileResponse); + openTextDocument.mockResolvedValueOnce("test.doc"); // Set up mock favorite session @@ -2551,7 +2538,7 @@ describe("Extension Unit Tests", () => { await extension.openUSS(favoriteFile, false, true, testUSSTree); expect(showTextDocument.mock.calls.length).toBe(1); showTextDocument.mockReset(); - + ussFile.mockReturnValueOnce(fileResponse); await extension.openUSS(child, false, true, testUSSTree); expect(showTextDocument.mock.calls.length).toBe(1); showTextDocument.mockReset(); @@ -2573,14 +2560,7 @@ describe("Extension Unit Tests", () => { existsSync.mockReturnValue(null); openTextDocument.mockResolvedValueOnce("test.doc"); - const response: brightside.IZosFilesResponse = { - success: true, - commandResponse: null, - apiResponse: { - etag: "123" - } - }; - withProgress.mockReturnValue(response); + withProgress.mockReturnValue(fileResponse); await extension.openUSS(node, false, true, testUSSTree); @@ -2613,6 +2593,8 @@ describe("Extension Unit Tests", () => { protocol: "https", type: "basic", }); + + ussFile.mockReturnValueOnce(fileResponse); const dsNode = new ZoweUSSNode("testSess", vscode.TreeItemCollapsibleState.Expanded, ussNode, sessionwocred, null); dsNode.contextValue = extension.USS_SESSION_CONTEXT; Object.defineProperty(profileLoader.Profiles, "getInstance", { @@ -2665,6 +2647,8 @@ describe("Extension Unit Tests", () => { showInputBox.mockReturnValueOnce("fake"); showInputBox.mockReturnValueOnce("fake"); + ussFile.mockReturnValueOnce(fileResponse); + await extension.openUSS(dsNode, false, true, testUSSTree); expect(openTextDocument.mock.calls.length).toBe(1); expect(showTextDocument.mock.calls.length).toBe(1); diff --git a/i18n/sample/src/ZoweNode.i18n.json b/i18n/sample/src/ZoweNode.i18n.json index c47c41da6c..f945f3c9e8 100644 --- a/i18n/sample/src/ZoweNode.i18n.json +++ b/i18n/sample/src/ZoweNode.i18n.json @@ -1,6 +1,7 @@ { "getChildren.search": "Use the search button to display datasets", "getChildren.error.invalidNode": "Invalid node", + "ZoweJobNode.getJobs.progress": "Get Dataset list command submitted.", "getChildren.error.response": "Retrieving response from zowe.List", "getChildren.responses.error": "The response from Zowe CLI was not successful", "getChildren.noDataset": "No datasets found" diff --git a/i18n/sample/src/ZoweUSSNode.i18n.json b/i18n/sample/src/ZoweUSSNode.i18n.json index af1ae6d4bf..5a9a0eaee5 100644 --- a/i18n/sample/src/ZoweUSSNode.i18n.json +++ b/i18n/sample/src/ZoweUSSNode.i18n.json @@ -1,5 +1,6 @@ { "getChildren.error.invalidNode": "Invalid node", + "ZoweUssNode.getList.progress": "Get USS file list command submitted.", "getChildren.error.response": "Retrieving response from ", "getChildren.responses.error.response": "The response from Zowe CLI was not successful", "getChildren.responses.open": "Open", diff --git a/src/ZoweDatasetNode.ts b/src/ZoweDatasetNode.ts index 265c286e26..af3e200f6c 100644 --- a/src/ZoweDatasetNode.ts +++ b/src/ZoweDatasetNode.ts @@ -96,24 +96,15 @@ export class ZoweDatasetNode extends ZoweTreeNode implements IZoweDatasetTreeNod throw Error(localize("getChildren.error.invalidNode", "Invalid node")); } - // Check if node is a favorite - let label = this.label.trim(); - if (this.label.startsWith("[")) { - label = this.label.substring(this.label.indexOf(":") + 1).trim(); - } - // Gets the datasets from the pattern or members of the dataset and displays any thrown errors - const responses: zowe.IZosFilesResponse[] = []; + let responses: zowe.IZosFilesResponse[] = []; try { - if (this.contextValue === extension.DS_SESSION_CONTEXT) { - this.pattern = this.pattern.toUpperCase(); - // loop through each pattern - for (const pattern of this.pattern.split(",")) { - responses.push(await zowe.List.dataSet(this.getSession(), pattern.trim(), {attributes: true})); - } - } else { - responses.push(await zowe.List.allMembers(this.getSession(), label, {attributes: true})); - } + responses = await vscode.window.withProgress({ + location: vscode.ProgressLocation.Notification, + title: localize("ZoweJobNode.getJobs.progress", "Get Dataset list command submitted.") + }, () => { + return this.getDatasets(); + }); } catch (err) { vscode.window.showErrorMessage(localize("getChildren.error.response", "Retrieving response from zowe.List") + `\n${err}\n`); @@ -184,4 +175,23 @@ export class ZoweDatasetNode extends ZoweTreeNode implements IZoweDatasetTreeNod public setEtag(etagValue): void { this.etag = etagValue; } + + private async getDatasets(): Promise { + const responses: zowe.IZosFilesResponse[] = []; + if (this.contextValue === extension.DS_SESSION_CONTEXT) { + this.pattern = this.pattern.toUpperCase(); + // loop through each pattern + for (const pattern of this.pattern.split(",")) { + responses.push(await zowe.List.dataSet(this.getSession(), pattern.trim(), {attributes: true})); + } + } else { + // Check if node is a favorite + let label = this.label.trim(); + if (this.label.startsWith("[")) { + label = this.label.substring(this.label.indexOf(":") + 1).trim(); + } + responses.push(await zowe.List.allMembers(this.getSession(), label, {attributes: true})); + } + return responses; + } } diff --git a/src/ZoweJobNode.ts b/src/ZoweJobNode.ts index a66a89ea96..ba208ffa96 100644 --- a/src/ZoweJobNode.ts +++ b/src/ZoweJobNode.ts @@ -18,7 +18,8 @@ import * as extension from "./extension"; import { IZoweJobTreeNode } from "./api/IZoweTreeNode"; import { ZoweTreeNode } from "./abstract/ZoweTreeNode"; import * as utils from "./utils"; - +import * as nls from "vscode-nls"; +const localize = nls.config({ messageFormat: nls.MessageFormat.file })(); // tslint:disable-next-line: max-classes-per-file export class Job extends ZoweTreeNode implements IZoweJobTreeNode { public static readonly JobId = "JobId:"; @@ -64,10 +65,15 @@ export class Job extends ZoweTreeNode implements IZoweJobTreeNode { */ public async getChildren(): Promise { if (this.dirty) { - const elementChildren = []; let spools: zowe.IJobFile[] = []; + const elementChildren = []; if (this.contextValue === extension.JOBS_JOB_CONTEXT || this.contextValue === extension.JOBS_JOB_CONTEXT + extension.FAV_SUFFIX) { - spools = await zowe.GetJobs.getSpoolFiles(this.session, this.job.jobname, this.job.jobid); + spools = await vscode.window.withProgress({ + location: vscode.ProgressLocation.Notification, + title: localize("ZoweJobNode.getJobs.spoolfiles", "Get Job Spool files command submitted.") + }, () => { + return zowe.GetJobs.getSpoolFiles(this.session, this.job.jobname, this.job.jobid); + }); spools.forEach((spool) => { const existing = this.children.find((element) => element.label.trim() === `${spool.stepname}:${spool.ddname}(${spool.id})` ); if (existing) { @@ -88,12 +94,12 @@ export class Job extends ZoweTreeNode implements IZoweJobTreeNode { } }); } else { - let jobs: zowe.IJob[] = []; - if (this.searchId.length > 0 ) { - jobs.push(await zowe.GetJobs.getJob(this.session, this._searchId)); - } else { - jobs = await zowe.GetJobs.getJobsByOwnerAndPrefix(this.session, this._owner, this._prefix); - } + const jobs = await vscode.window.withProgress({ + location: vscode.ProgressLocation.Notification, + title: localize("ZoweJobNode.getJobs.jobs", "Get Jobs command submitted.") + }, () => { + return this.getJobs(this.session, this._owner, this._prefix, this._searchId); + }); jobs.forEach((job) => { let nodeTitle: string; if (job.retcode) { @@ -181,6 +187,16 @@ export class Job extends ZoweTreeNode implements IZoweJobTreeNode { public get searchId() { return this._searchId; } + + private async getJobs(session, owner, prefix, searchId): Promise { + let jobsInternal: zowe.IJob[] = []; + if (this.searchId.length > 0 ) { + jobsInternal.push(await zowe.GetJobs.getJob(session, searchId)); + } else { + jobsInternal = await zowe.GetJobs.getJobsByOwnerAndPrefix(session, owner, prefix); + } + return jobsInternal; + } } // tslint:disable-next-line: max-classes-per-file diff --git a/src/ZoweUSSNode.ts b/src/ZoweUSSNode.ts index c8bb84ff7c..023dc4ae3f 100644 --- a/src/ZoweUSSNode.ts +++ b/src/ZoweUSSNode.ts @@ -126,7 +126,12 @@ export class ZoweUSSNode extends ZoweTreeNode implements IZoweUSSTreeNode { // Gets the directories from the fullPath and displays any thrown errors const responses: zowe.IZosFilesResponse[] = []; try { - responses.push(await zowe.List.fileList(this.getSession(), this.fullPath)); + responses.push(await vscode.window.withProgress({ + location: vscode.ProgressLocation.Notification, + title: localize("ZoweUssNode.getList.progress", "Get USS file list command submitted.") + }, () => { + return zowe.List.fileList(this.getSession(), this.fullPath); + })); } catch (err) { vscode.window.showErrorMessage(localize("getChildren.error.response", "Retrieving response from ") + `zowe.List\n${err}\n`); diff --git a/src/extension.ts b/src/extension.ts index 423ed517cd..a634fd185d 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -1163,7 +1163,7 @@ export async function cleanTempDir() { try { cleanDir(BRIGHTTEMPFOLDER); } catch (err) { - vscode.window.showErrorMessage(localize("deactivate.error", "Unable to delete temporary folder. ") + err); // TODO MISSED TESTING + vscode.window.showErrorMessage(localize("deactivate.error", "Unable to delete temporary folder. ") + err); } } @@ -1315,7 +1315,7 @@ export function getProfile(node: IZoweTreeNode) { let profile = node.getSessionNode().label.trim(); // if this is a favorite node, further extraction is necessary if (profile.includes("[")) { - profile = profile.substring(profile.indexOf("[") + 1, profile.indexOf("]")); // TODO MISSED TESTING + profile = profile.substring(profile.indexOf("[") + 1, profile.indexOf("]")); } return profile; } @@ -1462,7 +1462,7 @@ export async function openPS(node: IZoweDatasetTreeNode, previewMember: boolean, location: vscode.ProgressLocation.Notification, title: "Opening data set..." }, function downloadDataset() { - return zowe.Download.dataSet(node.getSession(), label, { // TODO MISSED TESTING + return zowe.Download.dataSet(node.getSession(), label, { file: documentFilePath, returnEtag: true }); @@ -1706,7 +1706,7 @@ export async function saveFile(doc: vscode.TextDocument, datasetProvider: IZoweT return zowe.Upload.pathToDataSet(documentSession, doc.fileName, label, uploadOptions); // TODO MISSED TESTING }); if (uploadResponse.success) { - vscode.window.showInformationMessage(uploadResponse.commandResponse); // TODO MISSED TESTING + vscode.window.showInformationMessage(uploadResponse.commandResponse); // set local etag with the new etag from the updated file on mainframe node.setEtag(uploadResponse.apiResponse[0].etag); } else if (!uploadResponse.success && uploadResponse.commandResponse.includes(localize("saveFile.error.ZosmfEtagMismatchError", "Rest API failure with HTTP(S) status 412"))) { @@ -1735,7 +1735,7 @@ export async function saveFile(doc: vscode.TextDocument, datasetProvider: IZoweT vscode.window.showErrorMessage(uploadResponse.commandResponse); } } catch (err) { - vscode.window.showErrorMessage(err.message); // TODO MISSED TESTING + vscode.window.showErrorMessage(err.message); } } @@ -1891,7 +1891,7 @@ export async function openUSS(node: IZoweUSSTreeNode, download = false, previewF location: vscode.ProgressLocation.Notification, title: "Opening USS file...", }, function downloadUSSFile() { - return zowe.Download.ussFile(node.getSession(), node.fullPath, { // TODO MISSED TESTING + return zowe.Download.ussFile(node.getSession(), node.fullPath, { file: documentFilePath, binary: chooseBinary, returnEtag: true From 1b15a2de50e3ec82a60d5efcf8a7ad3b66fa24d8 Mon Sep 17 00:00:00 2001 From: Colin Stone <30794003+Colin-Stone@users.noreply.github.com> Date: Wed, 29 Jan 2020 12:02:57 +0000 Subject: [PATCH 13/19] merged updates Signed-off-by: Colin Stone <30794003+Colin-Stone@users.noreply.github.com> --- __tests__/__unit__/DatasetTree.unit.test.ts | 19 +++++- __tests__/__unit__/ZoweNode.unit.test.ts | 10 +++- __tests__/__unit__/ZoweUSSNode.unit.test.ts | 12 ++-- __tests__/__unit__/extension.unit.test.ts | 16 +++-- i18n/sample/src/DatasetTree.i18n.json | 1 + i18n/sample/src/USSTree.i18n.json | 1 + i18n/sample/src/ZoweDatasetNode.i18n.json | 5 +- i18n/sample/src/ZoweNode.i18n.json | 2 +- i18n/sample/src/extension.i18n.json | 1 + i18n/sample/src/uss/ussNodeActions.i18n.json | 1 + i18n/sample/src/utils.i18n.json | 5 +- src/DatasetTree.ts | 30 +++++----- src/USSTree.ts | 11 ++-- src/ZosJobsProvider.ts | 12 ++-- src/ZoweDatasetNode.ts | 42 +++++++------- src/ZoweJobNode.ts | 7 ++- src/ZoweUSSNode.ts | 4 +- src/command/MvsCommandHandler.ts | 4 +- src/extension.ts | 61 ++++++++++---------- src/mvs/mvsNodeActions.ts | 3 +- src/uss/ussNodeActions.ts | 11 ++-- src/utils.ts | 32 +++++++++- 22 files changed, 181 insertions(+), 109 deletions(-) diff --git a/__tests__/__unit__/DatasetTree.unit.test.ts b/__tests__/__unit__/DatasetTree.unit.test.ts index 8e18276501..c48c13c1a6 100644 --- a/__tests__/__unit__/DatasetTree.unit.test.ts +++ b/__tests__/__unit__/DatasetTree.unit.test.ts @@ -39,6 +39,7 @@ describe("DatasetTree Unit Tests", () => { // Filter prompt const showInformationMessage = jest.fn(); + const showErrorMessage = jest.fn(); const showInputBox = jest.fn(); const showQuickPick = jest.fn(); const filters = jest.fn(); @@ -67,7 +68,7 @@ describe("DatasetTree Unit Tests", () => { Object.defineProperty(vscode, "ProgressLocation", {value: ProgressLocation}); Object.defineProperty(vscode.window, "withProgress", {value: withProgress}); Object.defineProperty(vscode.window, "showInformationMessage", {value: showInformationMessage}); - Object.defineProperty(vscode.window, "showInformationMessage", {value: showInformationMessage}); + Object.defineProperty(vscode.window, "showErrorMessage", {value: showErrorMessage}); Object.defineProperty(vscode.window, "showQuickPick", {value: showQuickPick}); Object.defineProperty(vscode.window, "showInputBox", {value: showInputBox}); Object.defineProperty(filters, "getFilters", { value: getFilters }); @@ -905,4 +906,20 @@ describe("DatasetTree Unit Tests", () => { expect(foundNode).toBe(nonFavoritedNode); sessionNode.children.pop(); }); + + it("tests utils error handling", async () => { + showQuickPick.mockReset(); + showInputBox.mockReset(); + showErrorMessage.mockReset(); + + const label = "invalidCred"; + // tslint:disable-next-line: object-literal-key-quotes + const error = {"mDetails": {"errorCode": 401}}; + await utils.errorHandling(error, label); + + expect(showErrorMessage.mock.calls.length).toEqual(1); + expect(showErrorMessage.mock.calls[0][0]).toEqual("Invalid Credentials. Please ensure the username and password for " + + `\n${label}\n` + + " are valid or this may lead to a lock-out."); + }); }); diff --git a/__tests__/__unit__/ZoweNode.unit.test.ts b/__tests__/__unit__/ZoweNode.unit.test.ts index 456cfd99cb..f657a91cf9 100644 --- a/__tests__/__unit__/ZoweNode.unit.test.ts +++ b/__tests__/__unit__/ZoweNode.unit.test.ts @@ -48,6 +48,9 @@ describe("Unit Tests (Jest)", () => { }); }); + const showErrorMessage = jest.fn(); + Object.defineProperty(vscode.window, "showErrorMessage", {value: showErrorMessage}); + afterEach(() => { jest.resetAllMocks(); }); @@ -135,13 +138,16 @@ describe("Unit Tests (Jest)", () => { *************************************************************************************************************/ it("Checks that when bright.List.dataSet/allMembers() causes an error on the brightside call, " + "it throws an error and the catch block is reached", async () => { + + showErrorMessage.mockReset(); // Creating a rootNode const rootNode = new ZoweDatasetNode("root", vscode.TreeItemCollapsibleState.Collapsed, null, session); rootNode.contextValue = extension.DS_SESSION_CONTEXT; rootNode.pattern = "THROW ERROR"; rootNode.dirty = true; - await expect(rootNode.getChildren()).rejects.toEqual(Error("Retrieving response from zowe.List\n" + - "Error: Throwing an error to check error handling for unit tests!\n")); + rootNode.getChildren(); + expect(showErrorMessage.mock.calls.length).toEqual(1); + expect(showErrorMessage.mock.calls[0][0]).toEqual("Retrieving response from zowe.List"); }); /************************************************************************************************************* diff --git a/__tests__/__unit__/ZoweUSSNode.unit.test.ts b/__tests__/__unit__/ZoweUSSNode.unit.test.ts index de85a5ab45..20cf4d8175 100644 --- a/__tests__/__unit__/ZoweUSSNode.unit.test.ts +++ b/__tests__/__unit__/ZoweUSSNode.unit.test.ts @@ -29,6 +29,8 @@ describe("Unit Tests (Jest)", () => { protocol: "https", type: "basic", }); + const showErrorMessage = jest.fn(); + Object.defineProperty(vscode.window, "showErrorMessage", {value: showErrorMessage}); const ProgressLocation = jest.fn().mockImplementation(() => { return { @@ -132,8 +134,9 @@ describe("Unit Tests (Jest)", () => { rootNode.contextValue = extension.USS_SESSION_CONTEXT; rootNode.fullPath = "Throw Error"; rootNode.dirty = true; - await expect(rootNode.getChildren()).rejects.toEqual(Error("Retrieving response from zowe.List\n" + - "Error: Throwing an error to check error handling for unit tests!\n")); + rootNode.getChildren(); + expect(showErrorMessage.mock.calls.length).toEqual(1); + expect(showErrorMessage.mock.calls[0][0]).toEqual("Retrieving response from zowe.List"); }); /************************************************************************************************************* @@ -148,8 +151,9 @@ describe("Unit Tests (Jest)", () => { const subNode = new ZoweUSSNode("Response Fail", vscode.TreeItemCollapsibleState.Collapsed, rootNode, null, null); subNode.fullPath = "THROW ERROR"; subNode.dirty = true; - await expect(subNode.getChildren()).rejects.toEqual(Error("Retrieving response from zowe.List\n" + - "Error: Throwing an error to check error handling for unit tests!\n")); + subNode.getChildren(); + expect(showErrorMessage.mock.calls.length).toEqual(1); + expect(showErrorMessage.mock.calls[0][0]).toEqual("Retrieving response from zowe.List"); }); /************************************************************************************************************* diff --git a/__tests__/__unit__/extension.unit.test.ts b/__tests__/__unit__/extension.unit.test.ts index 535a5f3a9a..33d3e2ee4e 100644 --- a/__tests__/__unit__/extension.unit.test.ts +++ b/__tests__/__unit__/extension.unit.test.ts @@ -241,6 +241,7 @@ describe("Extension Unit Tests", () => { renameNode: mockRenameNode, findFavoritedNode, findNonFavoritedNode, + getProfileName: jest.fn() }; }); const USSTree = jest.fn().mockImplementation(() => { @@ -262,7 +263,8 @@ describe("Extension Unit Tests", () => { getChildren: jest.fn(), addSession: jest.fn(), refresh: jest.fn(), - refreshElement: jest.fn() + refreshElement: jest.fn(), + getProfileName: jest.fn() }; }); @@ -289,7 +291,6 @@ describe("Extension Unit Tests", () => { const testJobsTree = JobsTree(); testJobsTree.mSessionNodes = []; testJobsTree.mSessionNodes.push(jobNode); - const mockLoadNamedProfile = jest.fn(); Object.defineProperty(profileLoader.Profiles, "createInstance", { value: jest.fn(() => { @@ -1178,9 +1179,8 @@ describe("Extension Unit Tests", () => { } catch (err) { // do nothing } - expect(showErrorMessage.mock.calls.length).toBe(1); - expect(showErrorMessage.mock.calls[0][0]).toBe("Generic Error"); + expect(showErrorMessage.mock.calls[0][0]).toBe("Error encountered when creating data set! Generic Error"); showQuickPick.mockReset(); showErrorMessage.mockReset(); @@ -1484,7 +1484,7 @@ describe("Extension Unit Tests", () => { await expect(extension.deleteDataset(node, testTree)).rejects.toEqual(Error("")); expect(showErrorMessage.mock.calls.length).toBe(1); - expect(showErrorMessage.mock.calls[0][0]).toEqual(Error("")); + expect(showErrorMessage.mock.calls[0][0]).toEqual(""); showQuickPick.mockResolvedValueOnce("No"); @@ -1573,8 +1573,6 @@ describe("Extension Unit Tests", () => { existsSync.mockReturnValueOnce(true); showQuickPick.mockResolvedValueOnce("Yes"); await expect(extension.deleteDataset(child, testTree)).rejects.toEqual(Error("deleteDataSet() called from invalid node.")); - expect(showErrorMessage.mock.calls.length).toBe(1); - expect(showErrorMessage.mock.calls[0][0].message).toEqual("deleteDataSet() called from invalid node."); }); it("Testing that enterPattern is executed successfully", async () => { @@ -2117,7 +2115,7 @@ describe("Extension Unit Tests", () => { expect(ussFile.mock.calls[0][1]).toBe(child.fullPath); expect(showErrorMessage.mock.calls.length).toBe(1); - expect(showErrorMessage.mock.calls[0][0]).toEqual(Error("")); + expect(showErrorMessage.mock.calls[0][0]).toEqual(""); showErrorMessage.mockReset(); openTextDocument.mockReset(); @@ -3557,7 +3555,7 @@ describe("Extension Unit Tests", () => { }); extension.moveTempFolder(originalPreferencePath, updatedPreferencePath); expect(showErrorMessage.mock.calls.length).toBe(1); - expect(showErrorMessage.mock.calls[0][0]).toEqual("testAsError 1"); + expect(showErrorMessage.mock.calls[0][0]).toEqual("Error encountered when creating temporary folder! testAsError 1"); }); it("Tests that temp folder error thrown 2", () => { diff --git a/i18n/sample/src/DatasetTree.i18n.json b/i18n/sample/src/DatasetTree.i18n.json index fc59e8398a..8eacbf11ae 100644 --- a/i18n/sample/src/DatasetTree.i18n.json +++ b/i18n/sample/src/DatasetTree.i18n.json @@ -10,6 +10,7 @@ "initializeFavorites.fileCorrupted": "Favorites file corrupted: ", "addFavorite": "PDS already in favorites", "enterPattern.log.debug.prompt": "Prompting the user for a data set pattern", + "datasetTree.error": "Error encountered in ", "searchHistory.options.prompt": "Select a filter", "enterPattern.pattern": "No selection made.", "enterPattern.options.prompt": "Search data sets by entering patterns: use a comma to separate multiple patterns", diff --git a/i18n/sample/src/USSTree.i18n.json b/i18n/sample/src/USSTree.i18n.json index c8f5700be6..9c81949265 100644 --- a/i18n/sample/src/USSTree.i18n.json +++ b/i18n/sample/src/USSTree.i18n.json @@ -1,6 +1,7 @@ { "Favorites": "Favorites", "ussFilterPrompt.log.debug.promptUSSPath": "Prompting the user for a USS path", + "ussTree.error": "Error encountered in ", "searchHistory.options.prompt": "Select a filter", "enterPattern.pattern": "No selection made.", "ussFilterPrompt.option.prompt.search": "Create a new filter", diff --git a/i18n/sample/src/ZoweDatasetNode.i18n.json b/i18n/sample/src/ZoweDatasetNode.i18n.json index c47c41da6c..878421c64a 100644 --- a/i18n/sample/src/ZoweDatasetNode.i18n.json +++ b/i18n/sample/src/ZoweDatasetNode.i18n.json @@ -1,7 +1,8 @@ { "getChildren.search": "Use the search button to display datasets", "getChildren.error.invalidNode": "Invalid node", - "getChildren.error.response": "Retrieving response from zowe.List", + "ZoweJobNode.getJobs.progress": "Get Dataset list command submitted.", "getChildren.responses.error": "The response from Zowe CLI was not successful", - "getChildren.noDataset": "No datasets found" + "getChildren.noDataset": "No datasets found", + "getChildren.error.response": "Retrieving response from " } \ No newline at end of file diff --git a/i18n/sample/src/ZoweNode.i18n.json b/i18n/sample/src/ZoweNode.i18n.json index f945f3c9e8..18cb86b33c 100644 --- a/i18n/sample/src/ZoweNode.i18n.json +++ b/i18n/sample/src/ZoweNode.i18n.json @@ -1,8 +1,8 @@ { "getChildren.search": "Use the search button to display datasets", "getChildren.error.invalidNode": "Invalid node", + "getChildren.error.response": "Retrieving response from ", "ZoweJobNode.getJobs.progress": "Get Dataset list command submitted.", - "getChildren.error.response": "Retrieving response from zowe.List", "getChildren.responses.error": "The response from Zowe CLI was not successful", "getChildren.noDataset": "No datasets found" } \ No newline at end of file diff --git a/i18n/sample/src/extension.i18n.json b/i18n/sample/src/extension.i18n.json index 53e17760a5..e3de90d22d 100644 --- a/i18n/sample/src/extension.i18n.json +++ b/i18n/sample/src/extension.i18n.json @@ -10,6 +10,7 @@ "activate.didSaveText.notDataSet": " is not a data set or USS file ", "profile.init.read.imperative": "Unable to read imperative file. ", "initialize.module.load": "Credentials not managed, unable to load security file: ", + "moveTempFolder.error": "Error encountered when creating temporary folder! ", "downloadSpool.select": "Select", "submitJcl.log.debug": "Submitting JCL in document ", "submitJcl.quickPickOption": "Select the Profile to use to submit the job", diff --git a/i18n/sample/src/uss/ussNodeActions.i18n.json b/i18n/sample/src/uss/ussNodeActions.i18n.json index 75394b3c5d..ed3698b7e6 100644 --- a/i18n/sample/src/uss/ussNodeActions.i18n.json +++ b/i18n/sample/src/uss/ussNodeActions.i18n.json @@ -1,6 +1,7 @@ { "createUSSNode.name": "Name of file or directory", "createUSSNode.error.create": "Unable to create node: ", + "ussNodeActions.error": "Error encountered in ", "renameUSSNode.error": "Unable to rename node: ", "copyPath.infoMessage": "Copy Path is not yet supported in Theia." } \ No newline at end of file diff --git a/i18n/sample/src/utils.i18n.json b/i18n/sample/src/utils.i18n.json index c94418e55b..8011020fb4 100644 --- a/i18n/sample/src/utils.i18n.json +++ b/i18n/sample/src/utils.i18n.json @@ -1,4 +1,7 @@ { "zosJobsProvider.option.prompt.createOwner": "Owner/Prefix Job Search", - "zosJobsProvider.option.prompt.createId": "Job Id search" + "zosJobsProvider.option.prompt.createId": "Job Id search", + "errorHandling.invalid.credentials": "Invalid Credentials. ", + "errorHandling.invalid.credentials2": "Please ensure the username and password for ", + "errorHandling.invalid.credentials3": " are valid or this may lead to a lock-out." } \ No newline at end of file diff --git a/src/DatasetTree.ts b/src/DatasetTree.ts index da8bd6048b..6a0c279ea8 100644 --- a/src/DatasetTree.ts +++ b/src/DatasetTree.ts @@ -16,7 +16,7 @@ import * as vscode from "vscode"; import * as nls from "vscode-nls"; import * as extension from "../src/extension"; import { Profiles } from "./Profiles"; -import { sortTreeItems, applyIcons, FilterDescriptor, FilterItem, getAppName, resolveQuickPickHelper } from "./utils"; +import { sortTreeItems, applyIcons, FilterDescriptor, FilterItem, getAppName, resolveQuickPickHelper, errorHandling } from "./utils"; import { IZoweTree } from "./api/IZoweTree"; import { IZoweDatasetTreeNode } from "./api/IZoweTreeNode"; import { ZoweTreeProvider } from "./abstract/ZoweTreeProvider"; @@ -109,14 +109,15 @@ export class DatasetTree extends ZoweTreeProvider implements IZoweTree { - return this.getDatasets(); - }); - } catch (err) { - vscode.window.showErrorMessage(localize("getChildren.error.response", "Retrieving response from zowe.List") - + `\n${err}\n`); - throw Error(localize("getChildren.error.response", "Retrieving response from zowe.List") + `\n${err}\n`); - } + }, () => { + return this.getDatasets(); + }); // push nodes to an object with property names to avoid duplicates const elementChildren = {}; @@ -178,19 +172,23 @@ export class ZoweDatasetNode extends ZoweTreeNode implements IZoweDatasetTreeNod private async getDatasets(): Promise { const responses: zowe.IZosFilesResponse[] = []; - if (this.contextValue === extension.DS_SESSION_CONTEXT) { - this.pattern = this.pattern.toUpperCase(); - // loop through each pattern - for (const pattern of this.pattern.split(",")) { - responses.push(await zowe.List.dataSet(this.getSession(), pattern.trim(), {attributes: true})); - } - } else { - // Check if node is a favorite - let label = this.label.trim(); - if (this.label.startsWith("[")) { - label = this.label.substring(this.label.indexOf(":") + 1).trim(); + try { + if (this.contextValue === extension.DS_SESSION_CONTEXT) { + this.pattern = this.pattern.toUpperCase(); + // loop through each pattern + for (const pattern of this.pattern.split(",")) { + responses.push(await zowe.List.dataSet(this.getSession(), pattern.trim(), {attributes: true})); + } + } else { + // Check if node is a favorite + let label = this.label.trim(); + if (this.label.startsWith("[")) { + label = this.label.substring(this.label.indexOf(":") + 1).trim(); + } + responses.push(await zowe.List.allMembers(this.getSession(), label, {attributes: true})); } - responses.push(await zowe.List.allMembers(this.getSession(), label, {attributes: true})); + } catch (err) { + await utils.errorHandling(err, this.label, localize("getChildren.error.response", "Retrieving response from ") + `zowe.List`); } return responses; } diff --git a/src/ZoweJobNode.ts b/src/ZoweJobNode.ts index ba208ffa96..aba81279d0 100644 --- a/src/ZoweJobNode.ts +++ b/src/ZoweJobNode.ts @@ -20,6 +20,7 @@ import { ZoweTreeNode } from "./abstract/ZoweTreeNode"; import * as utils from "./utils"; import * as nls from "vscode-nls"; const localize = nls.config({ messageFormat: nls.MessageFormat.file })(); + // tslint:disable-next-line: max-classes-per-file export class Job extends ZoweTreeNode implements IZoweJobTreeNode { public static readonly JobId = "JobId:"; @@ -193,7 +194,11 @@ export class Job extends ZoweTreeNode implements IZoweJobTreeNode { if (this.searchId.length > 0 ) { jobsInternal.push(await zowe.GetJobs.getJob(session, searchId)); } else { - jobsInternal = await zowe.GetJobs.getJobsByOwnerAndPrefix(session, owner, prefix); + try { + jobsInternal = await zowe.GetJobs.getJobsByOwnerAndPrefix(session, owner, prefix); + } catch (error) { + await utils.errorHandling(error, this.label, localize("getChildren.error.response", "Retrieving response from ") + `zowe.GetJobs`); + } } return jobsInternal; } diff --git a/src/ZoweUSSNode.ts b/src/ZoweUSSNode.ts index 023dc4ae3f..37a93ca5de 100644 --- a/src/ZoweUSSNode.ts +++ b/src/ZoweUSSNode.ts @@ -133,9 +133,7 @@ export class ZoweUSSNode extends ZoweTreeNode implements IZoweUSSTreeNode { return zowe.List.fileList(this.getSession(), this.fullPath); })); } catch (err) { - vscode.window.showErrorMessage(localize("getChildren.error.response", "Retrieving response from ") - + `zowe.List\n${err}\n`); - throw Error(localize("getChildren.error.response", "Retrieving response from ") + `zowe.List\n${err}\n`); + utils.errorHandling(err, this.label, localize("getChildren.error.response", "Retrieving response from ") + `zowe.List`); } // push nodes to an object with property names to avoid duplicates const elementChildren = {}; diff --git a/src/command/MvsCommandHandler.ts b/src/command/MvsCommandHandler.ts index ae4e4d0aa7..e6da74984d 100644 --- a/src/command/MvsCommandHandler.ts +++ b/src/command/MvsCommandHandler.ts @@ -16,7 +16,7 @@ import * as nls from "vscode-nls"; import * as extension from "../extension"; import { Profiles } from "../Profiles"; import { PersistentFilters } from "../PersistentFilters"; -import { FilterDescriptor, FilterItem, resolveQuickPickHelper } from "../utils"; +import { FilterDescriptor, FilterItem, resolveQuickPickHelper, errorHandling } from "../utils"; const localize = nls.config({ messageFormat: nls.MessageFormat.file })(); /** @@ -194,7 +194,7 @@ export class MvsCommandHandler { } } } catch (error) { - vscode.window.showErrorMessage(error.message); + await errorHandling(error, null, error.message); } this.history.addHistory(command); } diff --git a/src/extension.ts b/src/extension.ts index a634fd185d..656463a4a0 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -100,7 +100,7 @@ export async function activate(context: vscode.ExtensionContext) { fs.mkdirSync(USS_DIR); fs.mkdirSync(DS_DIR); } catch (err) { - vscode.window.showErrorMessage(err.message); + await utils.errorHandling(err, null, err.message); } let datasetProvider: DatasetTree; @@ -147,8 +147,8 @@ export async function activate(context: vscode.ExtensionContext) { jobsProvider = await createJobsTree(log); } catch (err) { + await utils.errorHandling(err, null,(localize("initialize.log.error", "Error encountered while activating and initializing logger! "))); log.error(localize("initialize.log.error", "Error encountered while activating and initializing logger! ") + JSON.stringify(err)); - vscode.window.showErrorMessage(err.message); // TODO MISSED TESTING } const spoolProvider = new SpoolProvider(); @@ -418,8 +418,8 @@ export function moveTempFolder(previousTempPath: string, currentTempPath: string fs.mkdirSync(USS_DIR); fs.mkdirSync(DS_DIR); } catch (err) { - log.error("Error encountered when creating temporary folder! " + JSON.stringify(err)); - vscode.window.showErrorMessage(err.message); + log.error(localize("moveTempFolder.error", "Error encountered when creating temporary folder! ") + JSON.stringify(err)); + utils.errorHandling(err, null, localize("moveTempFolder.error", "Error encountered when creating temporary folder! ") + err.message); } const previousTemp = path.join(previousTempPath, "temp"); try { @@ -464,7 +464,7 @@ export async function downloadSpool(job: Job){ }); } } catch (error) { - vscode.window.showErrorMessage(error.message); + await utils.errorHandling(error, null, error.message); } } @@ -475,7 +475,7 @@ export async function downloadJcl(job: Job) { const jclDoc = await vscode.workspace.openTextDocument({language: "jcl", content: jobJcl}); await vscode.window.showTextDocument(jclDoc); } catch (error) { - vscode.window.showErrorMessage(error.message); + await utils.errorHandling(error, null, error.message); } } @@ -548,7 +548,7 @@ export async function submitJcl(datasetProvider: DatasetTree) { const setJobCmd = `command:zowe.setJobSpool?${encodeURIComponent(JSON.stringify(args))}`; vscode.window.showInformationMessage(localize("submitJcl.jobSubmitted" ,"Job submitted ") + `[${job.jobid}](${setJobCmd})`); } catch (error) { - vscode.window.showErrorMessage(localize("submitJcl.jobSubmissionFailed", "Job submission failed\n") + error.message); + await utils.errorHandling(error, sesName, localize("submitJcl.jobSubmissionFailed", "Job submission failed\n") + error.message); } } @@ -593,7 +593,7 @@ export async function submitMember(node: IZoweTreeNode) { const setJobCmd = `command:zowe.setJobSpool?${encodeURIComponent(JSON.stringify(args))}`; vscode.window.showInformationMessage(localize("submitMember.jobSubmitted" ,"Job submitted ") + `[${job.jobid}](${setJobCmd})`); } catch (error) { - vscode.window.showErrorMessage(localize("submitMember.jobSubmissionFailed", "Job submission failed\n") + error.message); + await utils.errorHandling(error, sesName, localize("submitMember.jobSubmissionFailed", "Job submission failed\n") + error.message); } } @@ -676,13 +676,13 @@ export async function addZoweSession(zoweFileProvider: IZoweTree) try { newprofile = await Profiles.getInstance().createNewConnection(chosenProfile); } catch (error) { - vscode.window.showErrorMessage(error.message); + await utils.errorHandling(error, chosenProfile, error.message); } if (newprofile) { try { await Profiles.getInstance().refresh(); } catch (error) { - vscode.window.showErrorMessage(error.message); + await utils.errorHandling(error, newprofile, error.message); } await zoweFileProvider.addSession(newprofile); await zoweFileProvider.refresh(); @@ -733,7 +733,7 @@ export async function createFile(node: ZoweDatasetNode, datasetProvider: Dataset baseEncd = values [2]; } } catch (error) { - vscode.window.showErrorMessage(error.message); + await utils.errorHandling(error, node.getProfileName(), error.message); } if (usrNme !== undefined && passWrd !== undefined && baseEncd !== undefined) { node.getSession().ISession.user = usrNme; @@ -833,7 +833,8 @@ export async function createFile(node: ZoweDatasetNode, datasetProvider: Dataset } } catch (err) { log.error(localize("createDataSet.error", "Error encountered when creating data set! ") + JSON.stringify(err)); - vscode.window.showErrorMessage(err.message); + await utils.errorHandling(err, node.getProfileName(), localize("createDataSet.error", "Error encountered when creating data set! ") + + err.message); throw (err); } } @@ -859,7 +860,7 @@ export async function createMember(parent: ZoweDatasetNode, datasetProvider: Dat await zowe.Upload.bufferToDataSet(parent.getSession(), Buffer.from(""), label + "(" + name + ")"); } catch (err) { log.error(localize("createMember.log.error", "Error encountered when creating member! ") + JSON.stringify(err)); - vscode.window.showErrorMessage(localize("createMember.error", "Unable to create member: ") + err.message); + await utils.errorHandling(err, label, localize("createMember.error", "Unable to create member: ") + err.message); throw (err); } parent.dirty = true; @@ -897,7 +898,7 @@ export async function showDSAttributes(parent: ZoweDatasetNode, datasetProvider: } } catch (err) { log.error(localize("showDSAttributes.log.error", "Error encountered when listing attributes! ") + JSON.stringify(err)); - vscode.window.showErrorMessage(localize("showDSAttributes.error", "Unable to list attributes: ") + err.message); + await utils.errorHandling(err, parent.getProfileName(), localize("showDSAttributes.error", "Unable to list attributes: ") + err.message); throw (err); } @@ -962,7 +963,7 @@ export async function renameDataSet(node: ZoweDatasetNode, datasetProvider: Data node.label = `${favPrefix}${afterDataSetName}`; } catch (err) { log.error(localize("renameDataSet.log.error", "Error encountered when renaming data set! ") + JSON.stringify(err)); - vscode.window.showErrorMessage(localize("renameDataSet.error", "Unable to rename data set: ") + err.message); + await utils.errorHandling(err, favPrefix, localize("renameDataSet.error", "Unable to rename data set: ") + err.message); throw err; } if (isFavourite) { @@ -1103,7 +1104,7 @@ export async function renameDataSetMember(node: IZoweTreeNode, datasetProvider: node.label = `${profileLabel}${afterMemberName}`; } catch (err) { log.error(localize("renameDataSet.log.error", "Error encountered when renaming data set! ") + JSON.stringify(err)); - vscode.window.showErrorMessage(localize("renameDataSet.error", "Unable to rename data set: ") + err.message); + await utils.errorHandling(err, profileLabel, localize("renameDataSet.error", "Unable to rename data set: ") + err.message); throw err; } if (node.getParent().contextValue.includes(FAV_SUFFIX)) { @@ -1225,7 +1226,7 @@ export async function deleteDataset(node: IZoweTreeNode, datasetProvider: Datase vscode.window.showInformationMessage(localize("deleteDataSet.notFound.error1", "Unable to find file: ") + label + localize("deleteDataSet.notFound.error2", " was probably already deleted.")); } else { - vscode.window.showErrorMessage(err); + await utils.errorHandling(err, node.getProfileName(), err.message); } throw err; } @@ -1419,7 +1420,7 @@ export async function openPS(node: IZoweDatasetTreeNode, previewMember: boolean, baseEncd = values [2]; } } catch (error) { - vscode.window.showErrorMessage(error.message); + await utils.errorHandling(error, node.getProfileName(), error.message); } if (usrNme !== undefined && passWrd !== undefined && baseEncd !== undefined) { node.getSession().ISession.user = usrNme; @@ -1478,7 +1479,7 @@ export async function openPS(node: IZoweDatasetTreeNode, previewMember: boolean, } } catch (err) { log.error(localize("openPS.log.error.openDataSet", "Error encountered when opening data set! ") + JSON.stringify(err)); - vscode.window.showErrorMessage(err.message); + await utils.errorHandling(err, node.getProfileName(), err.message); throw (err); } } @@ -1546,7 +1547,7 @@ export async function refreshPS(node: ZoweDatasetNode) { vscode.window.showInformationMessage(localize("refreshPS.file1", "Unable to find file: ") + label + localize("refreshPS.file2", " was probably deleted.")); } else { - vscode.window.showErrorMessage(err.message); + await utils.errorHandling(err, node.getProfileName(), err.message); } } } @@ -1592,7 +1593,7 @@ export async function refreshUSS(node: ZoweUSSNode) { vscode.window.showInformationMessage(localize("refreshUSS.file1", "Unable to find file: ") + label + localize("refreshUSS.file2", " was probably deleted.")); } else { - vscode.window.showErrorMessage(err); + await utils.errorHandling(err, node.mProfileName, err.message); } } } @@ -1656,7 +1657,7 @@ export async function saveFile(doc: vscode.TextDocument, datasetProvider: IZoweT localize("saveFile.error.saveFailed", "Data set failed to save. Data set may have been deleted on mainframe.")); } } catch (err) { - vscode.window.showErrorMessage(err.message + "\n" + err.stack); + await utils.errorHandling(err, sesName, err.message); } } // Get specific node based on label and parent tree (session / favorites) @@ -1828,7 +1829,7 @@ export async function saveUSSFile(doc: vscode.TextDocument, ussFileProvider: USS await vscode.window.activeTextEditor.document.save(); } else { log.error(localize("saveUSSFile.log.error.save", "Error encountered when saving USS file: ") + JSON.stringify(err)); - vscode.window.showErrorMessage(err.message); + await utils.errorHandling(err, sesName, err.message); } } } @@ -1848,7 +1849,7 @@ export async function openUSS(node: IZoweUSSTreeNode, download = false, previewF baseEncd = values [2]; } } catch (error) { - vscode.window.showErrorMessage(error.message); + await utils.errorHandling(error, node.mProfileName, error.message); } if (usrNme !== undefined && passWrd !== undefined && baseEncd !== undefined) { node.getSession().ISession.user = usrNme; @@ -1909,7 +1910,7 @@ export async function openUSS(node: IZoweUSSTreeNode, download = false, previewF } } catch (err) { log.error(localize("openUSS.log.error.openFile", "Error encountered when opening USS file: ") + JSON.stringify(err)); - vscode.window.showErrorMessage(err.message); + await utils.errorHandling(err, node.mProfileName, err.message); throw (err); } } @@ -1923,7 +1924,7 @@ export async function modifyCommand(job: Job) { vscode.window.showInformationMessage(localize("modifyCommand.response", "Command response: ") + response.commandResponse); } } catch (error) { - vscode.window.showErrorMessage(error.message); + await utils.errorHandling(error, null, error.message); } } @@ -1932,7 +1933,7 @@ export async function stopCommand(job: Job) { const response = await zowe.IssueCommand.issueSimple(job.getSession(), `p ${job.job.jobname}`); vscode.window.showInformationMessage(localize("stopCommand.response", "Command response: ") + response.commandResponse); } catch (error) { - vscode.window.showErrorMessage(error.message); + await utils.errorHandling(error, null, error.message); } } @@ -1948,7 +1949,7 @@ export async function getSpoolContent(session: string, spool: IJobFile) { baseEncd = values [2]; } } catch (error) { - vscode.window.showErrorMessage(error.message); + await utils.errorHandling(error, session, error.message); } if (usrNme !== undefined && passWrd !== undefined && baseEncd !== undefined) { spoolSess.ISession.user = usrNme; @@ -1965,7 +1966,7 @@ export async function getSpoolContent(session: string, spool: IJobFile) { const document = await vscode.workspace.openTextDocument(uri); await vscode.window.showTextDocument(document); } catch (error) { - vscode.window.showErrorMessage(error.message); + await utils.errorHandling(error, session, error.message); } } } @@ -1998,7 +1999,7 @@ export async function refreshJobsServer(node: IZoweJobTreeNode, jobsProvider: IZ baseEncd = values [2]; } } catch (error) { - vscode.window.showErrorMessage(error.message); + await utils.errorHandling(error, node.getProfileName(), error.message); } if (usrNme !== undefined && passWrd !== undefined && baseEncd !== undefined) { node.getSession().ISession.user = usrNme; diff --git a/src/mvs/mvsNodeActions.ts b/src/mvs/mvsNodeActions.ts index 6728f264ee..96bfc8face 100644 --- a/src/mvs/mvsNodeActions.ts +++ b/src/mvs/mvsNodeActions.ts @@ -14,6 +14,7 @@ import * as vscode from "vscode"; import { ZoweDatasetNode } from "../ZoweDatasetNode"; import { DatasetTree } from "../DatasetTree"; import * as extension from "../../src/extension"; +import * as utils from "../utils"; export async function uploadDialog(node: ZoweDatasetNode, datasetProvider: DatasetTree) { const fileOpenOptions = { @@ -48,6 +49,6 @@ export async function uploadFile(node: ZoweDatasetNode, doc: vscode.TextDocument const datasetName = getDatasetLabel(node); await zowe.Upload.fileToDataset(node.getSession(), doc.fileName, datasetName); } catch (e) { - vscode.window.showErrorMessage(e.message); + await utils.errorHandling(e, node.getProfileName(), e.message); } } diff --git a/src/uss/ussNodeActions.ts b/src/uss/ussNodeActions.ts index ce6057f9cf..eb838ada21 100644 --- a/src/uss/ussNodeActions.ts +++ b/src/uss/ussNodeActions.ts @@ -47,8 +47,7 @@ export async function createUSSNode(node: ZoweUSSNode, ussFileProvider: USSTree, ussFileProvider.refreshElement(node); } } catch (err) { - vscode.window.showErrorMessage( - localize("createUSSNode.error.create", "Unable to create node: ") + err.message); + utils.errorHandling(err, node.mProfileName, localize("createUSSNode.error.create", "Unable to create node: ") + err.message); throw (err); } ussFileProvider.refresh(); @@ -69,7 +68,7 @@ export async function createUSSNodeDialog(node: ZoweUSSNode, ussFileProvider: US baseEncd = values[2]; } } catch (error) { - vscode.window.showErrorMessage(error.message); + utils.errorHandling(error, node.mProfileName, localize("ussNodeActions.error", "Error encountered in ") + `createUSSNodeDialog.optionalProfiles!`); return; } if (usrNme !== undefined && passWrd !== undefined && baseEncd !== undefined) { @@ -142,7 +141,7 @@ export async function renameUSSNode(originalNode: IZoweUSSTreeNode, ussFileProvi ussFileProvider.addFavorite(oldFavorite); } } catch (err) { - vscode.window.showErrorMessage(localize("renameUSSNode.error", "Unable to rename node: ") + err.message); + utils.errorHandling(err, originalNode.mProfileName, localize("renameUSSNode.error", "Unable to rename node: ") + err.message); throw (err); } } @@ -179,7 +178,7 @@ export async function uploadBinaryFile(node: ZoweUSSNode, filePath: string) { const ussName = `${node.fullPath}/${localFileName}`; await zowe.Upload.fileToUSSFile(node.getSession(), filePath, ussName, true); } catch (e) { - vscode.window.showErrorMessage(e.message); + utils.errorHandling(e, node.mProfileName, e.message); } } @@ -189,7 +188,7 @@ export async function uploadFile(node: ZoweUSSNode, doc: vscode.TextDocument) { const ussName = `${node.fullPath}/${localFileName}`; await zowe.Upload.fileToUSSFile(node.getSession(), doc.fileName, ussName); } catch (e) { - vscode.window.showErrorMessage(e.message); + utils.errorHandling(e, node.mProfileName, e.message); } } diff --git a/src/utils.ts b/src/utils.ts index b76932a535..625970569b 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -10,7 +10,7 @@ */ import * as path from "path"; -import { TreeItem, QuickPickItem, QuickPick } from "vscode"; +import { TreeItem, QuickPickItem, QuickPick, window } from "vscode"; import * as extension from "../src/extension"; import * as nls from "vscode-nls"; import { IZoweTreeNode } from "./api/IZoweTreeNode"; @@ -161,3 +161,33 @@ export function concatChildNodes(nodes: IZoweTreeNode[]) { export function getAppName(isTheia: boolean) { return isTheia? "Theia" : "VS Code"; } + +/************************************************************************************************************* + * Error Hanndling + * @param {errorDetails} error.mDetails + * @param {label} - additional information such as profile name, credentials, messageID etc + * @param {moreInfo} - additional/customized error messages + *************************************************************************************************************/ +export function errorHandling(errorDetails: any, label?: string, moreInfo?: string) { + let httpErrCode = null; + + if (errorDetails.mDetails !== undefined) { + httpErrCode = errorDetails.mDetails.errorCode; + } + + switch(httpErrCode) { + // tslint:disable-next-line: no-magic-numbers + case 401 : { + window.showErrorMessage(localize("errorHandling.invalid.credentials", "Invalid Credentials. ") + + localize("errorHandling.invalid.credentials2","Please ensure the username and password for ") + + `\n${label}\n` + + localize("errorHandling.invalid.credentials3", " are valid or this may lead to a lock-out.")); + break; + } + default: { + window.showErrorMessage(moreInfo); + break; + } + } + return; +} From 91b85c9e0f059a5af4b56b38315c8294789282c5 Mon Sep 17 00:00:00 2001 From: "Andrew W. Harn" Date: Tue, 4 Feb 2020 14:09:30 +0000 Subject: [PATCH 14/19] Add variable for full name of release VSIX Signed-off-by: Andrew W. Harn --- Jenkinsfile | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/Jenkinsfile b/Jenkinsfile index 529990378c..a625eb4e9d 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -209,14 +209,15 @@ pipeline { sh "git config --global user.email \"zowe.robot@gmail.com\"" def vscodePackageJson = readJSON file: "package.json" - def version = "vscode-extension-for-zowe-v${vscodePackageJson.version}" + def version = "v${vscodePackageJson.version}" + def versionName = "vscode-extension-for-zowe-v${vscodePackageJson.version}" - sh "npx vsce package -o ${version}.vsix" + sh "npx vsce package -o ${versionName}.vsix" // Release to Artifactory withCredentials([usernamePassword(credentialsId: ARTIFACTORY_CREDENTIALS_ID, usernameVariable: 'USERNAME', passwordVariable: 'PASSWORD')]) { script { - def uploadUrlArtifactory = "${DL_ARTIFACTORY_URL}/${version}.vsix" - sh "curl -u ${USERNAME}:${PASSWORD} --data-binary \"@${version}.vsix\" -H \"Content-Type: application/octet-stream\" -X PUT ${uploadUrlArtifactory}" + def uploadUrlArtifactory = "${DL_ARTIFACTORY_URL}/${versionName}.vsix" + sh "curl -u ${USERNAME}:${PASSWORD} --data-binary \"@${versionName}.vsix\" -H \"Content-Type: application/octet-stream\" -X PUT ${uploadUrlArtifactory}" } } withCredentials([usernamePassword(credentialsId: ZOWE_ROBOT_TOKEN, usernameVariable: 'USERNAME', passwordVariable: 'TOKEN')]) { script { @@ -235,9 +236,9 @@ pipeline { def releaseCreated = sh(returnStdout: true, script: "curl -H \"Content-Type: application/json\" -X POST -d '${releaseDetails}' ${releaseUrl}").trim() def releaseParsed = readJSON text: releaseCreated - def uploadUrl = "https://$TOKEN:x-oauth-basic@uploads.github.com/${releaseAPI}/${releaseParsed.id}/assets?name=${version}.vsix" + def uploadUrl = "https://$TOKEN:x-oauth-basic@uploads.github.com/${releaseAPI}/${releaseParsed.id}/assets?name=${versionName}.vsix" - sh "curl -X POST --data-binary @${version}.vsix -H \"Content-Type: application/octet-stream\" ${uploadUrl}" + sh "curl -X POST --data-binary @${versionName}.vsix -H \"Content-Type: application/octet-stream\" ${uploadUrl}" } } } } } From a7d37e71c9d7ba87638b4b1d605c5721f3175f2c Mon Sep 17 00:00:00 2001 From: zFernand0 Date: Wed, 5 Feb 2020 06:52:14 -0500 Subject: [PATCH 15/19] Adding npmrc for now. It can be removed as part of the mvoe2zowe effort. Signed-off-by: zFernand0 --- .gitignore | 1 - .npmrc | 1 + package-lock.json | 2 +- 3 files changed, 2 insertions(+), 2 deletions(-) create mode 100644 .npmrc diff --git a/.gitignore b/.gitignore index 2593401a9f..abaf8dccf6 100644 --- a/.gitignore +++ b/.gitignore @@ -10,6 +10,5 @@ npm-shrinkwrap.json vscode-extension-for-zowe*.vsix .vscode/settings.json .history -.npmrc .DS_Store .idea diff --git a/.npmrc b/.npmrc new file mode 100644 index 0000000000..dff9d7cafd --- /dev/null +++ b/.npmrc @@ -0,0 +1 @@ +@brightside:registry=https://api.bintray.com/npm/ca/brightside/ diff --git a/package-lock.json b/package-lock.json index e32611c4e6..1d968fb575 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "vscode-extension-for-zowe", - "version": "1.1.0", + "version": "1.2.0", "lockfileVersion": 1, "requires": true, "dependencies": { From e2c3ac497a8f9dd3ea5ce42e9a6beedb61a5ca39 Mon Sep 17 00:00:00 2001 From: Colin Stone <30794003+Colin-Stone@users.noreply.github.com> Date: Wed, 5 Feb 2020 11:55:52 +0000 Subject: [PATCH 16/19] Removed classonly methods from interface Signed-off-by: Colin Stone <30794003+Colin-Stone@users.noreply.github.com> --- src/ZoweUSSNode.ts | 8 ++++---- src/api/IZoweTreeNode.ts | 11 +++++------ 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/src/ZoweUSSNode.ts b/src/ZoweUSSNode.ts index 4c232d21c3..6b4a817970 100644 --- a/src/ZoweUSSNode.ts +++ b/src/ZoweUSSNode.ts @@ -115,7 +115,7 @@ export class ZoweUSSNode extends ZoweTreeNode implements IZoweUSSTreeNode { } public getSessionNode(): IZoweUSSTreeNode { - return this.session ? this : this.getParent().getSessionNode(); // as IZoweUSSTreeNode; // TODO BAD + return this.session ? this : this.getParent().getSessionNode(); } /** @@ -257,7 +257,7 @@ export class ZoweUSSNode extends ZoweTreeNode implements IZoweUSSTreeNode { return false; } - public getOpenedDocumentInstance(): vscode.TextDocument { + public get openedDocumentInstance(): vscode.TextDocument { const openedTextDocuments = vscode.workspace.textDocuments; const currentFilePath = this.getUSSDocumentFilePath(); @@ -488,7 +488,7 @@ export class ZoweUSSNode extends ZoweTreeNode implements IZoweUSSTreeNode { if (isDirty) { attachRecentSaveListener(); - vscode.window.showTextDocument(this.getOpenedDocumentInstance()); + vscode.window.showTextDocument(this.openedDocumentInstance); await vscode.commands.executeCommand("workbench.action.closeActiveEditor"); wasSaved = getRecentSaveStatus(); @@ -565,6 +565,6 @@ export class ZoweUSSNode extends ZoweTreeNode implements IZoweUSSTreeNode { * */ public getUSSDocumentFilePath() { - return path.join(extension.USS_DIR, "/" + this.getSessionNode().getProfileName() + "/", this.fullPath); + return path.join(extension.USS_DIR || "", "/" + this.getSessionNode().getProfileName() + "/", this.fullPath); } } diff --git a/src/api/IZoweTreeNode.ts b/src/api/IZoweTreeNode.ts index 538c3c450e..d93f4ddf49 100644 --- a/src/api/IZoweTreeNode.ts +++ b/src/api/IZoweTreeNode.ts @@ -125,7 +125,6 @@ export interface IZoweDatasetTreeNode extends IZoweTreeNode { */ export interface IZoweUSSTreeNode extends IZoweTreeNode { - /** * Retrieves an abridged for of the label */ @@ -171,11 +170,11 @@ export interface IZoweUSSTreeNode extends IZoweTreeNode { * @param binary true is a binary file otherwise false */ setBinary?(binary: boolean); - /** - * Opens the text document - * @return vscode.TextDocument - */ - getOpenedDocumentInstance?(): vscode.TextDocument; + // /** + // * Opens the text document + // * @return vscode.TextDocument + // */ + // getOpenedDocumentInstance?(): vscode.TextDocument; /** * Downloads and displays a file in a text editor view * From f42e69a9998ec273fdc3c04d5ef2501623aef85a Mon Sep 17 00:00:00 2001 From: Colin Stone <30794003+Colin-Stone@users.noreply.github.com> Date: Wed, 5 Feb 2020 12:36:53 +0000 Subject: [PATCH 17/19] Refresh unit tests fixed Signed-off-by: Colin Stone <30794003+Colin-Stone@users.noreply.github.com> --- __tests__/__unit__/extension.unit.test.ts | 220 +++++++++++----------- src/ZoweUSSNode.ts | 9 +- 2 files changed, 112 insertions(+), 117 deletions(-) diff --git a/__tests__/__unit__/extension.unit.test.ts b/__tests__/__unit__/extension.unit.test.ts index 322fa6edc0..2a4fd26ce7 100644 --- a/__tests__/__unit__/extension.unit.test.ts +++ b/__tests__/__unit__/extension.unit.test.ts @@ -2164,116 +2164,116 @@ describe("Extension Unit Tests", () => { }); - // describe("refresh USS checking", () => { - // const isDirtyInEditor = jest.fn(); - // const openedDocumentInstance = jest.fn(); - - // const setMocksForNode = (node: ZoweUSSNode) => { - // Object.defineProperty(node, "isDirtyInEditor", { - // get: isDirtyInEditor - // }); - // Object.defineProperty(node, "openedDocumentInstance", { - // get: openedDocumentInstance - // }); - - // node.contextValue = extension.USS_SESSION_CONTEXT; - // node.fullPath = "/u/myuser"; - // }; - // const resetMocks = () => { - // showErrorMessage.mockReset(); - // showTextDocument.mockReset(); - // ussFile.mockReset(); - // executeCommand.mockReset(); - // isDirtyInEditor.mockReset(); - // openedDocumentInstance.mockReset(); - // }; - - // it("refreshUSS works correctly for dirty file state, when user didn't cancel file save", async () => { - // const node = new ZoweUSSNode("test-node", vscode.TreeItemCollapsibleState.None, ussNode, null, "/"); - - // resetMocks(); - // setMocksForNode(node); - - // const response: brightside.IZosFilesResponse = { - // success: true, - // commandResponse: null, - // apiResponse: { - // etag: "132" - // } - // }; - // ussFile.mockResolvedValue(response); - // isDirtyInEditor.mockReturnValueOnce(true); - // isDirtyInEditor.mockReturnValueOnce(false); - // await node.refreshUSS(); - - // expect(ussFile.mock.calls.length).toBe(1); - // expect(showTextDocument.mock.calls.length).toBe(2); - // expect(executeCommand.mock.calls.length).toBe(1); - // expect(node.downloaded).toBe(true); - // }); - // it("refreshUSS works correctly for dirty file state, when user cancelled file save", async () => { - // const node = new ZoweUSSNode("test-node", vscode.TreeItemCollapsibleState.None, ussNode, null, "/"); - - // resetMocks(); - // setMocksForNode(node); - - // const response: brightside.IZosFilesResponse = { - // success: true, - // commandResponse: null, - // apiResponse: { - // etag: "132" - // } - // }; - // ussFile.mockResolvedValueOnce(response); - // isDirtyInEditor.mockReturnValueOnce(true); - // isDirtyInEditor.mockReturnValueOnce(true); - // await node.refreshUSS(); - - // expect(ussFile.mock.calls.length).toBe(0); - // expect(showTextDocument.mock.calls.length).toBe(1); - // expect(executeCommand.mock.calls.length).toBe(1); - // expect(node.downloaded).toBe(false); - // }); - // it("refreshUSS works correctly for not dirty file state", async () => { - // const node = new ZoweUSSNode("test-node", vscode.TreeItemCollapsibleState.None, ussNode, null, "/"); - - // resetMocks(); - // setMocksForNode(node); - - // const response: brightside.IZosFilesResponse = { - // success: true, - // commandResponse: null, - // apiResponse: { - // etag: "132" - // } - // }; - // ussFile.mockResolvedValueOnce(response); - // isDirtyInEditor.mockReturnValueOnce(false); - // isDirtyInEditor.mockReturnValueOnce(false); - // await node.refreshUSS(); - - // expect(ussFile.mock.calls.length).toBe(1); - // expect(showTextDocument.mock.calls.length).toBe(0); - // expect(executeCommand.mock.calls.length).toBe(0); - // expect(node.downloaded).toBe(true); - // }); - // it("refreshUSS works correctly with exception thrown in process", async () => { - // const node = new ZoweUSSNode("test-node", vscode.TreeItemCollapsibleState.None, ussNode, null, "/"); - - // resetMocks(); - // setMocksForNode(node); - - // ussFile.mockRejectedValueOnce(Error("")); - // isDirtyInEditor.mockReturnValueOnce(true); - // isDirtyInEditor.mockReturnValueOnce(false); - // await node.refreshUSS(); - - // expect(ussFile.mock.calls.length).toBe(1); - // expect(showTextDocument.mock.calls.length).toBe(1); - // expect(executeCommand.mock.calls.length).toBe(1); - // expect(node.downloaded).toBe(false); - // }); - // }); + describe("refresh USS checking", () => { + const isDirtyInEditor = jest.fn(); + const openedDocumentInstance = jest.fn(); + + const setMocksForNode = (node: ZoweUSSNode) => { + Object.defineProperty(node, "isDirtyInEditor", { + get: isDirtyInEditor + }); + Object.defineProperty(node, "openedDocumentInstance", { + get: openedDocumentInstance + }); + + node.contextValue = extension.USS_SESSION_CONTEXT; + node.fullPath = "/u/myuser"; + }; + const resetMocks = () => { + showErrorMessage.mockReset(); + showTextDocument.mockReset(); + ussFile.mockReset(); + executeCommand.mockReset(); + isDirtyInEditor.mockReset(); + openedDocumentInstance.mockReset(); + }; + + it("refreshUSS works correctly for dirty file state, when user didn't cancel file save", async () => { + const node = new ZoweUSSNode("test-node", vscode.TreeItemCollapsibleState.None, ussNode, null, "/"); + + resetMocks(); + setMocksForNode(node); + + const response: brightside.IZosFilesResponse = { + success: true, + commandResponse: null, + apiResponse: { + etag: "132" + } + }; + ussFile.mockResolvedValue(response); + isDirtyInEditor.mockReturnValueOnce(true); + isDirtyInEditor.mockReturnValueOnce(false); + await node.refreshUSS(); + + expect(ussFile.mock.calls.length).toBe(1); + expect(showTextDocument.mock.calls.length).toBe(2); + expect(executeCommand.mock.calls.length).toBe(1); + expect(node.downloaded).toBe(true); + }); + it("refreshUSS works correctly for dirty file state, when user cancelled file save", async () => { + const node = new ZoweUSSNode("test-node", vscode.TreeItemCollapsibleState.None, ussNode, null, "/"); + + resetMocks(); + setMocksForNode(node); + + const response: brightside.IZosFilesResponse = { + success: true, + commandResponse: null, + apiResponse: { + etag: "132" + } + }; + ussFile.mockResolvedValueOnce(response); + isDirtyInEditor.mockReturnValueOnce(true); + isDirtyInEditor.mockReturnValueOnce(true); + await node.refreshUSS(); + + expect(ussFile.mock.calls.length).toBe(0); + expect(showTextDocument.mock.calls.length).toBe(1); + expect(executeCommand.mock.calls.length).toBe(1); + expect(node.downloaded).toBe(false); + }); + it("refreshUSS works correctly for not dirty file state", async () => { + const node = new ZoweUSSNode("test-node", vscode.TreeItemCollapsibleState.None, ussNode, null, "/"); + + resetMocks(); + setMocksForNode(node); + + const response: brightside.IZosFilesResponse = { + success: true, + commandResponse: null, + apiResponse: { + etag: "132" + } + }; + ussFile.mockResolvedValueOnce(response); + isDirtyInEditor.mockReturnValueOnce(false); + isDirtyInEditor.mockReturnValueOnce(false); + await node.refreshUSS(); + + expect(ussFile.mock.calls.length).toBe(1); + expect(showTextDocument.mock.calls.length).toBe(0); + expect(executeCommand.mock.calls.length).toBe(0); + expect(node.downloaded).toBe(true); + }); + it("refreshUSS works correctly with exception thrown in process", async () => { + const node = new ZoweUSSNode("test-node", vscode.TreeItemCollapsibleState.None, ussNode, null, "/"); + + resetMocks(); + setMocksForNode(node); + + ussFile.mockRejectedValueOnce(Error("")); + isDirtyInEditor.mockReturnValueOnce(true); + isDirtyInEditor.mockReturnValueOnce(false); + await node.refreshUSS(); + + expect(ussFile.mock.calls.length).toBe(1); + expect(showTextDocument.mock.calls.length).toBe(1); + expect(executeCommand.mock.calls.length).toBe(1); + expect(node.downloaded).toBe(false); + }); + }); describe("Add USS Session Unit Test", () => { const qpItem: vscode.QuickPickItem = new utils.FilterDescriptor("\uFF0B " + "Create a new filter"); diff --git a/src/ZoweUSSNode.ts b/src/ZoweUSSNode.ts index 6b4a817970..83a0c4fdd1 100644 --- a/src/ZoweUSSNode.ts +++ b/src/ZoweUSSNode.ts @@ -477,11 +477,6 @@ export class ZoweUSSNode extends ZoweTreeNode implements IZoweUSSTreeNode { } try { const ussDocumentFilePath = this.getUSSDocumentFilePath(); - const response1 = await ZoweExplorerApiRegister.getUssApi(this.getProfile()).getContents(this.fullPath, { - file: ussDocumentFilePath, - returnEtag: true - }); - this.setEtag(response1.apiResponse.etag); const isDirty = this.isDirtyInEditor; let wasSaved = false; @@ -496,11 +491,11 @@ export class ZoweUSSNode extends ZoweTreeNode implements IZoweUSSTreeNode { } if ((isDirty && !this.isDirtyInEditor && !wasSaved) || !isDirty) { - const response2 = await ZoweExplorerApiRegister.getUssApi(this.getProfile()).getContents(this.fullPath, { + const response = await ZoweExplorerApiRegister.getUssApi(this.getProfile()).getContents(this.fullPath, { file: ussDocumentFilePath, returnEtag: true }); - this.setEtag(response2.apiResponse.etag); + this.setEtag(response.apiResponse.etag); this.downloaded = true; if (isDirty) { From 0307e47e21564dae2ee49cfac152db7714d54e2b Mon Sep 17 00:00:00 2001 From: Colin Stone <30794003+Colin-Stone@users.noreply.github.com> Date: Thu, 6 Feb 2020 09:17:08 +0000 Subject: [PATCH 18/19] checks for undefined node Signed-off-by: Colin Stone <30794003+Colin-Stone@users.noreply.github.com> --- src/extension.ts | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/extension.ts b/src/extension.ts index df25248649..0710dfff50 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -1781,20 +1781,22 @@ export async function saveFile(doc: vscode.TextDocument, datasetProvider: Datase location: vscode.ProgressLocation.Notification, title: localize("saveFile.response.save.title", "Saving data set...") }, () => { - return ZoweExplorerApiRegister.getMvsApi(node.profile).putContents(doc.fileName, label, uploadOptions); // TODO MISSED TESTING + return ZoweExplorerApiRegister.getMvsApi(node ? node.profile: profile).putContents(doc.fileName, label, uploadOptions); }); if (uploadResponse.success) { vscode.window.showInformationMessage(uploadResponse.commandResponse); // set local etag with the new etag from the updated file on mainframe - node.setEtag(uploadResponse.apiResponse[0].etag); + if (node) { + node.setEtag(uploadResponse.apiResponse[0].etag); + } } else if (!uploadResponse.success && uploadResponse.commandResponse.includes(localize("saveFile.error.ZosmfEtagMismatchError", "Rest API failure with HTTP(S) status 412"))) { - const downloadResponse = await ZoweExplorerApiRegister.getMvsApi(node.profile).getContents(label, { + const downloadResponse = await ZoweExplorerApiRegister.getMvsApi(node ? node.profile: profile).getContents(label, { file: doc.fileName, returnEtag: true }); // re-assign etag, so that it can be used with subsequent requests const downloadEtag = downloadResponse.apiResponse.etag; - if (downloadEtag !== node.getEtag()) { + if (node && downloadEtag !== node.getEtag()) { node.setEtag(downloadEtag); } vscode.window.showWarningMessage(localize("saveFile.error.etagMismatch", "Remote file has been modified in the meantime.\nSelect 'Compare' to resolve the conflict.")); From 6139da6a0ab394d8a88deb65f66380f50bb81c83 Mon Sep 17 00:00:00 2001 From: Colin Stone <30794003+Colin-Stone@users.noreply.github.com> Date: Thu, 6 Feb 2020 15:38:46 +0000 Subject: [PATCH 19/19] Updated to interfaces Signed-off-by: Colin Stone <30794003+Colin-Stone@users.noreply.github.com> --- src/extension.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/extension.ts b/src/extension.ts index cb7c0a9245..1251975651 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -1705,7 +1705,7 @@ export async function saveFile(doc: vscode.TextDocument, datasetProvider: IZoweT location: vscode.ProgressLocation.Notification, title: localize("saveFile.response.save.title", "Saving data set...") }, () => { - return ZoweExplorerApiRegister.getMvsApi(node ? node.profile: profile).putContents(doc.fileName, label, uploadOptions); + return ZoweExplorerApiRegister.getMvsApi(node ? node.getProfile(): profile).putContents(doc.fileName, label, uploadOptions); }); if (uploadResponse.success) { vscode.window.showInformationMessage(uploadResponse.commandResponse); @@ -1714,7 +1714,7 @@ export async function saveFile(doc: vscode.TextDocument, datasetProvider: IZoweT node.setEtag(uploadResponse.apiResponse[0].etag); } } else if (!uploadResponse.success && uploadResponse.commandResponse.includes(localize("saveFile.error.ZosmfEtagMismatchError", "Rest API failure with HTTP(S) status 412"))) { - const downloadResponse = await ZoweExplorerApiRegister.getMvsApi(node ? node.profile: profile).getContents(label, { + const downloadResponse = await ZoweExplorerApiRegister.getMvsApi(node ? node.getProfile(): profile).getContents(label, { file: doc.fileName, returnEtag: true });