From f715818e48fafe5f3bc5fb2937dd42b4b6362164 Mon Sep 17 00:00:00 2001 From: katelynienaber Date: Tue, 4 Feb 2020 15:02:08 +0100 Subject: [PATCH 1/7] Fix issue 485 Signed-off-by: katelynienaber --- .../extension.integration.test.ts | 28 +++++------ __tests__/__unit__/extension.unit.test.ts | 31 +++++++++--- package-lock.json | 49 ++++++------------- src/DatasetTree.ts | 1 + src/USSTree.ts | 1 + src/ZosJobsProvider.ts | 1 + src/extension.ts | 29 ++++++----- 7 files changed, 69 insertions(+), 71 deletions(-) diff --git a/__tests__/__integration__/extension.integration.test.ts b/__tests__/__integration__/extension.integration.test.ts index cd227ee89a..39e7d3c0fb 100644 --- a/__tests__/__integration__/extension.integration.test.ts +++ b/__tests__/__integration__/extension.integration.test.ts @@ -249,13 +249,13 @@ describe("Extension Integration Tests", () => { expect(testTree.mSessionNodes[1].tooltip).to.equal(pattern); expect(testTree.mSessionNodes[1].collapsibleState).to.equal(vscode.TreeItemCollapsibleState.Expanded); - const testTreeView = vscode.window.createTreeView("zowe.explorer", {treeDataProvider: testTree}); + testTree.treeView = vscode.window.createTreeView("zowe.explorer", {treeDataProvider: testTree}); const childrenFromTree = await sessionNode.getChildren(); childrenFromTree.unshift(...(await childrenFromTree[0].getChildren())); - await testTreeView.reveal(childrenFromTree[0]); - expect(childrenFromTree[0]).to.deep.equal(testTreeView.selection[0]); + await testTree.treeView.reveal(childrenFromTree[0]); + expect(childrenFromTree[0]).to.deep.equal(testTree.treeView.selection[0]); }).timeout(TIMEOUT); @@ -270,14 +270,14 @@ describe("Extension Integration Tests", () => { expect(testTree.mSessionNodes[1].tooltip).to.equal(search.toUpperCase()); expect(testTree.mSessionNodes[1].collapsibleState).to.equal(vscode.TreeItemCollapsibleState.Expanded); - const testTreeView = vscode.window.createTreeView("zowe.explorer", {treeDataProvider: testTree}); + testTree.treeView = vscode.window.createTreeView("zowe.explorer", {treeDataProvider: testTree}); const sessionChildren = await sessionNode.getChildren(); const childrenFromTree = await getAllNodes(sessionChildren); for (const child of childrenFromTree) { - await testTreeView.reveal(child); - expect(child).to.deep.equal(testTreeView.selection[0]); + await testTree.treeView.reveal(child); + expect(child).to.deep.equal(testTree.treeView.selection[0]); } }).timeout(TIMEOUT); @@ -302,7 +302,7 @@ describe("Extension Integration Tests", () => { expect(testTree.mSessionNodes[1].tooltip).to.equal(searchPattern.toUpperCase()); expect(testTree.mSessionNodes[1].collapsibleState).to.equal(vscode.TreeItemCollapsibleState.Expanded); - const testTreeView = vscode.window.createTreeView("zowe.explorer", {treeDataProvider: testTree}); + testTree.treeView = vscode.window.createTreeView("zowe.explorer", {treeDataProvider: testTree}); const childrenFromTree = await sessionNode.getChildren(); expect(childrenFromTree[0].children).to.deep.equal([]); @@ -920,17 +920,17 @@ describe("Extension Integration Tests - USS", () => { const ussFileProvider = new USSTree(); // Create the TreeView using ussFileProvider to create tree structure - const ussTestTreeView = vscode.window.createTreeView("zowe.uss.explorer", {treeDataProvider: ussFileProvider}); + ussFileProvider.treeView = vscode.window.createTreeView("zowe.uss.explorer", {treeDataProvider: ussFileProvider}); const nonFavorites = ussFileProvider.mSessionNodes.filter((node) => node.contextValue !== extension.FAVORITE_CONTEXT ); const allNodes = await getAllUSSNodes(nonFavorites); for (const node of allNodes) { // For each node, select that node in TreeView by calling reveal() - await ussTestTreeView.reveal(node); + await ussFileProvider.treeView.reveal(node); // Test that the node is successfully selected - expect(node).to.deep.equal(ussTestTreeView.selection[0]); + expect(node).to.deep.equal(ussFileProvider.treeView.selection[0]); } - ussTestTreeView.dispose(); + ussFileProvider.treeView.dispose(); }).timeout(TIMEOUT); }); @@ -990,14 +990,14 @@ describe("Extension Integration Tests - USS", () => { expect(ussTestTree.mSessionNodes[0].tooltip).to.equal(fullUSSPath); expect(ussTestTree.mSessionNodes[0].collapsibleState).to.equal(vscode.TreeItemCollapsibleState.Expanded); - const ussTestTreeView = vscode.window.createTreeView("zowe.uss.explorer", {treeDataProvider: ussTestTree}); + ussTestTree.treeView = vscode.window.createTreeView("zowe.uss.explorer", {treeDataProvider: ussTestTree}); const childrenFromTree = await ussSessionNode.getChildren(); childrenFromTree.unshift(...(await childrenFromTree[0].getChildren())); for (const child of childrenFromTree) { - await ussTestTreeView.reveal(child); - expect(child).to.deep.equal(ussTestTreeView.selection[0]); + await ussTestTree.treeView.reveal(child); + expect(child).to.deep.equal(ussTestTree.treeView.selection[0]); } }).timeout(TIMEOUT); diff --git a/__tests__/__unit__/extension.unit.test.ts b/__tests__/__unit__/extension.unit.test.ts index fa0ec66d4b..390d3f64ac 100644 --- a/__tests__/__unit__/extension.unit.test.ts +++ b/__tests__/__unit__/extension.unit.test.ts @@ -147,12 +147,14 @@ describe("Extension Unit Tests", () => { const mkdirSync = jest.fn(); const moveSync = jest.fn(); const getAllProfileNames = jest.fn(); - const createTreeView = jest.fn(); - const reveal = jest.fn(); + const mockReveal = jest.fn(); const createWebviewPanel = jest.fn(); + const createTreeView = jest.fn(); const pathMock = jest.fn(); const registerCommand = jest.fn(); const onDidSaveTextDocument = jest.fn(); + const onDidChangeSelection = jest.fn(); + const onDidChangeVisibility = jest.fn(); const onDidCollapseElement = jest.fn(); const onDidExpandElement = jest.fn(); const existsSync = jest.fn(); @@ -268,12 +270,24 @@ describe("Extension Unit Tests", () => { }; }); const CliProfileManager = jest.fn().mockImplementation(() => { - return {getAllProfileNames, load}; + return { getAllProfileNames, load }; + }); + const TreeView = jest.fn().mockImplementation(() => { + return { + reveal: mockReveal, + onDidExpandElement, + onDidCollapseElement, + selection: [], + onDidChangeSelection, + visible: true, + onDidChangeVisibility + }; }); const DatasetTree = jest.fn().mockImplementation(() => { return { mSessionNodes: [], mFavorites: [], + treeView: new TreeView(), addSession: mockAddZoweSession, addHistory: mockAddHistory, getHistory: mockGetHistory, @@ -328,7 +342,6 @@ describe("Extension Unit Tests", () => { testTree.mSessionNodes.push(sessNode); Object.defineProperty(testTree, "onDidExpandElement", {value: jest.fn()}); Object.defineProperty(testTree, "onDidCollapseElement", {value: jest.fn()}); - Object.defineProperty(testTree, "reveal", {value: jest.fn()}); Object.defineProperty(vscode.window, "createQuickPick", {value: createQuickPick}); const testUSSTree = USSTree(); @@ -362,7 +375,6 @@ describe("Extension Unit Tests", () => { Object.defineProperty(vscode.workspace, "onDidSaveTextDocument", {value: onDidSaveTextDocument}); Object.defineProperty(vscode.window, "onDidCollapseElement", {value: onDidCollapseElement}); Object.defineProperty(vscode.window, "onDidExpandElement", {value: onDidExpandElement}); - Object.defineProperty(vscode.window, "reveal", {value: reveal}); Object.defineProperty(vscode.workspace, "getConfiguration", {value: getConfiguration}); Object.defineProperty(vscode.workspace, "onDidChangeConfiguration", {value: onDidChangeConfiguration}); Object.defineProperty(fs, "readdirSync", {value: readdirSync}); @@ -459,7 +471,7 @@ describe("Extension Unit Tests", () => { }); it("Testing that activate correctly executes", async () => { - createTreeView.mockReturnValue(testTree); + createTreeView.mockReturnValue(new TreeView()); existsSync.mockReturnValueOnce(true); existsSync.mockReturnValueOnce(true); @@ -1194,6 +1206,7 @@ describe("Extension Unit Tests", () => { mockGetHistory.mockReset(); getConfiguration.mockReturnValue("FakeConfig"); + createTreeView.mockReturnValue(new TreeView()); showInputBox.mockReturnValue("node"); allMembers.mockReturnValue(uploadResponse); dataSetList.mockReturnValue(uploadResponse); @@ -1257,14 +1270,14 @@ describe("Extension Unit Tests", () => { expect(showErrorMessage.mock.calls.length).toBe(0); mockGetHistory.mockReset(); - testTree.reveal.mockReset(); + testTree.treeView.reveal.mockReset(); // Testing the addition of new node to tree view mockGetHistory.mockReturnValueOnce(["NODE1"]); showQuickPick.mockResolvedValueOnce("Data Set Sequential"); await extension.createFile(sessNode2, testTree); expect(testTree.addHistory).toHaveBeenCalledWith("NODE1,NODE.*"); - expect(testTree.reveal.mock.calls.length).toBe(1); + expect(testTree.treeView.reveal.mock.calls.length).toBe(1); testTree.addHistory.mockReset(); @@ -1326,6 +1339,7 @@ describe("Extension Unit Tests", () => { allMembers.mockReset(); getConfiguration.mockReturnValue("FakeConfig"); + createTreeView.mockReturnValue(new TreeView()); showInputBox.mockReturnValue("FakeName"); mockGetHistory.mockReturnValue(["mockHistory"]); dataSetList.mockReturnValue(uploadResponse); @@ -1409,6 +1423,7 @@ describe("Extension Unit Tests", () => { getConfiguration.mockReturnValue("FakeConfig"); showInputBox.mockReturnValue("FakeName"); + createTreeView.mockReturnValue(new TreeView()); testTree.getChildren.mockReturnValue([new ZoweNode("node", vscode.TreeItemCollapsibleState.None, sessNode, null, undefined, undefined, profileOne), sessNode]); allMembers.mockReturnValue(uploadResponse); diff --git a/package-lock.json b/package-lock.json index e32611c4e6..c882ce3af2 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": { @@ -869,9 +869,9 @@ } }, "arg": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.2.tgz", - "integrity": "sha512-+ytCkGcBtHZ3V2r2Z06AncYO8jz46UEamcspGoU8lHcEbpn6J77QK0vdWvChsclg/tM5XIJC5tnjmPp7Eq6Obg==", + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", "dev": true }, "argparse": { @@ -2956,8 +2956,7 @@ "ansi-regex": { "version": "2.1.1", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "aproba": { "version": "1.2.0", @@ -2978,14 +2977,12 @@ "balanced-match": { "version": "1.0.0", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "brace-expansion": { "version": "1.1.11", "bundled": true, "dev": true, - "optional": true, "requires": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -3000,20 +2997,17 @@ "code-point-at": { "version": "1.1.0", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "concat-map": { "version": "0.0.1", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "console-control-strings": { "version": "1.1.0", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "core-util-is": { "version": "1.0.2", @@ -3130,8 +3124,7 @@ "inherits": { "version": "2.0.4", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "ini": { "version": "1.3.5", @@ -3143,7 +3136,6 @@ "version": "1.0.0", "bundled": true, "dev": true, - "optional": true, "requires": { "number-is-nan": "^1.0.0" } @@ -3158,7 +3150,6 @@ "version": "3.0.4", "bundled": true, "dev": true, - "optional": true, "requires": { "brace-expansion": "^1.1.7" } @@ -3166,14 +3157,12 @@ "minimist": { "version": "0.0.8", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "minipass": { "version": "2.9.0", "bundled": true, "dev": true, - "optional": true, "requires": { "safe-buffer": "^5.1.2", "yallist": "^3.0.0" @@ -3192,7 +3181,6 @@ "version": "0.5.1", "bundled": true, "dev": true, - "optional": true, "requires": { "minimist": "0.0.8" } @@ -3282,8 +3270,7 @@ "number-is-nan": { "version": "1.0.1", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "object-assign": { "version": "4.1.1", @@ -3295,7 +3282,6 @@ "version": "1.4.0", "bundled": true, "dev": true, - "optional": true, "requires": { "wrappy": "1" } @@ -3381,8 +3367,7 @@ "safe-buffer": { "version": "5.1.2", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "safer-buffer": { "version": "2.1.2", @@ -3418,7 +3403,6 @@ "version": "1.0.2", "bundled": true, "dev": true, - "optional": true, "requires": { "code-point-at": "^1.0.0", "is-fullwidth-code-point": "^1.0.0", @@ -3438,7 +3422,6 @@ "version": "3.0.1", "bundled": true, "dev": true, - "optional": true, "requires": { "ansi-regex": "^2.0.0" } @@ -3482,14 +3465,12 @@ "wrappy": { "version": "1.0.2", "bundled": true, - "dev": true, - "optional": true + "dev": true }, "yallist": { "version": "3.1.1", "bundled": true, - "dev": true, - "optional": true + "dev": true } } }, diff --git a/src/DatasetTree.ts b/src/DatasetTree.ts index 5be223c295..77268b9bbd 100644 --- a/src/DatasetTree.ts +++ b/src/DatasetTree.ts @@ -53,6 +53,7 @@ export class DatasetTree implements IZoweTree { // 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 treeView: vscode.TreeView; private mHistory: PersistentFilters; private log: Logger; private validProfile: number = -1; diff --git a/src/USSTree.ts b/src/USSTree.ts index 682305b249..724cece4a9 100644 --- a/src/USSTree.ts +++ b/src/USSTree.ts @@ -52,6 +52,7 @@ export class USSTree implements IZoweTree { // 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 treeView: vscode.TreeView; private mHistory: PersistentFilters; private log: Logger; diff --git a/src/ZosJobsProvider.ts b/src/ZosJobsProvider.ts index 8644863063..126bd67cbe 100644 --- a/src/ZosJobsProvider.ts +++ b/src/ZosJobsProvider.ts @@ -66,6 +66,7 @@ export class ZosJobsProvider implements IZoweTree { public readonly onDidChangeTreeData: vscode.Event = this.mOnDidChangeTreeData.event; public createOwner = new OwnerFilterDescriptor(); public createId = new JobIdFilterDescriptor(); + public treeView: vscode.TreeView; private validProfile: number = -1; private mHistory: PersistentFilters; diff --git a/src/extension.ts b/src/extension.ts index df25248649..3260106bb1 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -228,13 +228,13 @@ export async function activate(context: vscode.ExtensionContext): Promise { + datasetProvider.treeView.onDidCollapseElement(async (e) => { datasetProvider.flipState(e.element, false); }); - databaseView.onDidExpandElement(async (e) => { + datasetProvider.treeView.onDidExpandElement(async (e) => { datasetProvider.flipState(e.element, true); }); } @@ -266,13 +266,13 @@ export async function activate(context: vscode.ExtensionContext): Promise { ussFileProvider.onDidChangeConfiguration(e); }); - const ussView = vscode.window.createTreeView("zowe.uss.explorer", {treeDataProvider: ussFileProvider}); - context.subscriptions.push(ussView); + ussFileProvider.treeView = vscode.window.createTreeView("zowe.uss.explorer", {treeDataProvider: ussFileProvider}); + context.subscriptions.push(ussFileProvider.treeView); if (!ISTHEIA) { - ussView.onDidCollapseElement(async (e) => { + ussFileProvider.treeView.onDidCollapseElement(async (e) => { ussFileProvider.flipState(e.element, false); }); - ussView.onDidExpandElement(async (e) => { + ussFileProvider.treeView.onDidExpandElement(async (e) => { ussFileProvider.flipState(e.element, true); }); } @@ -321,7 +321,7 @@ export async function activate(context: vscode.ExtensionContext): Promise { return jobNode.job.jobid === jobid; }); - jobsProvider.setJob(jobView, job); + jobsProvider.setJob(jobsProvider.treeView, job); }); vscode.commands.registerCommand("zowe.jobs.search", (node) => jobsProvider.searchPrompt(node)); vscode.commands.registerCommand("zowe.issueTsoCmd", async () => MvsCommandHandler.getInstance().issueMvsCommand()); @@ -334,13 +334,13 @@ export async function activate(context: vscode.ExtensionContext): Promise jobsProvider.removeJobsFavorite(node)); vscode.commands.registerCommand("zowe.jobs.saveSearch", async (node) => jobsProvider.saveSearch(node)); vscode.commands.registerCommand("zowe.jobs.removeSearchFavorite", async (node) => jobsProvider.removeJobsFavorite(node)); - const jobView = vscode.window.createTreeView("zowe.jobs", {treeDataProvider: jobsProvider}); - context.subscriptions.push(jobView); + jobsProvider.treeView = vscode.window.createTreeView("zowe.jobs", {treeDataProvider: jobsProvider}); + context.subscriptions.push(jobsProvider.treeView); if (!ISTHEIA) { - jobView.onDidCollapseElement(async (e: { element: Job; }) => { + jobsProvider.treeView.onDidCollapseElement(async (e: { element: Job; }) => { jobsProvider.flipState(e.element, false); }); - jobView.onDidExpandElement(async (e: { element: Job; }) => { + jobsProvider.treeView.onDidExpandElement(async (e: { element: Job; }) => { jobsProvider.flipState(e.element, true); }); } @@ -874,8 +874,7 @@ export async function createFile(node: ZoweNode, datasetProvider: DatasetTree) { node.dirty = true; const newNode = await node.getChildren().then((children) => children.find((child) => child.label === name)); - const newNodeView = vscode.window.createTreeView("zowe.explorer", {treeDataProvider: datasetProvider}); - newNodeView.reveal(newNode, {select: true}); + datasetProvider.treeView.reveal(newNode, {select: true}); } } catch (err) { log.error(localize("createDataSet.error", "Error encountered when creating data set! ") + JSON.stringify(err)); From fd59146365834dd51db9da415ae4c7422be40748 Mon Sep 17 00:00:00 2001 From: katelynienaber Date: Tue, 4 Feb 2020 16:12:46 +0100 Subject: [PATCH 2/7] Fixing integration test Signed-off-by: katelynienaber --- __tests__/__integration__/extension.integration.test.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/__tests__/__integration__/extension.integration.test.ts b/__tests__/__integration__/extension.integration.test.ts index 39e7d3c0fb..ea4b37f28e 100644 --- a/__tests__/__integration__/extension.integration.test.ts +++ b/__tests__/__integration__/extension.integration.test.ts @@ -51,6 +51,7 @@ describe("Extension Integration Tests", () => { const pattern = testConst.normalPattern.toUpperCase(); sessionNode.pattern = pattern; const testTree = new DatasetTree(); + testTree.treeView = vscode.window.createTreeView("zowe.explorer", {treeDataProvider: testTree}); testTree.mSessionNodes.push(sessionNode); let sandbox; From 1f16bbd50af43f01960e0c5df3246e1e894bcc16 Mon Sep 17 00:00:00 2001 From: katelynienaber Date: Wed, 5 Feb 2020 13:23:05 +0100 Subject: [PATCH 3/7] Created function to access TreeView in class Signed-off-by: katelynienaber --- .../extension.integration.test.ts | 13 +++------ __tests__/__unit__/DatasetTree.unit.test.ts | 4 +++ __tests__/__unit__/USSTree.unit.test.ts | 4 +++ __tests__/__unit__/ZoweJobNode.unit.test.ts | 7 +++++ __tests__/__unit__/extension.unit.test.ts | 10 +++++++ src/DatasetTree.ts | 12 +++++++- src/USSTree.ts | 12 +++++++- src/ZosJobsProvider.ts | 13 ++++++++- src/extension.ts | 28 +++++++++---------- 9 files changed, 77 insertions(+), 26 deletions(-) diff --git a/__tests__/__integration__/extension.integration.test.ts b/__tests__/__integration__/extension.integration.test.ts index ea4b37f28e..a258f7b61d 100644 --- a/__tests__/__integration__/extension.integration.test.ts +++ b/__tests__/__integration__/extension.integration.test.ts @@ -51,7 +51,6 @@ describe("Extension Integration Tests", () => { const pattern = testConst.normalPattern.toUpperCase(); sessionNode.pattern = pattern; const testTree = new DatasetTree(); - testTree.treeView = vscode.window.createTreeView("zowe.explorer", {treeDataProvider: testTree}); testTree.mSessionNodes.push(sessionNode); let sandbox; @@ -250,13 +249,12 @@ describe("Extension Integration Tests", () => { expect(testTree.mSessionNodes[1].tooltip).to.equal(pattern); expect(testTree.mSessionNodes[1].collapsibleState).to.equal(vscode.TreeItemCollapsibleState.Expanded); - testTree.treeView = vscode.window.createTreeView("zowe.explorer", {treeDataProvider: testTree}); const childrenFromTree = await sessionNode.getChildren(); childrenFromTree.unshift(...(await childrenFromTree[0].getChildren())); - await testTree.treeView.reveal(childrenFromTree[0]); - expect(childrenFromTree[0]).to.deep.equal(testTree.treeView.selection[0]); + await testTree.getTreeView().reveal(childrenFromTree[0]); + expect(childrenFromTree[0]).to.deep.equal(testTree.getTreeView().selection[0]); }).timeout(TIMEOUT); @@ -271,14 +269,13 @@ describe("Extension Integration Tests", () => { expect(testTree.mSessionNodes[1].tooltip).to.equal(search.toUpperCase()); expect(testTree.mSessionNodes[1].collapsibleState).to.equal(vscode.TreeItemCollapsibleState.Expanded); - testTree.treeView = vscode.window.createTreeView("zowe.explorer", {treeDataProvider: testTree}); const sessionChildren = await sessionNode.getChildren(); const childrenFromTree = await getAllNodes(sessionChildren); for (const child of childrenFromTree) { - await testTree.treeView.reveal(child); - expect(child).to.deep.equal(testTree.treeView.selection[0]); + await testTree.getTreeView().reveal(child); + expect(child).to.deep.equal(testTree.getTreeView().selection[0]); } }).timeout(TIMEOUT); @@ -303,8 +300,6 @@ describe("Extension Integration Tests", () => { expect(testTree.mSessionNodes[1].tooltip).to.equal(searchPattern.toUpperCase()); expect(testTree.mSessionNodes[1].collapsibleState).to.equal(vscode.TreeItemCollapsibleState.Expanded); - testTree.treeView = vscode.window.createTreeView("zowe.explorer", {treeDataProvider: testTree}); - const childrenFromTree = await sessionNode.getChildren(); expect(childrenFromTree[0].children).to.deep.equal([]); diff --git a/__tests__/__unit__/DatasetTree.unit.test.ts b/__tests__/__unit__/DatasetTree.unit.test.ts index d1d849fb58..e2fd9400eb 100644 --- a/__tests__/__unit__/DatasetTree.unit.test.ts +++ b/__tests__/__unit__/DatasetTree.unit.test.ts @@ -45,6 +45,7 @@ describe("DatasetTree Unit Tests", () => { const filters = jest.fn(); const getFilters = jest.fn(); const createQuickPick = jest.fn(); + const createTreeView = jest.fn(); const createBasicZosmfSession = jest.fn(); const ZosmfSession = jest.fn(); Object.defineProperty(zowe, "ZosmfSession", { value: ZosmfSession }); @@ -71,11 +72,13 @@ describe("DatasetTree Unit Tests", () => { Object.defineProperty(vscode.window, "showErrorMessage", {value: showErrorMessage}); Object.defineProperty(vscode.window, "showQuickPick", {value: showQuickPick}); Object.defineProperty(vscode.window, "showInputBox", {value: showInputBox}); + Object.defineProperty(vscode.window, "createTreeView", {value: createTreeView}); Object.defineProperty(filters, "getFilters", { value: getFilters }); Object.defineProperty(vscode.window, "createQuickPick", {value: createQuickPick}); Object.defineProperty(vscode, "ProgressLocation", {value: ProgressLocation}); Object.defineProperty(vscode.window, "withProgress", {value: withProgress}); getFilters.mockReturnValue(["HLQ", "HLQ.PROD1"]); + createTreeView.mockReturnValue("testTreeView"); const getConfiguration = jest.fn(); Object.defineProperty(vscode.workspace, "getConfiguration", { value: getConfiguration }); getConfiguration.mockReturnValue({ @@ -140,6 +143,7 @@ describe("DatasetTree Unit Tests", () => { *************************************************************************************************************/ it("Testing that the dataset tree is defined", async () => { expect(testTree.mSessionNodes).toBeDefined(); + expect(testTree.getTreeView()).toEqual("testTreeView"); }); /************************************************************************************************************* diff --git a/__tests__/__unit__/USSTree.unit.test.ts b/__tests__/__unit__/USSTree.unit.test.ts index 0bd7c9b79c..0a64ccf461 100644 --- a/__tests__/__unit__/USSTree.unit.test.ts +++ b/__tests__/__unit__/USSTree.unit.test.ts @@ -69,6 +69,7 @@ describe("Unit Tests (Jest)", () => { const showInformationMessage = jest.fn(); const showInputBox = jest.fn(); const createQuickPick = jest.fn(); + const createTreeView = jest.fn(); const showQuickPick = jest.fn(); const filters = jest.fn(); const getFilters = jest.fn(); @@ -79,7 +80,9 @@ describe("Unit Tests (Jest)", () => { Object.defineProperty(filters, "getFilters", { value: getFilters }); Object.defineProperty(vscode, "ProgressLocation", {value: ProgressLocation}); Object.defineProperty(vscode.window, "withProgress", {value: withProgress}); + Object.defineProperty(vscode.window, "createTreeView", {value: createTreeView}); getFilters.mockReturnValue(["/u/aDir{directory}", "/u/myFile.txt{textFile}"]); + createTreeView.mockReturnValue("testTreeView"); const testTree = new USSTree(); const profileOne: IProfileLoaded = { @@ -142,6 +145,7 @@ describe("Unit Tests (Jest)", () => { *************************************************************************************************************/ it("Testing that the uss tree is defined", async () => { expect(testTree.mSessionNodes).toBeDefined(); + expect(testTree.getTreeView()).toEqual("testTreeView"); }); /************************************************************************************************************* diff --git a/__tests__/__unit__/ZoweJobNode.unit.test.ts b/__tests__/__unit__/ZoweJobNode.unit.test.ts index 4150abd2b7..fc2ceeb834 100644 --- a/__tests__/__unit__/ZoweJobNode.unit.test.ts +++ b/__tests__/__unit__/ZoweJobNode.unit.test.ts @@ -26,8 +26,10 @@ describe("Zos Jobs Unit Tests", () => { const GetJobs = jest.fn(); const getConfiguration = jest.fn(); const showErrorMessage = jest.fn(); + const createTreeView = jest.fn(); Object.defineProperty(vscode.workspace, "getConfiguration", { value: getConfiguration }); Object.defineProperty(vscode.window, "showErrorMessage", {value: showErrorMessage}); + Object.defineProperty(vscode.window, "createTreeView", {value: createTreeView}); getConfiguration.mockReturnValue({ get: (setting: string) => [ "[test]: Owner:stonecc Prefix:*{server}", @@ -37,6 +39,7 @@ describe("Zos Jobs Unit Tests", () => { return {}; }) }); + createTreeView.mockReturnValue("testTreeView"); const enums = jest.fn().mockImplementation(() => { return { @@ -232,6 +235,10 @@ describe("Zos Jobs Unit Tests", () => { expect(testJobsProvider.mSessionNodes[sessions].tooltip).toEqual("fake - owner: prefix: *"); }); + it("tests that the TreeView is created successfully", async () => { + const testJobsProvider = await createJobsTree(Logger.getAppLogger()); + }); + it("tests that the user is informed when a job is deleted", async () => { showInformationMessage.mockReset(); const testJobsProvider = await createJobsTree(Logger.getAppLogger()); diff --git a/__tests__/__unit__/extension.unit.test.ts b/__tests__/__unit__/extension.unit.test.ts index 390d3f64ac..9823b3555c 100644 --- a/__tests__/__unit__/extension.unit.test.ts +++ b/__tests__/__unit__/extension.unit.test.ts @@ -214,6 +214,7 @@ describe("Extension Unit Tests", () => { const isFile = jest.fn(); const load = jest.fn(); const GetJobs = jest.fn(); + const getTreeView = jest.fn(); const getSpoolContentById = jest.fn(); const getJclForJob = jest.fn(); const DownloadJobs = jest.fn(); @@ -294,6 +295,7 @@ describe("Extension Unit Tests", () => { refresh: mockRefresh, refreshElement: mockRefreshElement, getChildren: mockGetChildren, + getTreeView, removeFavorite: mockRemoveFavorite, enterPattern: mockPattern, initializeFavorites: mockInitialize, @@ -312,6 +314,8 @@ describe("Extension Unit Tests", () => { refresh: mockUSSRefresh, addHistory: mockAddHistory, getHistory: mockGetHistory, + getTreeView, + treeView: new TreeView(), refreshElement: mockUSSRefreshElement, getChildren: mockGetUSSChildren, initializeUSSFavorites: mockInitializeUSS, @@ -324,6 +328,8 @@ describe("Extension Unit Tests", () => { getChildren: jest.fn(), addSession: jest.fn(), refresh: jest.fn(), + getTreeView, + treeView: new TreeView(), refreshElement: jest.fn(), getProfileName: jest.fn() }; @@ -1211,6 +1217,7 @@ describe("Extension Unit Tests", () => { allMembers.mockReturnValue(uploadResponse); dataSetList.mockReturnValue(uploadResponse); mockGetHistory.mockReturnValue([]); + testTree.getTreeView.mockReturnValue(new TreeView()); showQuickPick.mockResolvedValueOnce("Data Set Binary"); await extension.createFile(sessNode2, testTree); @@ -1344,6 +1351,7 @@ describe("Extension Unit Tests", () => { mockGetHistory.mockReturnValue(["mockHistory"]); dataSetList.mockReturnValue(uploadResponse); allMembers.mockReturnValue(uploadResponse); + testTree.getTreeView.mockReturnValue(new TreeView()); showQuickPick.mockResolvedValueOnce("Data Set Binary"); await extension.createFile(newsessNode, testTree); @@ -1429,6 +1437,7 @@ describe("Extension Unit Tests", () => { allMembers.mockReturnValue(uploadResponse); dataSet.mockReturnValue(uploadResponse); mockGetHistory.mockReturnValue(["mockHistory1"]); + testTree.getTreeView.mockReturnValue(new TreeView()); showQuickPick.mockResolvedValueOnce("Data Set Binary"); await extension.createFile(newsessNode, testTree); @@ -1508,6 +1517,7 @@ describe("Extension Unit Tests", () => { mockGetHistory.mockReturnValueOnce(["mockHistory"]); allMembers.mockReturnValueOnce(uploadResponse); dataSetList.mockReturnValue(uploadResponse); + testTree.getTreeView.mockReturnValue(new TreeView()); showQuickPick.mockResolvedValueOnce("Data Set Binary"); await extension.createFile(newsessNode, testTree); diff --git a/src/DatasetTree.ts b/src/DatasetTree.ts index 77268b9bbd..b53ddabe5c 100644 --- a/src/DatasetTree.ts +++ b/src/DatasetTree.ts @@ -53,7 +53,7 @@ export class DatasetTree implements IZoweTree { // 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 treeView: vscode.TreeView; + private treeView: vscode.TreeView; private mHistory: PersistentFilters; private log: Logger; private validProfile: number = -1; @@ -64,6 +64,7 @@ export class DatasetTree implements IZoweTree { this.mFavoriteSession.iconPath = applyIcons(this.mFavoriteSession); this.mSessionNodes = [this.mFavoriteSession]; this.mHistory = new PersistentFilters(DatasetTree.persistenceSchema); + this.treeView = vscode.window.createTreeView("zowe.explorer", {treeDataProvider: this}); } /** @@ -151,6 +152,15 @@ export class DatasetTree implements IZoweTree { return element; } + /** + * Returns the tree view for the current DatasetTree + * + * @returns {vscode.TreeView} + */ + public getTreeView(): vscode.TreeView { + return this.treeView; + } + /** * Takes argument of type ZoweNode and retrieves all of the first level children * diff --git a/src/USSTree.ts b/src/USSTree.ts index 724cece4a9..17fa747a3d 100644 --- a/src/USSTree.ts +++ b/src/USSTree.ts @@ -52,7 +52,7 @@ export class USSTree implements IZoweTree { // 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 treeView: vscode.TreeView; + private treeView: vscode.TreeView; private mHistory: PersistentFilters; private log: Logger; @@ -66,6 +66,7 @@ export class USSTree implements IZoweTree { this.mSessionNodes = [this.mFavoriteSession]; this.mFavoriteSession.iconPath = applyIcons(this.mFavoriteSession); this.mHistory = new PersistentFilters(USSTree.persistenceSchema); + this.treeView = vscode.window.createTreeView("zowe.uss.explorer", {treeDataProvider: this}); } /** @@ -78,6 +79,15 @@ export class USSTree implements IZoweTree { return element; } + /** + * Returns the tree view for the current USSTree + * + * @returns {vscode.TreeView} + */ + public getTreeView(): vscode.TreeView { + return this.treeView; + } + /** * Takes argument of type ZoweUSSNode and retrieves all of the first level children * diff --git a/src/ZosJobsProvider.ts b/src/ZosJobsProvider.ts index 126bd67cbe..53f58c5715 100644 --- a/src/ZosJobsProvider.ts +++ b/src/ZosJobsProvider.ts @@ -66,7 +66,7 @@ export class ZosJobsProvider implements IZoweTree { public readonly onDidChangeTreeData: vscode.Event = this.mOnDidChangeTreeData.event; public createOwner = new OwnerFilterDescriptor(); public createId = new JobIdFilterDescriptor(); - public treeView: vscode.TreeView; + private treeView: vscode.TreeView; private validProfile: number = -1; private mHistory: PersistentFilters; @@ -78,6 +78,7 @@ export class ZosJobsProvider implements IZoweTree { this.mFavoriteSession.iconPath = applyIcons(this.mFavoriteSession); this.mSessionNodes = [this.mFavoriteSession]; this.mHistory = new PersistentFilters(ZosJobsProvider.persistenceSchema); + this.treeView = vscode.window.createTreeView("zowe.jobs", {treeDataProvider: this}); } public getChildren(element?: Job | undefined): vscode.ProviderResult { @@ -97,6 +98,16 @@ export class ZosJobsProvider implements IZoweTree { public getTreeItem(element: Job): vscode.TreeItem | Thenable { return element; } + + /** + * Returns the tree view for the current JobTree + * + * @returns {vscode.TreeView} + */ + public getTreeView(): vscode.TreeView { + return this.treeView; + } + public getParent(element: Job): Job { return element.mParent; } diff --git a/src/extension.ts b/src/extension.ts index 3260106bb1..9ac77d07f7 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -228,13 +228,13 @@ export async function activate(context: vscode.ExtensionContext): Promise { + theTreeView.onDidCollapseElement(async (e) => { datasetProvider.flipState(e.element, false); }); - datasetProvider.treeView.onDidExpandElement(async (e) => { + theTreeView.onDidExpandElement(async (e) => { datasetProvider.flipState(e.element, true); }); } @@ -266,13 +266,13 @@ export async function activate(context: vscode.ExtensionContext): Promise { ussFileProvider.onDidChangeConfiguration(e); }); - ussFileProvider.treeView = vscode.window.createTreeView("zowe.uss.explorer", {treeDataProvider: ussFileProvider}); - context.subscriptions.push(ussFileProvider.treeView); + const theTreeView = ussFileProvider.getTreeView(); + context.subscriptions.push(theTreeView); if (!ISTHEIA) { - ussFileProvider.treeView.onDidCollapseElement(async (e) => { + theTreeView.onDidCollapseElement(async (e) => { ussFileProvider.flipState(e.element, false); }); - ussFileProvider.treeView.onDidExpandElement(async (e) => { + theTreeView.onDidExpandElement(async (e) => { ussFileProvider.flipState(e.element, true); }); } @@ -321,7 +321,7 @@ export async function activate(context: vscode.ExtensionContext): Promise { return jobNode.job.jobid === jobid; }); - jobsProvider.setJob(jobsProvider.treeView, job); + jobsProvider.setJob(jobsProvider.getTreeView(), job); }); vscode.commands.registerCommand("zowe.jobs.search", (node) => jobsProvider.searchPrompt(node)); vscode.commands.registerCommand("zowe.issueTsoCmd", async () => MvsCommandHandler.getInstance().issueMvsCommand()); @@ -334,13 +334,13 @@ export async function activate(context: vscode.ExtensionContext): Promise jobsProvider.removeJobsFavorite(node)); vscode.commands.registerCommand("zowe.jobs.saveSearch", async (node) => jobsProvider.saveSearch(node)); vscode.commands.registerCommand("zowe.jobs.removeSearchFavorite", async (node) => jobsProvider.removeJobsFavorite(node)); - jobsProvider.treeView = vscode.window.createTreeView("zowe.jobs", {treeDataProvider: jobsProvider}); - context.subscriptions.push(jobsProvider.treeView); + const theTreeView = jobsProvider.getTreeView(); + context.subscriptions.push(theTreeView); if (!ISTHEIA) { - jobsProvider.treeView.onDidCollapseElement(async (e: { element: Job; }) => { + theTreeView.onDidCollapseElement(async (e: { element: Job; }) => { jobsProvider.flipState(e.element, false); }); - jobsProvider.treeView.onDidExpandElement(async (e: { element: Job; }) => { + theTreeView.onDidExpandElement(async (e: { element: Job; }) => { jobsProvider.flipState(e.element, true); }); } @@ -874,7 +874,7 @@ export async function createFile(node: ZoweNode, datasetProvider: DatasetTree) { node.dirty = true; const newNode = await node.getChildren().then((children) => children.find((child) => child.label === name)); - datasetProvider.treeView.reveal(newNode, {select: true}); + datasetProvider.getTreeView().reveal(newNode, {select: true}); } } catch (err) { log.error(localize("createDataSet.error", "Error encountered when creating data set! ") + JSON.stringify(err)); From 1260a86aed993cfdfb29a6406303f68b4c91b3b6 Mon Sep 17 00:00:00 2001 From: katelynienaber Date: Wed, 5 Feb 2020 13:46:47 +0100 Subject: [PATCH 4/7] Fixing integration tests Signed-off-by: katelynienaber --- .../__integration__/extension.integration.test.ts | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/__tests__/__integration__/extension.integration.test.ts b/__tests__/__integration__/extension.integration.test.ts index a258f7b61d..43ffe1ae50 100644 --- a/__tests__/__integration__/extension.integration.test.ts +++ b/__tests__/__integration__/extension.integration.test.ts @@ -915,18 +915,15 @@ describe("Extension Integration Tests - USS", () => { // Initialize uss file provider const ussFileProvider = new USSTree(); - // Create the TreeView using ussFileProvider to create tree structure - ussFileProvider.treeView = vscode.window.createTreeView("zowe.uss.explorer", {treeDataProvider: ussFileProvider}); - const nonFavorites = ussFileProvider.mSessionNodes.filter((node) => node.contextValue !== extension.FAVORITE_CONTEXT ); const allNodes = await getAllUSSNodes(nonFavorites); for (const node of allNodes) { // For each node, select that node in TreeView by calling reveal() - await ussFileProvider.treeView.reveal(node); + await ussFileProvider.getTreeView().reveal(node); // Test that the node is successfully selected - expect(node).to.deep.equal(ussFileProvider.treeView.selection[0]); + expect(node).to.deep.equal(ussFileProvider.getTreeView().selection[0]); } - ussFileProvider.treeView.dispose(); + ussFileProvider.getTreeView().dispose(); }).timeout(TIMEOUT); }); @@ -986,14 +983,12 @@ describe("Extension Integration Tests - USS", () => { expect(ussTestTree.mSessionNodes[0].tooltip).to.equal(fullUSSPath); expect(ussTestTree.mSessionNodes[0].collapsibleState).to.equal(vscode.TreeItemCollapsibleState.Expanded); - ussTestTree.treeView = vscode.window.createTreeView("zowe.uss.explorer", {treeDataProvider: ussTestTree}); - const childrenFromTree = await ussSessionNode.getChildren(); childrenFromTree.unshift(...(await childrenFromTree[0].getChildren())); for (const child of childrenFromTree) { - await ussTestTree.treeView.reveal(child); - expect(child).to.deep.equal(ussTestTree.treeView.selection[0]); + await ussTestTree.getTreeView().reveal(child); + expect(child).to.deep.equal(ussTestTree.getTreeView().selection[0]); } }).timeout(TIMEOUT); From cabf9c93a9008c4b8200f56442f5aeb0430d5852 Mon Sep 17 00:00:00 2001 From: katelynienaber Date: Thu, 6 Feb 2020 10:38:18 +0100 Subject: [PATCH 5/7] Added setter for TreeView to fix integration tests Signed-off-by: katelynienaber --- .../extension.integration.test.ts | 19 ++++++++++++------- src/DatasetTree.ts | 9 +++++++++ src/USSTree.ts | 9 +++++++++ src/ZosJobsProvider.ts | 9 +++++++++ 4 files changed, 39 insertions(+), 7 deletions(-) diff --git a/__tests__/__integration__/extension.integration.test.ts b/__tests__/__integration__/extension.integration.test.ts index 43ffe1ae50..7d0569dc71 100644 --- a/__tests__/__integration__/extension.integration.test.ts +++ b/__tests__/__integration__/extension.integration.test.ts @@ -249,6 +249,8 @@ describe("Extension Integration Tests", () => { expect(testTree.mSessionNodes[1].tooltip).to.equal(pattern); expect(testTree.mSessionNodes[1].collapsibleState).to.equal(vscode.TreeItemCollapsibleState.Expanded); + const newView = vscode.window.createTreeView("zowe.explorer", {treeDataProvider: testTree}); + testTree.setTreeView(newView); const childrenFromTree = await sessionNode.getChildren(); childrenFromTree.unshift(...(await childrenFromTree[0].getChildren())); @@ -269,7 +271,6 @@ describe("Extension Integration Tests", () => { expect(testTree.mSessionNodes[1].tooltip).to.equal(search.toUpperCase()); expect(testTree.mSessionNodes[1].collapsibleState).to.equal(vscode.TreeItemCollapsibleState.Expanded); - const sessionChildren = await sessionNode.getChildren(); const childrenFromTree = await getAllNodes(sessionChildren); @@ -923,7 +924,6 @@ describe("Extension Integration Tests - USS", () => { // Test that the node is successfully selected expect(node).to.deep.equal(ussFileProvider.getTreeView().selection[0]); } - ussFileProvider.getTreeView().dispose(); }).timeout(TIMEOUT); }); @@ -983,6 +983,9 @@ describe("Extension Integration Tests - USS", () => { expect(ussTestTree.mSessionNodes[0].tooltip).to.equal(fullUSSPath); expect(ussTestTree.mSessionNodes[0].collapsibleState).to.equal(vscode.TreeItemCollapsibleState.Expanded); + const newView = vscode.window.createTreeView("zowe.uss.explorer", {treeDataProvider: ussTestTree}); + ussTestTree.setTreeView(newView); + const childrenFromTree = await ussSessionNode.getChildren(); childrenFromTree.unshift(...(await childrenFromTree[0].getChildren())); @@ -990,6 +993,11 @@ describe("Extension Integration Tests - USS", () => { await ussTestTree.getTreeView().reveal(child); expect(child).to.deep.equal(ussTestTree.getTreeView().selection[0]); } + + for (const child of childrenFromTree) { + await ussTestTree.getTreeView().reveal(child); + expect(child).to.deep.equal(ussTestTree.getTreeView().selection[0]); + } }).timeout(TIMEOUT); it("should pop up a message if the user doesn't enter a USS path", async () => { @@ -1050,17 +1058,14 @@ describe("TreeView", () => { it("should create the TreeView", async () => { // Initialize dataset provider const datasetProvider = new DatasetTree(); - // Create the TreeView using datasetProvider to create tree structure - const testTreeView = vscode.window.createTreeView("zowe.explorer", {treeDataProvider: datasetProvider}); const allNodes = await getAllNodes(datasetProvider.mSessionNodes); for (const node of allNodes) { // For each node, select that node in TreeView by calling reveal() - await testTreeView.reveal(node); + await datasetProvider.getTreeView().reveal(node); // Test that the node is successfully selected - expect(node).to.deep.equal(testTreeView.selection[0]); + expect(node).to.deep.equal(datasetProvider.getTreeView().selection[0]); } - testTreeView.dispose(); }).timeout(TIMEOUT); }); diff --git a/src/DatasetTree.ts b/src/DatasetTree.ts index b53ddabe5c..3df011a30d 100644 --- a/src/DatasetTree.ts +++ b/src/DatasetTree.ts @@ -161,6 +161,15 @@ export class DatasetTree implements IZoweTree { return this.treeView; } + /** + * Sets the tree view for the current USSTree + * + * @param {vscode.TreeView} + */ + public setTreeView(newView) { + this.treeView = newView; + } + /** * Takes argument of type ZoweNode and retrieves all of the first level children * diff --git a/src/USSTree.ts b/src/USSTree.ts index 17fa747a3d..901fbd4dfd 100644 --- a/src/USSTree.ts +++ b/src/USSTree.ts @@ -88,6 +88,15 @@ export class USSTree implements IZoweTree { return this.treeView; } + /** + * Sets the tree view for the current USSTree + * + * @param {vscode.TreeView} + */ + public setTreeView(newView) { + this.treeView = newView; + } + /** * Takes argument of type ZoweUSSNode and retrieves all of the first level children * diff --git a/src/ZosJobsProvider.ts b/src/ZosJobsProvider.ts index 53f58c5715..1ff198f39a 100644 --- a/src/ZosJobsProvider.ts +++ b/src/ZosJobsProvider.ts @@ -108,6 +108,15 @@ export class ZosJobsProvider implements IZoweTree { return this.treeView; } + /** + * Sets the tree view for the current JobTree + * + * @param {vscode.TreeView} + */ + public setTreeView(newView) { + this.treeView = newView; + } + public getParent(element: Job): Job { return element.mParent; } From a35718c58a5e5872d81d0e30eba4389e1465ca87 Mon Sep 17 00:00:00 2001 From: katelynienaber Date: Thu, 6 Feb 2020 13:01:18 +0100 Subject: [PATCH 6/7] Fixing integration tests Signed-off-by: katelynienaber --- .../extension.integration.test.ts | 26 ++++++------------- src/DatasetTree.ts | 9 ------- src/USSTree.ts | 9 ------- src/ZosJobsProvider.ts | 9 ------- 4 files changed, 8 insertions(+), 45 deletions(-) diff --git a/__tests__/__integration__/extension.integration.test.ts b/__tests__/__integration__/extension.integration.test.ts index 7d0569dc71..513b995983 100644 --- a/__tests__/__integration__/extension.integration.test.ts +++ b/__tests__/__integration__/extension.integration.test.ts @@ -249,15 +249,11 @@ describe("Extension Integration Tests", () => { expect(testTree.mSessionNodes[1].tooltip).to.equal(pattern); expect(testTree.mSessionNodes[1].collapsibleState).to.equal(vscode.TreeItemCollapsibleState.Expanded); - const newView = vscode.window.createTreeView("zowe.explorer", {treeDataProvider: testTree}); - testTree.setTreeView(newView); - const childrenFromTree = await sessionNode.getChildren(); childrenFromTree.unshift(...(await childrenFromTree[0].getChildren())); await testTree.getTreeView().reveal(childrenFromTree[0]); expect(childrenFromTree[0]).to.deep.equal(testTree.getTreeView().selection[0]); - }).timeout(TIMEOUT); it("should match data sets for multiple patterns", async () => { @@ -972,31 +968,25 @@ describe("Extension Integration Tests - USS", () => { describe("Enter USS Pattern", () => { it("should output path that match the user-provided path", async () => { + const ussTestTree1 = new USSTree(); + ussTestTree1.mSessionNodes.splice(-1, 0, ussSessionNode); const inputBoxStub2 = sandbox.stub(vscode.window, "showInputBox"); inputBoxStub2.returns(fullUSSPath); const stubresolve = sandbox.stub(utils, "resolveQuickPickHelper"); stubresolve.returns(new utils.FilterItem(fullUSSPath)); - await ussTestTree.ussFilterPrompt(ussSessionNode); - - expect(ussTestTree.mSessionNodes[0].fullPath).to.equal(fullUSSPath); - expect(ussTestTree.mSessionNodes[0].tooltip).to.equal(fullUSSPath); - expect(ussTestTree.mSessionNodes[0].collapsibleState).to.equal(vscode.TreeItemCollapsibleState.Expanded); + await ussTestTree1.ussFilterPrompt(ussSessionNode); - const newView = vscode.window.createTreeView("zowe.uss.explorer", {treeDataProvider: ussTestTree}); - ussTestTree.setTreeView(newView); + expect(ussTestTree1.mSessionNodes[0].fullPath).to.equal(fullUSSPath); + expect(ussTestTree1.mSessionNodes[0].tooltip).to.equal(fullUSSPath); + expect(ussTestTree1.mSessionNodes[0].collapsibleState).to.equal(vscode.TreeItemCollapsibleState.Expanded); const childrenFromTree = await ussSessionNode.getChildren(); childrenFromTree.unshift(...(await childrenFromTree[0].getChildren())); for (const child of childrenFromTree) { - await ussTestTree.getTreeView().reveal(child); - expect(child).to.deep.equal(ussTestTree.getTreeView().selection[0]); - } - - for (const child of childrenFromTree) { - await ussTestTree.getTreeView().reveal(child); - expect(child).to.deep.equal(ussTestTree.getTreeView().selection[0]); + await ussTestTree1.getTreeView().reveal(child); + expect(child).to.deep.equal(ussTestTree1.getTreeView().selection[0]); } }).timeout(TIMEOUT); diff --git a/src/DatasetTree.ts b/src/DatasetTree.ts index 3df011a30d..b53ddabe5c 100644 --- a/src/DatasetTree.ts +++ b/src/DatasetTree.ts @@ -161,15 +161,6 @@ export class DatasetTree implements IZoweTree { return this.treeView; } - /** - * Sets the tree view for the current USSTree - * - * @param {vscode.TreeView} - */ - public setTreeView(newView) { - this.treeView = newView; - } - /** * Takes argument of type ZoweNode and retrieves all of the first level children * diff --git a/src/USSTree.ts b/src/USSTree.ts index 901fbd4dfd..17fa747a3d 100644 --- a/src/USSTree.ts +++ b/src/USSTree.ts @@ -88,15 +88,6 @@ export class USSTree implements IZoweTree { return this.treeView; } - /** - * Sets the tree view for the current USSTree - * - * @param {vscode.TreeView} - */ - public setTreeView(newView) { - this.treeView = newView; - } - /** * Takes argument of type ZoweUSSNode and retrieves all of the first level children * diff --git a/src/ZosJobsProvider.ts b/src/ZosJobsProvider.ts index 1ff198f39a..53f58c5715 100644 --- a/src/ZosJobsProvider.ts +++ b/src/ZosJobsProvider.ts @@ -108,15 +108,6 @@ export class ZosJobsProvider implements IZoweTree { return this.treeView; } - /** - * Sets the tree view for the current JobTree - * - * @param {vscode.TreeView} - */ - public setTreeView(newView) { - this.treeView = newView; - } - public getParent(element: Job): Job { return element.mParent; } From ff5d2fa61aea67af5e3fd3243a35684783ea6fb9 Mon Sep 17 00:00:00 2001 From: katelynienaber Date: Fri, 7 Feb 2020 11:16:33 +0100 Subject: [PATCH 7/7] Fixing unsigned commit Signed-off-by: katelynienaber --- .gitignore | 1 - .npmrc | 2 +- Jenkinsfile | 13 +- __mocks__/@brightside/imperative.ts | 8 +- .../DatasetTree.integration.test.ts | 35 +- .../USSTree.integration.test.ts | 4 +- .../ZoweNode.integration.test.ts | 57 +- .../extension.integration.test.ts | 65 +-- __tests__/__unit__/DatasetTree.unit.test.ts | 112 ++-- __tests__/__unit__/USSTree.unit.test.ts | 16 +- __tests__/__unit__/ZoweJobNode.unit.test.ts | 78 ++- __tests__/__unit__/ZoweNode.unit.test.ts | 79 +-- __tests__/__unit__/ZoweUSSNode.unit.test.ts | 2 +- __tests__/__unit__/extension.unit.test.ts | 365 ++++++------ .../__unit__/mvs/mvsNodeActions.unit.test.ts | 22 +- .../__unit__/uss/ussNodeActions.unit.test.ts | 53 +- i18n/sample/src/DatasetTree.i18n.json | 2 +- i18n/sample/src/USSTree.i18n.json | 2 +- i18n/sample/src/ZosJobsProvider.i18n.json | 2 +- i18n/sample/src/ZoweDatasetNode.i18n.json | 8 + i18n/sample/src/ZoweUSSNode.i18n.json | 14 +- i18n/sample/src/extension.i18n.json | 10 - i18n/sample/src/uss/ussNodeActions.i18n.json | 4 - src/DatasetTree.ts | 217 +++----- src/USSTree.ts | 178 ++---- src/ZosJobsProvider.ts | 195 ++----- src/ZoweDatasetNode.ts | 202 +++++++ src/ZoweJobNode.ts | 74 +-- src/ZoweUSSNode.ts | 302 ++++++++-- src/__mocks__/DatasetTree.ts | 36 +- src/abstract/ZoweTreeNode.ts | 110 ++++ src/abstract/ZoweTreeProvider.ts | 153 +++++ src/api/IZoweTree.ts | 72 +++ src/api/IZoweTreeNode.ts | 250 +++++++++ src/extension.ts | 526 ++++++------------ src/generators/icons/index.ts | 4 +- src/mvs/mvsNodeActions.ts | 16 +- src/uss/ussNodeActions.ts | 60 +- src/utils.ts | 21 +- stringUpdateScript.js | 4 +- 40 files changed, 1975 insertions(+), 1399 deletions(-) create mode 100644 i18n/sample/src/ZoweDatasetNode.i18n.json create mode 100644 src/ZoweDatasetNode.ts create mode 100644 src/abstract/ZoweTreeNode.ts create mode 100644 src/abstract/ZoweTreeProvider.ts create mode 100644 src/api/IZoweTree.ts create mode 100644 src/api/IZoweTreeNode.ts 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 index 9c99d49ed6..dff9d7cafd 100644 --- a/.npmrc +++ b/.npmrc @@ -1 +1 @@ -@brightside:registry=https://api.bintray.com/npm/ca/brightside/ \ No newline at end of file +@brightside:registry=https://api.bintray.com/npm/ca/brightside/ 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}" } } } } } 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__/__integration__/DatasetTree.integration.test.ts b/__tests__/__integration__/DatasetTree.integration.test.ts index 6f7b7f7094..ff7e841b5e 100644 --- a/__tests__/__integration__/DatasetTree.integration.test.ts +++ b/__tests__/__integration__/DatasetTree.integration.test.ts @@ -16,7 +16,7 @@ import { Logger, IProfileLoaded } from "@brightside/imperative"; 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"; @@ -38,7 +38,8 @@ 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, undefined, undefined, testProfile); + const sessNode = new ZoweDatasetNode(testConst.profile.name, vscode.TreeItemCollapsibleState.Expanded, + null, session, undefined, undefined, testProfile); sessNode.contextValue = extension.DS_SESSION_CONTEXT; const pattern = testConst.normalPattern.toUpperCase(); sessNode.pattern = pattern + ".PUBLIC"; @@ -70,7 +71,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); }); @@ -85,19 +86,19 @@ 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]]}; - 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]]}; @@ -145,18 +146,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); @@ -195,7 +196,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 === @@ -217,7 +218,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__/USSTree.integration.test.ts b/__tests__/__integration__/USSTree.integration.test.ts index bac5ca8048..9078ee272b 100644 --- a/__tests__/__integration__/USSTree.integration.test.ts +++ b/__tests__/__integration__/USSTree.integration.test.ts @@ -118,7 +118,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"); @@ -210,7 +210,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 6b737990d1..bd696088b8 100644 --- a/__tests__/__integration__/ZoweNode.integration.test.ts +++ b/__tests__/__integration__/ZoweNode.integration.test.ts @@ -16,7 +16,7 @@ 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"; import { Profiles } from "../../src/Profiles"; @@ -36,47 +36,48 @@ describe("ZoweNode Integration Tests", async () => { // 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, undefined, undefined, testProfile); + const sessNode = new ZoweDatasetNode(testConst.profile.name, vscode.TreeItemCollapsibleState.Expanded, + null, session, undefined, undefined, testProfile); 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.mParent).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(); - expect(PSNode.mParent).toBeDefined(); + expect(PSNode.getParent()).toBeDefined(); }); /************************************************************************************************************* - * 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(); - expect(edgeNode.mParent).toBeDefined(); + expect(edgeNode.getParent()).toBeDefined(); }); /************************************************************************************************************* - * 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(); @@ -86,11 +87,11 @@ 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]] }; @@ -102,28 +103,28 @@ describe("ZoweNode Integration Tests", async () => { }).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 @@ -136,7 +137,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(); @@ -153,9 +154,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 513b995983..ad6aa6ec3e 100644 --- a/__tests__/__integration__/extension.integration.test.ts +++ b/__tests__/__integration__/extension.integration.test.ts @@ -23,9 +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/IZoweTreeNode"; import { Profiles } from "../../src/Profiles"; const TIMEOUT = 45000; @@ -45,7 +46,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, + const sessionNode = new ZoweDatasetNode(testConst.profile.name, vscode.TreeItemCollapsibleState.Expanded, null, session, undefined, undefined, testProfile); sessionNode.contextValue = extension.DS_SESSION_CONTEXT; const pattern = testConst.normalPattern.toUpperCase(); @@ -150,7 +151,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); @@ -193,7 +194,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"); @@ -206,7 +207,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"); @@ -222,7 +223,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"); @@ -288,7 +289,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); @@ -309,7 +310,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(""); @@ -317,7 +318,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); @@ -412,7 +413,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); @@ -447,8 +448,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"); @@ -478,7 +479,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); @@ -503,7 +504,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"); @@ -520,8 +521,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"); @@ -570,8 +571,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); @@ -608,8 +609,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; @@ -662,8 +663,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; @@ -720,9 +721,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; @@ -863,8 +864,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())); @@ -1005,7 +1006,7 @@ describe("Extension Integration Tests - USS", () => { }); describe("Saving a USS File", () => { - + // TODO Move to appropriate class it("should download, change, and re-upload a file", async () => { const changedData = "File Upload Test "+ Math.random().toString(36).slice(2); @@ -1019,7 +1020,7 @@ describe("Extension Integration Tests - USS", () => { const localPath = path.join(extension.USS_DIR, "/", testConst.profile.name, dirChildren[0].fullPath); - await extension.openUSS(dirChildren[0], false, true); + await dirChildren[0].openUSS(false, true, ussTestTree); const doc = await vscode.workspace.openTextDocument(localPath); const originalData = doc.getText().trim(); @@ -1032,7 +1033,7 @@ describe("Extension Integration Tests - USS", () => { await fs.unlinkSync(localPath); // Download file - await extension.openUSS(dirChildren[0], false, true); + await dirChildren[0].openUSS(false, true, ussTestTree); // Change contents back fs.writeFileSync(localPath, originalData); @@ -1062,8 +1063,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__/DatasetTree.unit.test.ts b/__tests__/__unit__/DatasetTree.unit.test.ts index e2fd9400eb..97a8607182 100644 --- a/__tests__/__unit__/DatasetTree.unit.test.ts +++ b/__tests__/__unit__/DatasetTree.unit.test.ts @@ -19,7 +19,7 @@ jest.mock("isbinaryfile"); 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, IProfileLoaded } from "@brightside/imperative"; import * as zowe from "@brightside/core"; import * as utils from "../../src/utils"; @@ -120,7 +120,8 @@ describe("DatasetTree Unit Tests", () => { }) }); const testTree = new DatasetTree(); - testTree.mSessionNodes.push(new ZoweNode("testSess", vscode.TreeItemCollapsibleState.Collapsed, null, session, undefined, undefined, profileOne)); + testTree.mSessionNodes.push(new ZoweDatasetNode("testSess", vscode.TreeItemCollapsibleState.Collapsed, + null, session, undefined, undefined, profileOne)); testTree.mSessionNodes[1].contextValue = extension.DS_SESSION_CONTEXT; testTree.mSessionNodes[1].pattern = "test"; testTree.mSessionNodes[1].iconPath = utils.applyIcons(testTree.mSessionNodes[1]); @@ -150,7 +151,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); }); @@ -164,8 +165,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; @@ -192,16 +193,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); @@ -214,21 +215,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 () => { + 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, undefined, undefined, profileOne), - new ZoweNode("BRTVS99.CA10", vscode.TreeItemCollapsibleState.None, testTree.mSessionNodes[1], + const sampleChildren: ZoweDatasetNode[] = [ + new ZoweDatasetNode("BRTVS99", vscode.TreeItemCollapsibleState.None, testTree.mSessionNodes[1], null, undefined, undefined, profileOne), + new ZoweDatasetNode("BRTVS99.CA10", vscode.TreeItemCollapsibleState.None, testTree.mSessionNodes[1], null, extension.DS_MIGRATED_FILE_CONTEXT, undefined, profileOne), - new ZoweNode("BRTVS99.CA11.SPFTEMP0.CNTL", vscode.TreeItemCollapsibleState.Collapsed, testTree.mSessionNodes[1], + new ZoweDatasetNode("BRTVS99.CA11.SPFTEMP0.CNTL", vscode.TreeItemCollapsibleState.Collapsed, testTree.mSessionNodes[1], null, undefined, undefined, profileOne), - new ZoweNode("BRTVS99.DDIR", vscode.TreeItemCollapsibleState.Collapsed, testTree.mSessionNodes[1], + new ZoweDatasetNode("BRTVS99.DDIR", vscode.TreeItemCollapsibleState.Collapsed, testTree.mSessionNodes[1], null, undefined, undefined, profileOne), ]; @@ -239,16 +240,16 @@ 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 () => { // 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 @@ -256,17 +257,17 @@ 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]] }; @@ -281,7 +282,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"); }); @@ -308,9 +309,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({ @@ -329,13 +330,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); @@ -391,7 +392,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"; @@ -409,7 +410,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); @@ -419,7 +420,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); @@ -449,7 +450,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); @@ -479,7 +480,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"); @@ -503,7 +505,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); @@ -557,7 +559,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, undefined, undefined, profileOne); favoriteSearch.contextValue = extension.DS_SESSION_CONTEXT + extension.FAV_SUFFIX; const checkSession = jest.spyOn(testTree, "addSession"); @@ -691,7 +693,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}`; @@ -704,7 +706,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); @@ -723,9 +725,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(() => { @@ -760,12 +762,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", { @@ -808,12 +810,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({ @@ -872,9 +874,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(() => { @@ -894,8 +896,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); @@ -907,8 +909,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__/USSTree.unit.test.ts b/__tests__/__unit__/USSTree.unit.test.ts index 0a64ccf461..f0dc4cc838 100644 --- a/__tests__/__unit__/USSTree.unit.test.ts +++ b/__tests__/__unit__/USSTree.unit.test.ts @@ -136,7 +136,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(); }); @@ -299,11 +299,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); }); @@ -326,8 +326,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([]); }); @@ -344,14 +344,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 fc2ceeb834..c25fbe856d 100644 --- a/__tests__/__unit__/ZoweJobNode.unit.test.ts +++ b/__tests__/__unit__/ZoweJobNode.unit.test.ts @@ -304,7 +304,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 () => { @@ -315,7 +318,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 () => { @@ -332,7 +338,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, profileOne); + testJobsProvider.mSessionNodes[1].getSession(), iJob, profileOne); job.contextValue = "job"; await testJobsProvider.flipState(job, true); expect(JSON.stringify(job.iconPath)).toContain("folder-open.svg"); @@ -350,7 +356,7 @@ describe("Zos Jobs Unit Tests", () => { const refresh = jest.fn(); createBasicZosmfSession.mockReturnValue(sessionwocred); const newjobNode = new Job("[fake]: Owner:fakeUser Prefix:*", vscode.TreeItemCollapsibleState.Expanded, - jobNode, sessionwocred, iJob, jobNode.profile); + jobNode, sessionwocred, iJob, jobNode.getProfile()); const testJobsProvider = await createJobsTree(Logger.getAppLogger()); Object.defineProperty(testJobsProvider, "refresh", {value: refresh}); refresh.mockReset(); @@ -383,7 +389,7 @@ describe("Zos Jobs Unit Tests", () => { const refresh = jest.fn(); createBasicZosmfSession.mockReturnValue(sessionwocred); const newjobNode = new Job("[fake]: Owner:fakeUser Prefix:*", vscode.TreeItemCollapsibleState.Expanded, - jobNode, sessionwocred, iJob, jobNode.profile); + jobNode, sessionwocred, iJob, jobNode.getProfile()); const testJobsProvider = await createJobsTree(Logger.getAppLogger()); Object.defineProperty(testJobsProvider, "refresh", {value: refresh}); refresh.mockReset(); @@ -402,7 +408,7 @@ describe("Zos Jobs Unit Tests", () => { *************************************************************************************************************/ it("Testing that prompt credentials is called when searchPrompt is triggered", async () => { createBasicZosmfSession.mockReturnValue(sessionwocred); - const newjobNode = new Job("jobtest", vscode.TreeItemCollapsibleState.Expanded, jobNode, sessionwocred, iJob, jobNode.profile); + const newjobNode = new Job("jobtest", vscode.TreeItemCollapsibleState.Expanded, jobNode, sessionwocred, iJob, jobNode.getProfile()); newjobNode.contextValue = extension.JOBS_SESSION_CONTEXT; const testJobsProvider = await createJobsTree(Logger.getAppLogger()); const qpItem: vscode.QuickPickItem = testJobsProvider.createOwner; @@ -437,14 +443,52 @@ 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, jobNode.getProfile()); + 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, jobNode.profile); + jobNode, sessionwocred, iJob, jobNode.getProfile()); 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( @@ -498,7 +542,7 @@ describe("Zos Jobs Unit Tests", () => { createBasicZosmfSession.mockReturnValue(sessionwocred); const newjobNode = new Job("jobtest", vscode.TreeItemCollapsibleState.Expanded, - jobNode, sessionwocred, iJob, jobNode.profile); + jobNode, sessionwocred, iJob, jobNode.getProfile()); newjobNode.contextValue = extension.JOBS_SESSION_CONTEXT; const testJobsProvider = await createJobsTree(Logger.getAppLogger()); testJobsProvider.initializeJobsTree(Logger.getAppLogger()); @@ -728,10 +772,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, profileOne); + testTree.mSessionNodes[1].getSession(), iJob, profileOne); // Check adding job - await testTree.addJobsFavorite(job); + await testTree.addFavorite(job); expect(testTree.mFavorites.length).toEqual(1); testTree.mSessionNodes[1].owner = "myHLQ"; @@ -758,10 +802,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 f43af4489c..e057f4ecfd 100644 --- a/__tests__/__unit__/ZoweNode.unit.test.ts +++ b/__tests__/__unit__/ZoweNode.unit.test.ts @@ -15,7 +15,7 @@ jest.mock("@brightside/imperative"); jest.mock("@brightside/core/lib/zosfiles/src/api/methods/list/doc/IListOptions"); jest.mock("Session"); import * as vscode from "vscode"; -import { ZoweNode } from "../../src/ZoweNode"; +import { ZoweDatasetNode } from "../../src/ZoweDatasetNode"; import { Session, IProfileLoaded } from "@brightside/imperative"; import * as extension from "../../src/extension"; import { List } from "@brightside/core"; @@ -57,37 +57,38 @@ describe("Unit Tests (Jest)", () => { }); /************************************************************************************************************* - * 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(); expect(testNode.collapsibleState).toBeDefined(); expect(testNode.label).toBeDefined(); - expect(testNode.mParent).toBeDefined(); + expect(testNode.getParent()).toBeDefined(); expect(testNode.getSession()).toBeDefined(); }); /************************************************************************************************************* - * 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, undefined, undefined, profileOne); + const rootNode = new ZoweDatasetNode("root", vscode.TreeItemCollapsibleState.Collapsed, null, session, undefined, undefined, profileOne); 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, undefined, undefined, profileOne), - new ZoweNode("BRTVS99.CA10", vscode.TreeItemCollapsibleState.None, rootNode, null, extension.DS_MIGRATED_FILE_CONTEXT, + const sampleChildren: ZoweDatasetNode[] = [ + new ZoweDatasetNode("BRTVS99", vscode.TreeItemCollapsibleState.None, rootNode, null, undefined, undefined, profileOne), + new ZoweDatasetNode("BRTVS99.CA10", vscode.TreeItemCollapsibleState.None, rootNode, null, extension.DS_MIGRATED_FILE_CONTEXT, undefined, profileOne), - new ZoweNode("BRTVS99.CA11.SPFTEMP0.CNTL", vscode.TreeItemCollapsibleState.Collapsed, rootNode, null, undefined, undefined, profileOne), - new ZoweNode("BRTVS99.DDIR", vscode.TreeItemCollapsibleState.Collapsed, rootNode, null, undefined, undefined, profileOne), + new ZoweDatasetNode("BRTVS99.CA11.SPFTEMP0.CNTL", vscode.TreeItemCollapsibleState.Collapsed, + rootNode, null, undefined, undefined, profileOne), + new ZoweDatasetNode("BRTVS99.DDIR", vscode.TreeItemCollapsibleState.Collapsed, rootNode, null, undefined, undefined, profileOne), ]; sampleChildren[0].command = { command: "zowe.ZoweNode.openPS", title: "", arguments: [sampleChildren[0]] }; @@ -102,32 +103,33 @@ 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, undefined, undefined, profileOne); + const errorNode = new ZoweDatasetNode("", vscode.TreeItemCollapsibleState.Collapsed, null, session, undefined, undefined, profileOne); 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, undefined, undefined, profileOne); + const rootNode2 = new ZoweDatasetNode("root[test]", vscode.TreeItemCollapsibleState.Collapsed, + null, session, undefined, undefined, profileOne); 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, undefined, undefined, profileOne); + const rootNode = new ZoweDatasetNode("root", vscode.TreeItemCollapsibleState.None, null, session, undefined, undefined, profileOne); rootNode.contextValue = extension.DS_SESSION_CONTEXT; rootNode.dirty = true; - const subNode = new ZoweNode("sub", vscode.TreeItemCollapsibleState.Collapsed, rootNode, null, undefined, undefined, profileOne); + const subNode = new ZoweDatasetNode("sub", vscode.TreeItemCollapsibleState.Collapsed, rootNode, null, undefined, undefined, profileOne); 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, undefined, undefined, profileOne), - new ZoweNode("BRTVS99.DDIR", vscode.TreeItemCollapsibleState.None, subNode, null, undefined, undefined, profileOne), + const sampleChildren: ZoweDatasetNode[] = [ + new ZoweDatasetNode("BRTVS99", vscode.TreeItemCollapsibleState.None, subNode, null, undefined, undefined, profileOne), + new ZoweDatasetNode("BRTVS99.DDIR", vscode.TreeItemCollapsibleState.None, subNode, null, undefined, undefined, profileOne), ]; sampleChildren[0].command = { command: "zowe.ZoweNode.openPS", title: "", arguments: [sampleChildren[0]] }; @@ -144,7 +146,7 @@ describe("Unit Tests (Jest)", () => { showErrorMessage.mockReset(); // Creating a rootNode - const rootNode = new ZoweNode("root", vscode.TreeItemCollapsibleState.Collapsed, null, session, undefined, undefined, profileOne); + const rootNode = new ZoweDatasetNode("root", vscode.TreeItemCollapsibleState.Collapsed, null, session, undefined, undefined, profileOne); rootNode.contextValue = extension.DS_SESSION_CONTEXT; rootNode.pattern = "THROW ERROR"; rootNode.dirty = true; @@ -159,11 +161,11 @@ 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, undefined, undefined, profileOne); 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, undefined, undefined, profileOne); subNode.dirty = true; await expect(subNode.getChildren()).rejects.toEqual(Error("The response from Zowe CLI was not successful")); @@ -174,8 +176,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, undefined, undefined, profileOne); - 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, undefined, undefined, profileOne); + const infoChild = new ZoweDatasetNode("Use the search button to display datasets", vscode.TreeItemCollapsibleState.None, rootNode, null, extension.INFORMATION_CONTEXT, undefined, profileOne); rootNode.contextValue = extension.DS_SESSION_CONTEXT; rootNode.dirty = false; @@ -187,8 +189,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, undefined, undefined, profileOne); - 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, undefined, undefined, profileOne); + const infoChild = new ZoweDatasetNode("Use the search button to display datasets", vscode.TreeItemCollapsibleState.None, rootNode, null, extension.INFORMATION_CONTEXT, undefined, profileOne); rootNode.contextValue = extension.DS_SESSION_CONTEXT; await expect(await rootNode.getChildren()).toEqual([infoChild]); @@ -199,11 +201,11 @@ 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, undefined, undefined, profileOne); + const rootNode = new ZoweDatasetNode("root", vscode.TreeItemCollapsibleState.Collapsed, null, session, undefined, undefined, profileOne); rootNode.contextValue = extension.DS_SESSION_CONTEXT; - const subNode = new ZoweNode(extension.DS_PDS_CONTEXT, vscode.TreeItemCollapsibleState.Collapsed, rootNode, null, + const subNode = new ZoweDatasetNode(extension.DS_PDS_CONTEXT, vscode.TreeItemCollapsibleState.Collapsed, rootNode, null, undefined, undefined, profileOne); - const member = new ZoweNode(extension.DS_MEMBER_CONTEXT, vscode.TreeItemCollapsibleState.None, subNode, null, + const member = new ZoweDatasetNode(extension.DS_MEMBER_CONTEXT, vscode.TreeItemCollapsibleState.None, subNode, null, undefined, undefined, profileOne); await expect(member.getSession()).toBeDefined(); }); @@ -212,7 +214,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, undefined, undefined, profileOne); + const rootNode = new ZoweDatasetNode("root", vscode.TreeItemCollapsibleState.Collapsed, null, session, undefined, undefined, profileOne); rootNode.dirty = true; rootNode.contextValue = extension.DS_DS_CONTEXT; expect(await rootNode.getChildren()).toHaveLength(0); @@ -226,8 +228,9 @@ 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, undefined, undefined, profileOne); - rootNode.children = [new ZoweNode("onestep", vscode.TreeItemCollapsibleState.Collapsed, null, session, undefined, undefined, profileOne)]; + const rootNode = new ZoweDatasetNode("root", vscode.TreeItemCollapsibleState.Collapsed, null, session, undefined, undefined, profileOne); + rootNode.children = [new ZoweDatasetNode("onestep", vscode.TreeItemCollapsibleState.Collapsed, + null, session, undefined, undefined, profileOne)]; rootNode.dirty = false; rootNode.contextValue = extension.DS_PDS_CONTEXT; expect((await rootNode.getChildren())[0].label).toEqual("onestep"); @@ -238,7 +241,8 @@ 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, undefined, undefined, profileOne); + const pds = new ZoweDatasetNode("[root]: something", vscode.TreeItemCollapsibleState.Collapsed, + null, session, undefined, undefined, profileOne); pds.dirty = true; pds.contextValue = extension.DS_PDS_CONTEXT; expect((await pds.getChildren())[0].label).toEqual("BRTVS99"); @@ -249,7 +253,8 @@ 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, undefined, undefined, profileOne); + const pds = new ZoweDatasetNode("[root]: something", vscode.TreeItemCollapsibleState.Collapsed, + null, session, undefined, undefined, profileOne); pds.dirty = true; pds.contextValue = extension.DS_PDS_CONTEXT; const allMembers = jest.fn(); diff --git a/__tests__/__unit__/ZoweUSSNode.unit.test.ts b/__tests__/__unit__/ZoweUSSNode.unit.test.ts index f8db2959db..b2f6a21180 100644 --- a/__tests__/__unit__/ZoweUSSNode.unit.test.ts +++ b/__tests__/__unit__/ZoweUSSNode.unit.test.ts @@ -109,7 +109,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 9823b3555c..4b9799dc48 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"; @@ -134,7 +134,7 @@ describe("Extension Unit Tests", () => { getJesApiMock.mockReturnValue(jesApi); ZoweExplorerApiRegister.getJesApi = getJesApiMock.bind(ZoweExplorerApiRegister); - const sessNode = new ZoweNode("sestest", vscode.TreeItemCollapsibleState.Expanded, null, session, undefined, undefined, profileOne); + const sessNode = new ZoweDatasetNode("sestest", vscode.TreeItemCollapsibleState.Expanded, null, session, undefined, undefined, profileOne); sessNode.contextValue = extension.DS_SESSION_CONTEXT; sessNode.pattern = "test hlq"; @@ -246,9 +246,6 @@ describe("Extension Unit Tests", () => { const findFavoritedNode = jest.fn(); const findNonFavoritedNode = jest.fn(); const concatChildNodes = jest.fn(); - const concatUSSChildNodes = jest.fn(); - const ImperativeError = jest.fn(); - const getProfileName = jest.fn(); let mockClipboardData: string; const fileResponse: brightside.IZosFilesResponse = { success: true, @@ -369,9 +366,7 @@ 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, "ImperativeError", {value: ImperativeError}); Object.defineProperty(brtimperative, "CliProfileManager", {value: CliProfileManager}); Object.defineProperty(vscode.window, "createTreeView", {value: createTreeView}); Object.defineProperty(vscode.window, "createWebviewPanel", {value: createWebviewPanel}); @@ -448,10 +443,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(ZoweNode, "getProfileName", { value: getProfileName }); - Object.defineProperty(brtimperative, "ImperativeConfig", { value: ImperativeConfig }); - Object.defineProperty(ImperativeConfig, "instance", { value: icInstance }); - Object.defineProperty(icInstance, "cliHome", { value: cliHome }); beforeEach(() => { mockLoadNamedProfile.mockReturnValue(profileOne); @@ -585,15 +576,16 @@ 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); const sampleFavorites = [ - new ZoweNode("[test]: brtvs99.public.test", vscode.TreeItemCollapsibleState.Collapsed, + new ZoweDatasetNode("[test]: brtvs99.public.test", vscode.TreeItemCollapsibleState.Collapsed, undefined, undefined, undefined, undefined, profileOne), - new ZoweNode("[test]: brtvs99.test", vscode.TreeItemCollapsibleState.None, + new ZoweDatasetNode("[test]: brtvs99.test", vscode.TreeItemCollapsibleState.None, undefined, undefined, undefined, undefined, profileOne), - new ZoweNode("[test]: brtvs99.test.search", vscode.TreeItemCollapsibleState.None, + new ZoweDatasetNode("[test]: brtvs99.test.search", vscode.TreeItemCollapsibleState.None, undefined, null, undefined, undefined, profileOne) ]; sampleFavorites[0].contextValue = extension.DS_PDS_CONTEXT + extension.FAV_SUFFIX; @@ -793,7 +785,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"); @@ -831,9 +823,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(); @@ -880,7 +872,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(""); @@ -923,12 +915,20 @@ describe("Extension Unit Tests", () => { it("Call Change File type", async () => { const node = new ZoweUSSNode("node", vscode.TreeItemCollapsibleState.None, ussNode, null, null); + const response: brightside.IZosFilesResponse = { + success: true, + commandResponse: null, + apiResponse: { + etag: "132" + } + }; + ussFile.mockResolvedValueOnce(response); const res = extension.changeFileType(node, false, testUSSTree); expect(res).not.toBeUndefined(); }); 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(); }); @@ -1189,10 +1189,10 @@ describe("Extension Unit Tests", () => { }); it("Testing that createFile is executed successfully", async () => { - const sessNode2 = new ZoweNode("sestest", vscode.TreeItemCollapsibleState.Expanded, null, session, undefined, undefined, profileOne); + const sessNode2 = new ZoweDatasetNode("sestest", vscode.TreeItemCollapsibleState.Expanded, null, session, undefined, undefined, profileOne); sessNode2.contextValue = extension.DS_SESSION_CONTEXT; sessNode2.pattern = "test hlq"; - const childNode = new ZoweNode("NODE", vscode.TreeItemCollapsibleState.None, sessNode2, null, undefined, undefined, profileOne); + const childNode = new ZoweDatasetNode("NODE", vscode.TreeItemCollapsibleState.None, sessNode2, null, undefined, undefined, profileOne); sessNode2.children.push(childNode); const uploadResponse: brightside.IZosFilesResponse = { @@ -1334,7 +1334,8 @@ describe("Extension Unit Tests", () => { }; createBasicZosmfSession.mockReturnValue(sessionwocred); - const newsessNode = new ZoweNode("sestest", vscode.TreeItemCollapsibleState.Expanded, null, sessionwocred, undefined, undefined, profileOne); + const newsessNode = new ZoweDatasetNode("sestest", vscode.TreeItemCollapsibleState.Expanded, + null, sessionwocred, undefined, undefined, profileOne); newsessNode.contextValue = extension.DS_SESSION_CONTEXT; showQuickPick.mockReset(); @@ -1417,7 +1418,8 @@ describe("Extension Unit Tests", () => { }; createBasicZosmfSession.mockReturnValue(sessionwocred); - const newsessNode = new ZoweNode("sestest", vscode.TreeItemCollapsibleState.Expanded, null, sessionwocred, undefined, undefined, profileOne); + const newsessNode = new ZoweDatasetNode("sestest", vscode.TreeItemCollapsibleState.Expanded, + null, sessionwocred, undefined, undefined, profileOne); newsessNode.contextValue = extension.DS_SESSION_CONTEXT + extension.FAV_SUFFIX; showQuickPick.mockReset(); @@ -1432,8 +1434,8 @@ describe("Extension Unit Tests", () => { getConfiguration.mockReturnValue("FakeConfig"); showInputBox.mockReturnValue("FakeName"); createTreeView.mockReturnValue(new TreeView()); - testTree.getChildren.mockReturnValue([new ZoweNode("node", vscode.TreeItemCollapsibleState.None, sessNode, - null, undefined, undefined, profileOne), sessNode]); + testTree.getChildren.mockReturnValue([new ZoweDatasetNode("node", vscode.TreeItemCollapsibleState.None, sessNode, + null, undefined, undefined, profileOne), sessNode]); allMembers.mockReturnValue(uploadResponse); dataSet.mockReturnValue(uploadResponse); mockGetHistory.mockReturnValue(["mockHistory1"]); @@ -1500,7 +1502,8 @@ describe("Extension Unit Tests", () => { }); const createFile = jest.spyOn(extension, "createFile"); createBasicZosmfSession.mockReturnValue(sessionwocred); - const newsessNode = new ZoweNode("sestest", vscode.TreeItemCollapsibleState.Expanded, null, sessionwocred, undefined, undefined, profileOne); + const newsessNode = new ZoweDatasetNode("sestest", vscode.TreeItemCollapsibleState.Expanded, + null, sessionwocred, undefined, undefined, profileOne); newsessNode.contextValue = extension.DS_SESSION_CONTEXT; newsessNode.pattern = "sestest"; @@ -1532,11 +1535,12 @@ describe("Extension Unit Tests", () => { showQuickPick.mockReset(); const deleteSpy = jest.spyOn(mvsApi, "deleteDataSet"); - let node = new ZoweNode("HLQ.TEST.NODE", vscode.TreeItemCollapsibleState.Expanded, sessNode, null); - const parent = new ZoweNode("parent", vscode.TreeItemCollapsibleState.Collapsed, sessNode, null); - const parentAsFavorite = new ZoweNode("[sestest]: parent", vscode.TreeItemCollapsibleState.Collapsed, sessNode, null); + let node = new ZoweDatasetNode("HLQ.TEST.NODE", vscode.TreeItemCollapsibleState.None, sessNode, null, undefined, undefined, profileOne); + const parent = new ZoweDatasetNode("parent", vscode.TreeItemCollapsibleState.Collapsed, sessNode, null, undefined, undefined, profileOne); + let child = new ZoweDatasetNode("child", vscode.TreeItemCollapsibleState.None, parent, null, undefined, undefined, profileOne); + const parentAsFavorite = new ZoweDatasetNode("[sestest]: parent", vscode.TreeItemCollapsibleState.Collapsed, + sessNode, null, undefined, undefined, profileOne); parentAsFavorite.contextValue = extension.PDS_FAV_CONTEXT; - let child = new ZoweNode("child", vscode.TreeItemCollapsibleState.None, parent, null); testTree.mFavorites.push(parentAsFavorite); existsSync.mockReturnValueOnce(true); @@ -1559,7 +1563,7 @@ describe("Extension Unit Tests", () => { await extension.deleteDataset(child, testTree); expect(unlinkSync.mock.calls.length).toBe(0); - expect(deleteSpy.mock.calls[0][0]).toBe(child.mParent.label + "(" + child.label + ")"); + expect(deleteSpy.mock.calls[0][0]).toBe(child.getParent().getLabel() + "(" + child.label + ")"); deleteSpy.mockReset(); deleteSpy.mockRejectedValueOnce(Error("not found")); @@ -1585,13 +1589,13 @@ describe("Extension Unit Tests", () => { await extension.deleteDataset(child, testTree); existsSync.mockReturnValueOnce(true); - node = new ZoweNode("HLQ.TEST.NODE", vscode.TreeItemCollapsibleState.None, sessNode, null, undefined, undefined, profileOne); + node = new ZoweDatasetNode("HLQ.TEST.NODE", vscode.TreeItemCollapsibleState.None, sessNode, null, undefined, undefined, profileOne); 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, undefined, undefined, profileOne); + child = new ZoweDatasetNode("child", vscode.TreeItemCollapsibleState.None, node, null, undefined, undefined, profileOne); await extension.deleteDataset(child, testTree); expect(mockRefreshElement).toHaveBeenCalledWith(parent); expect(mockRefreshElement).toHaveBeenCalledWith(parentAsFavorite); @@ -1604,9 +1608,10 @@ describe("Extension Unit Tests", () => { const deleteSpy = jest.spyOn(mvsApi, "deleteDataSet"); mockRemoveFavorite.mockReset(); - const node = new ZoweNode("HLQ.TEST.DELETE.PARENT", vscode.TreeItemCollapsibleState.None, sessNode, null); - const nodeAsFavorite = new ZoweNode("[sestest]: HLQ.TEST.DELETE.PARENT", vscode.TreeItemCollapsibleState.None, sessNode, null); - const child = new ZoweNode("[sestest]: HLQ.TEST.DELETE.NODE", vscode.TreeItemCollapsibleState.None, nodeAsFavorite, 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; + const nodeAsFavorite = new ZoweDatasetNode("[sestest]: HLQ.TEST.DELETE.PARENT", vscode.TreeItemCollapsibleState.None, sessNode, null); nodeAsFavorite.contextValue = extension.FAVORITE_CONTEXT; sessNode.children.push(node, nodeAsFavorite, child); testTree.mFavorites.push(nodeAsFavorite); @@ -1639,8 +1644,8 @@ describe("Extension Unit Tests", () => { const deleteSpy = jest.spyOn(mvsApi, "deleteDataSet"); 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); @@ -1667,10 +1672,10 @@ 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); - child.contextValue = "junk"; + 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); showQuickPick.mockResolvedValueOnce("Yes"); @@ -1681,7 +1686,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; @@ -1706,7 +1711,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); @@ -1771,7 +1776,8 @@ 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, undefined, undefined, profileOne); + const nodeWitoutSession = new ZoweDatasetNode("HLQ.TEST.AFILE", vscode.TreeItemCollapsibleState.None, + null, null, undefined, undefined, profileOne); testTree.getChildren.mockReturnValueOnce([nodeWitoutSession]); concatChildNodes.mockReturnValueOnce([nodeWitoutSession]); const getSessionSpy = jest.spyOn(mvsApi, "getSession").mockReturnValueOnce(sessionwocred); @@ -1808,7 +1814,7 @@ describe("Extension Unit Tests", () => { }) }); - testTree.getChildren.mockReturnValueOnce([new ZoweNode("node", vscode.TreeItemCollapsibleState.None, + testTree.getChildren.mockReturnValueOnce([new ZoweDatasetNode("node", vscode.TreeItemCollapsibleState.None, sessNode, null, undefined, undefined, profileOne), sessNode]); showErrorMessage.mockReset(); const dataSetSpy = jest.spyOn(mvsApi, "dataSet").mockImplementationOnce( @@ -1819,7 +1825,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, undefined, undefined, profileOne); + const node = new ZoweDatasetNode("HLQ.TEST.AFILE", vscode.TreeItemCollapsibleState.None, sessNode, null, undefined, undefined, profileOne); sessNode.children.push(node); testResponse.apiResponse.items = [{dsname: "HLQ.TEST.AFILE"}, {dsname: "HLQ.TEST.AFILE(mem)"}]; dataSetList.mockReset(); @@ -1910,7 +1916,7 @@ describe("Extension Unit Tests", () => { dataSetList.mockReset(); showErrorMessage.mockReset(); - sessNode.children.push(new ZoweNode( + sessNode.children.push(new ZoweDatasetNode( "HLQ.TEST.AFILE(mem)", vscode.TreeItemCollapsibleState.None, sessNode, null, undefined, undefined, profileOne)); testTree.getChildren.mockReturnValueOnce([sessNode]); dataSetList.mockResolvedValueOnce(testResponse); @@ -1921,7 +1927,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, + testTree.getChildren.mockReturnValueOnce([new ZoweDatasetNode("node", vscode.TreeItemCollapsibleState.None, sessNode, null, undefined, undefined, profileOne), sessNode]); dataSetList.mockReset(); showErrorMessage.mockReset(); @@ -1960,9 +1966,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); @@ -1992,7 +1998,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); @@ -2017,7 +2023,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) { @@ -2055,7 +2061,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(() => { @@ -2091,7 +2097,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(() => { @@ -2127,7 +2133,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(() => { @@ -2160,7 +2166,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(() => { @@ -2220,10 +2226,10 @@ describe("Extension Unit Tests", () => { etag: "132" } }; - ussFile.mockResolvedValueOnce(response); + ussFile.mockResolvedValue(response); isDirtyInEditor.mockReturnValueOnce(true); isDirtyInEditor.mockReturnValueOnce(false); - await extension.refreshUSS(node); + await node.refreshUSS(); expect(ussFile.mock.calls.length).toBe(1); expect(showTextDocument.mock.calls.length).toBe(2); @@ -2246,7 +2252,7 @@ describe("Extension Unit Tests", () => { ussFile.mockResolvedValueOnce(response); isDirtyInEditor.mockReturnValueOnce(true); isDirtyInEditor.mockReturnValueOnce(true); - await extension.refreshUSS(node); + await node.refreshUSS(); expect(ussFile.mock.calls.length).toBe(0); expect(showTextDocument.mock.calls.length).toBe(1); @@ -2269,7 +2275,7 @@ describe("Extension Unit Tests", () => { ussFile.mockResolvedValueOnce(response); isDirtyInEditor.mockReturnValueOnce(false); isDirtyInEditor.mockReturnValueOnce(false); - await extension.refreshUSS(node); + await node.refreshUSS(); expect(ussFile.mock.calls.length).toBe(1); expect(showTextDocument.mock.calls.length).toBe(0); @@ -2285,7 +2291,7 @@ describe("Extension Unit Tests", () => { ussFile.mockRejectedValueOnce(Error("")); isDirtyInEditor.mockReturnValueOnce(true); isDirtyInEditor.mockReturnValueOnce(false); - await extension.refreshUSS(node); + await node.refreshUSS(); expect(ussFile.mock.calls.length).toBe(1); expect(showTextDocument.mock.calls.length).toBe(1); @@ -2557,6 +2563,7 @@ describe("Extension Unit Tests", () => { expect(testTree.refresh).toHaveBeenCalled(); }); + // TODO Node tests it("Testing that open is executed successfully", async () => { ussFile.mockReset(); openTextDocument.mockReset(); @@ -2576,12 +2583,13 @@ describe("Extension Unit Tests", () => { ussFile.mockReturnValueOnce(fileResponse); withProgress.mockReturnValue(fileResponse); - await extension.openUSS(node, false, true, testUSSTree); + await node.openUSS(false, true, testUSSTree); 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(isBinSpy.mock.calls.length).toBe(1); - expect(isBinSpy.mock.calls[0][0]).toBe(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); expect(withProgress).toBeCalledWith( { location: vscode.ProgressLocation.Notification, @@ -2591,14 +2599,14 @@ describe("Extension Unit Tests", () => { withProgress(downloadUSSFile); expect(withProgress).toBeCalledWith(downloadUSSFile); expect(openTextDocument.mock.calls.length).toBe(1); - expect(openTextDocument.mock.calls[0][0]).toBe(extension.getUSSDocumentFilePath(node)); + expect(openTextDocument.mock.calls[0][0]).toBe(node.getUSSDocumentFilePath()); expect(showTextDocument.mock.calls.length).toBe(1); expect(showTextDocument.mock.calls[0][0]).toBe("test.doc"); openTextDocument.mockResolvedValueOnce("test.doc"); const node2 = new ZoweUSSNode("usstest", vscode.TreeItemCollapsibleState.None, ussNode, null, null); - await extension.openUSS(node2, false, true, testUSSTree); + await node2.openUSS(false, true, testUSSTree); ussFile.mockReset(); openTextDocument.mockReset(); @@ -2609,21 +2617,21 @@ describe("Extension Unit Tests", () => { showTextDocument.mockRejectedValueOnce(Error("testError")); try { - await extension.openUSS(child, false, true, testUSSTree); + await child.openUSS(false, true, testUSSTree); } catch (err) { // do nothing } expect(ussFile.mock.calls.length).toBe(0); expect(openTextDocument.mock.calls.length).toBe(1); - expect(openTextDocument.mock.calls[0][0]).toBe(extension.getUSSDocumentFilePath(child)); + expect(openTextDocument.mock.calls[0][0]).toBe(child.getUSSDocumentFilePath()); expect(showTextDocument.mock.calls.length).toBe(1); expect(showErrorMessage.mock.calls.length).toBe(1); expect(showErrorMessage.mock.calls[0][0]).toBe("testError"); const child2 = new ZoweUSSNode("child", vscode.TreeItemCollapsibleState.None, node2, null, null); try { - await extension.openUSS(child2, false, true, testUSSTree); + await child2.openUSS(false, true, testUSSTree); } catch (err) { // do nothing } @@ -2638,7 +2646,7 @@ describe("Extension Unit Tests", () => { badparent.contextValue = "turnip"; const brat = new ZoweUSSNode("brat", vscode.TreeItemCollapsibleState.None, badparent, null, null); try { - await extension.openUSS(brat, false, true, testUSSTree); + await brat.openUSS(false, true, testUSSTree); // tslint:disable-next-line: no-empty } catch (err) { } @@ -2648,6 +2656,7 @@ describe("Extension Unit Tests", () => { expect(showErrorMessage.mock.calls[1][0]).toBe("open() called from invalid node."); }); + // TODO Node tests it("Tests that openUSS executes successfully with favored files", async () => { ussFile.mockReset(); openTextDocument.mockReset(); @@ -2672,15 +2681,16 @@ describe("Extension Unit Tests", () => { child.contextValue = extension.DS_TEXT_FILE_CONTEXT; // For each node, make sure that code below the log.debug statement is execute - await extension.openUSS(favoriteFile, false, true, testUSSTree); + await favoriteFile.openUSS(false, true, testUSSTree); expect(showTextDocument.mock.calls.length).toBe(1); showTextDocument.mockReset(); ussFile.mockReturnValueOnce(fileResponse); - await extension.openUSS(child, false, true, testUSSTree); + await child.openUSS(false, true, testUSSTree); expect(showTextDocument.mock.calls.length).toBe(1); showTextDocument.mockReset(); }); + // TODO Node tests it("Testing that open is executed successfully when chtag says binary", async () => { ussFile.mockReset(); openTextDocument.mockReset(); @@ -2689,7 +2699,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, ussNode.getProfileName()); const parent = new ZoweUSSNode("parent", vscode.TreeItemCollapsibleState.Collapsed, ussNode, null, "/"); const child = new ZoweUSSNode("child", vscode.TreeItemCollapsibleState.None, parent, null, "/parent"); @@ -2699,10 +2709,10 @@ describe("Extension Unit Tests", () => { withProgress.mockReturnValue(fileResponse); - await extension.openUSS(node, false, true, testUSSTree); + await node.openUSS(false, true, testUSSTree); 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, @@ -2712,11 +2722,12 @@ describe("Extension Unit Tests", () => { withProgress(downloadUSSFile); expect(withProgress).toBeCalledWith(downloadUSSFile); expect(openTextDocument.mock.calls.length).toBe(1); - expect(openTextDocument.mock.calls[0][0]).toBe(extension.getUSSDocumentFilePath(node)); + expect(openTextDocument.mock.calls[0][0]).toBe(node.getUSSDocumentFilePath()); expect(showTextDocument.mock.calls.length).toBe(1); expect(showTextDocument.mock.calls[0][0]).toBe("test.doc"); }); + // TODO Node tests it("Testing that that openUSS credentials prompt is executed successfully", async () => { showQuickPick.mockReset(); showInputBox.mockReset(); @@ -2750,7 +2761,7 @@ describe("Extension Unit Tests", () => { showInputBox.mockReturnValueOnce("fake"); showInputBox.mockReturnValueOnce("fake"); - await extension.openUSS(dsNode, false, true, testUSSTree); + await dsNode.openUSS(false, true, testUSSTree); expect(openTextDocument.mock.calls.length).toBe(1); expect(showTextDocument.mock.calls.length).toBe(1); }); @@ -2788,7 +2799,7 @@ describe("Extension Unit Tests", () => { ussFile.mockReturnValueOnce(fileResponse); - await extension.openUSS(dsNode, false, true, testUSSTree); + await dsNode.openUSS(false, true, testUSSTree); expect(openTextDocument.mock.calls.length).toBe(1); expect(showTextDocument.mock.calls.length).toBe(1); }); @@ -2823,9 +2834,9 @@ describe("Extension Unit Tests", () => { showInputBox.mockReturnValueOnce("fake"); showInputBox.mockReturnValueOnce("fake"); - const spyopenUSS = jest.spyOn(extension, "openUSS"); - await extension.openUSS(dsNode, false, true, testUSSTree); - expect(extension.openUSS).toHaveBeenCalled(); + const spyopenUSS = jest.spyOn(dsNode, "openUSS"); + await dsNode.openUSS(false, true, testUSSTree); + expect(dsNode.openUSS).toHaveBeenCalled(); }); it("Testing that that openUSS credentials prompt ends in error", async () => { @@ -2853,7 +2864,7 @@ describe("Extension Unit Tests", () => { }) }); - await extension.openUSS(dsNode, false, true, testUSSTree); + await dsNode.openUSS(false, true, testUSSTree); expect(showErrorMessage.mock.calls.length).toBe(1); showQuickPick.mockReset(); showInputBox.mockReset(); @@ -2903,20 +2914,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); @@ -2927,8 +2938,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")); @@ -2936,8 +2947,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"; @@ -3014,7 +3025,7 @@ describe("Extension Unit Tests", () => { type: "basic", }); createBasicZosmfSession.mockReturnValue(sessionwocred); - const newjobNode = new Job("jobtest", vscode.TreeItemCollapsibleState.Expanded, jobNode, sessionwocred, iJob, jobNode.profile); + const newjobNode = new Job("jobtest", vscode.TreeItemCollapsibleState.Expanded, jobNode, sessionwocred, iJob, jobNode.getProfile()); newjobNode.contextValue = "server"; newjobNode.contextValue = "server"; await extension.refreshJobsServer(newjobNode, testJobsTree); @@ -3044,7 +3055,7 @@ describe("Extension Unit Tests", () => { type: "basic", }); createBasicZosmfSession.mockReturnValue(sessionwocred); - const newjobNode = new Job("jobtest", vscode.TreeItemCollapsibleState.Expanded, jobNode, sessionwocred, iJob, jobNode.profile); + const newjobNode = new Job("jobtest", vscode.TreeItemCollapsibleState.Expanded, jobNode, sessionwocred, iJob, jobNode.getProfile()); newjobNode.contextValue = extension.JOBS_SESSION_CONTEXT + extension.FAV_SUFFIX; await extension.refreshJobsServer(newjobNode, testJobsTree); expect(extension.refreshJobsServer).toHaveBeenCalled(); @@ -3073,7 +3084,7 @@ describe("Extension Unit Tests", () => { type: "basic", }); createBasicZosmfSession.mockReturnValue(sessionwocred); - const newjobNode = new Job("jobtest", vscode.TreeItemCollapsibleState.Expanded, jobNode, sessionwocred, iJob, jobNode.profile); + const newjobNode = new Job("jobtest", vscode.TreeItemCollapsibleState.Expanded, jobNode, sessionwocred, iJob, jobNode.getProfile()); newjobNode.contextValue = extension.JOBS_SESSION_CONTEXT + extension.FAV_SUFFIX; const spyopenPS = jest.spyOn(extension, "refreshJobsServer"); await extension.refreshJobsServer(newjobNode, testJobsTree); @@ -3097,7 +3108,7 @@ describe("Extension Unit Tests", () => { }); createBasicZosmfSession.mockReturnValue(session); - const newjobNode = new Job("jobtest", vscode.TreeItemCollapsibleState.Expanded, jobNode, session, iJob, jobNode.profile); + const newjobNode = new Job("jobtest", vscode.TreeItemCollapsibleState.Expanded, jobNode, session, iJob, jobNode.getProfile()); newjobNode.contextValue = "server"; newjobNode.contextValue = "server"; await extension.refreshJobsServer(newjobNode, testJobsTree); @@ -3125,7 +3136,7 @@ describe("Extension Unit Tests", () => { type: "basic", }); createBasicZosmfSession.mockReturnValue(sessionwocred); - const newjobNode = new Job("jobtest", vscode.TreeItemCollapsibleState.Expanded, jobNode, sessionwocred, iJob, jobNode.profile); + const newjobNode = new Job("jobtest", vscode.TreeItemCollapsibleState.Expanded, jobNode, sessionwocred, iJob, jobNode.getProfile()); newjobNode.contextValue = "server"; newjobNode.contextValue = "server"; await extension.refreshJobsServer(newjobNode, testJobsTree); @@ -3428,7 +3439,7 @@ describe("Extension Unit Tests", () => { type: "basic", }); createBasicZosmfSession.mockReturnValue(sessionwocred); - const newjobNode = new Job("jobtest", vscode.TreeItemCollapsibleState.Expanded, jobNode, sessionwocred, iJob, jobNode.profile); + const newjobNode = new Job("jobtest", vscode.TreeItemCollapsibleState.Expanded, jobNode, sessionwocred, iJob, jobNode.getProfile()); newjobNode.contextValue = extension.JOBS_SESSION_CONTEXT; Object.defineProperty(profileLoader.Profiles, "getInstance", { value: jest.fn(() => { @@ -3462,7 +3473,7 @@ describe("Extension Unit Tests", () => { type: "basic", }); createBasicZosmfSession.mockReturnValue(sessionwocred); - const newjobNode = new Job("jobtest", vscode.TreeItemCollapsibleState.Expanded, jobNode, sessionwocred, iJob, jobNode.profile); + const newjobNode = new Job("jobtest", vscode.TreeItemCollapsibleState.Expanded, jobNode, sessionwocred, iJob, jobNode.getProfile()); newjobNode.contextValue = extension.JOBS_SESSION_CONTEXT; Object.defineProperty(profileLoader.Profiles, "getInstance", { value: jest.fn(() => { @@ -3562,7 +3573,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(); @@ -3572,21 +3583,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 @@ -3687,6 +3698,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("Error encountered when creating temporary folder! 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(); @@ -3724,72 +3771,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: "", @@ -3839,7 +3886,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); @@ -3847,7 +3894,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); @@ -3868,7 +3915,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); @@ -3880,7 +3927,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); @@ -3896,7 +3943,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 { @@ -3913,8 +3960,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); @@ -3926,8 +3973,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; @@ -3946,8 +3993,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; @@ -3967,7 +4014,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); @@ -3976,7 +4023,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); @@ -3985,8 +4032,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); @@ -3995,8 +4042,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); @@ -4006,7 +4053,8 @@ describe("Extension Unit Tests", () => { describe("Pasting Data Sets", () => { it("Should call zowe.Copy.dataSet when pasting to sequential data set", async () => { const copySpy = jest.spyOn(mvsApi, "copyDataSetMember"); - const node = new ZoweNode("HLQ.TEST.TO.NODE", vscode.TreeItemCollapsibleState.None, sessNode, null, undefined, undefined, profileOne); + const node = new ZoweDatasetNode("HLQ.TEST.TO.NODE", vscode.TreeItemCollapsibleState.None, sessNode, + null, undefined, undefined, profileOne); node.contextValue = extension.DS_SESSION_CONTEXT; clipboard.writeText(JSON.stringify({ dataSetName: "HLQ.TEST.BEFORE.NODE", profileName: profileOne.name })); @@ -4020,7 +4068,8 @@ 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, undefined, undefined, profileOne); + const node = new ZoweDatasetNode("HLQ.TEST.TO.NODE", vscode.TreeItemCollapsibleState.None, sessNode, + null, undefined, undefined, profileOne); node.contextValue = extension.DS_SESSION_CONTEXT; clipboard.writeText("INVALID"); try { @@ -4037,7 +4086,8 @@ describe("Extension Unit Tests", () => { dataSetGet.mockImplementation(() => { throw Error("Member not found"); }); - const node = new ZoweNode("HLQ.TEST.TO.NODE", vscode.TreeItemCollapsibleState.None, sessNode, null, undefined, undefined, profileOne); + const node = new ZoweDatasetNode("HLQ.TEST.TO.NODE", vscode.TreeItemCollapsibleState.None, sessNode, + null, undefined, undefined, profileOne); node.contextValue = extension.DS_PDS_CONTEXT; clipboard.writeText(JSON.stringify({ dataSetName: "HLQ.TEST.BEFORE.NODE", profileName: "sestest" })); @@ -4051,7 +4101,8 @@ describe("Extension Unit Tests", () => { }); const spy2 = jest.spyOn(mvsApi, "copyDataSetMember"); - const node = new ZoweNode("HLQ.TEST.TO.NODE", vscode.TreeItemCollapsibleState.None, sessNode, null, undefined, undefined, profileOne); + const node = new ZoweDatasetNode("HLQ.TEST.TO.NODE", vscode.TreeItemCollapsibleState.None, + sessNode, null, undefined, undefined, profileOne); node.contextValue = extension.DS_PDS_CONTEXT; showInputBox.mockResolvedValueOnce("mem1"); @@ -4077,7 +4128,7 @@ describe("Extension Unit Tests", () => { }; let error; jest.spyOn(mvsApi, "getContents").mockImplementationOnce(async () => testResponse); - 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"); @@ -4102,10 +4153,10 @@ 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, undefined, undefined, profileOne); 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, undefined, undefined, profileOne); findNonFavoritedNode.mockImplementation(() => nonFavoritedNode); diff --git a/__tests__/__unit__/mvs/mvsNodeActions.unit.test.ts b/__tests__/__unit__/mvs/mvsNodeActions.unit.test.ts index 939144aed5..b9fd5d1f22 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"; import * as brtimperative from "@brightside/imperative"; @@ -44,15 +44,18 @@ const session = new brtimperative.Session({ }); const testTree = DatasetTree(); -const sessNode = new ZoweNode("sestest", vscode.TreeItemCollapsibleState.Expanded, null, session); +const profileOne: brtimperative.IProfileLoaded = { name: "profile1", profile: {}, type: "zosmf", message: "", failNotFound: false }; +const sessNode = new ZoweDatasetNode("sestest", vscode.TreeItemCollapsibleState.Expanded, null, session, undefined, undefined, profileOne); describe("mvsNodeActions", () => { afterEach(() => { jest.resetAllMocks(); }); + // TODO this test is actually throwing an error biut gets away with it from the tests perspective it("should call upload dialog and upload file", async () => { - const node = new ZoweNode("node", vscode.TreeItemCollapsibleState.Collapsed, sessNode, null); - const nodeAsFavorite = new ZoweNode("[sestest]: node", vscode.TreeItemCollapsibleState.Collapsed, sessNode, null, extension.PDS_FAV_CONTEXT); + const node = new ZoweDatasetNode("node", vscode.TreeItemCollapsibleState.Collapsed, sessNode, null, null, null, profileOne); + const nodeAsFavorite = new ZoweDatasetNode("[sestest]: node", vscode.TreeItemCollapsibleState.Collapsed, + sessNode, null, null, extension.PDS_FAV_CONTEXT, profileOne); testTree.mFavorites.push(nodeAsFavorite); const fileUri = {fsPath: "/tmp/foo"}; @@ -68,8 +71,9 @@ describe("mvsNodeActions", () => { expect(testTree.refreshElement).toBeCalledWith(nodeAsFavorite); }); it("should call upload dialog and upload file (from favorites)", async () => { - const node = new ZoweNode("node", vscode.TreeItemCollapsibleState.Collapsed, sessNode, null); - const nodeAsFavorite = new ZoweNode("[sestest]: node", vscode.TreeItemCollapsibleState.Collapsed, sessNode, null, extension.PDS_FAV_CONTEXT); + const node = new ZoweDatasetNode("node", vscode.TreeItemCollapsibleState.Collapsed, sessNode, null); + const nodeAsFavorite = new ZoweDatasetNode("[sestest]: node", vscode.TreeItemCollapsibleState.Collapsed, + sessNode, null, extension.PDS_FAV_CONTEXT); testTree.mFavorites.push(nodeAsFavorite); const fileUri = {fsPath: "/tmp/foo"}; @@ -90,16 +94,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 2189e5b14f..4971596f55 100644 --- a/__tests__/__unit__/uss/ussNodeActions.unit.test.ts +++ b/__tests__/__unit__/uss/ussNodeActions.unit.test.ts @@ -31,8 +31,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(); @@ -57,11 +57,10 @@ const profileOne: brtimperative.IProfileLoaded = { }; function getUSSNode() { - const ussNode1 = new ZoweUSSNode("usstest", vscode.TreeItemCollapsibleState.Expanded, null, session, null, false, profileOne.name); const mParent = new ZoweUSSNode("parentNode", vscode.TreeItemCollapsibleState.Expanded, null, session, null, false, profileOne.name); + const ussNode1 = new ZoweUSSNode("usstest", vscode.TreeItemCollapsibleState.Expanded, mParent, session, null, false, profileOne.name); ussNode1.contextValue = extension.USS_SESSION_CONTEXT; ussNode1.fullPath = "/u/myuser"; - ussNode1.mParent = mParent; return ussNode1; } @@ -72,7 +71,6 @@ function getFavoriteUSSNode() { 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; } @@ -88,8 +86,8 @@ function getUSSTree() { refreshAll: mockUSSRefresh, refreshElement: mockUSSRefreshElement, getChildren: mockGetUSSChildren, - addUSSFavorite: mockAddUSSFavorite, - removeUSSFavorite: mockRemoveUSSFavorite, + addFavorite: mockAddFavorite, + removeFavorite: mockRemoveFavorite, initializeUSSFavorites: mockInitializeFavorites }; }); @@ -318,20 +316,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 () => { @@ -341,7 +340,7 @@ describe("ussNodeActions", () => { throw (Error("testError")); }); try { - await ussNodeActions.deleteUSSNode(ussNode, testUSSTree, ""); + await ussNode.deleteUSSNode(testUSSTree, ""); // tslint:disable-next-line:no-empty } catch (err) { } @@ -392,17 +391,18 @@ describe("ussNodeActions", () => { await ussNodeActions.renameUSSNode(ussNode, testUSSTree, "file"); expect(testUSSTree.refreshElement).not.toHaveBeenCalled(); }); - it("should execute rename favorite USS file", async () => { - resetMocks(); - resetNode(ussNode); - - showInputBox.mockReturnValueOnce("new name"); - await ussNodeActions.renameUSSNode(ussFavNode, testUSSTree, "file"); - 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); - }); + // TODO CHeck this has been duplicated + // it("should execute rename favorite USS file", async () => { + // resetMocks(); + // resetNode(ussNode); + + // showInputBox.mockReturnValueOnce("new name"); + // await ussNodeActions.renameUSSNode(ussFavNode, testUSSTree, "file"); + // 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); + // }); it("should attempt to rename USS file but throw an error", async () => { resetMocks(); resetNode(ussNode); @@ -416,6 +416,15 @@ describe("ussNodeActions", () => { } expect(showErrorMessage.mock.calls.length).toBe(1); }); + it("should execute rename favorite USS file", async () => { + showInputBox.mockReturnValueOnce("new name"); + await ussNodeActions.renameUSSNode(ussFavNode, testUSSTree, "file"); + expect(testUSSTree.refresh).toHaveBeenCalled(); + expect(showErrorMessage.mock.calls.length).toBe(0); + expect(renameUSSFile.mock.calls.length).toBe(1); + expect(mockRemoveFavorite.mock.calls.length).toBe(1); + expect(mockAddFavorite.mock.calls.length).toBe(1); + }); }); describe("uploadFile", () => { Object.defineProperty(zowe, "Upload", {value: Upload}); diff --git a/i18n/sample/src/DatasetTree.i18n.json b/i18n/sample/src/DatasetTree.i18n.json index 69d9cf34ba..8eacbf11ae 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/USSTree.i18n.json b/i18n/sample/src/USSTree.i18n.json index 487fd3efd4..9c81949265 100644 --- a/i18n/sample/src/USSTree.i18n.json +++ b/i18n/sample/src/USSTree.i18n.json @@ -1,7 +1,7 @@ { "Favorites": "Favorites", - "ussTree.error": "Error encountered in ", "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/ZosJobsProvider.i18n.json b/i18n/sample/src/ZosJobsProvider.i18n.json index a087003b6a..8f2e64e936 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/ZoweDatasetNode.i18n.json b/i18n/sample/src/ZoweDatasetNode.i18n.json new file mode 100644 index 0000000000..878421c64a --- /dev/null +++ b/i18n/sample/src/ZoweDatasetNode.i18n.json @@ -0,0 +1,8 @@ +{ + "getChildren.search": "Use the search button to display datasets", + "getChildren.error.invalidNode": "Invalid node", + "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.error.response": "Retrieving response from " +} \ No newline at end of file diff --git a/i18n/sample/src/ZoweUSSNode.i18n.json b/i18n/sample/src/ZoweUSSNode.i18n.json index 761a683fd7..bf64b58b39 100644 --- a/i18n/sample/src/ZoweUSSNode.i18n.json +++ b/i18n/sample/src/ZoweUSSNode.i18n.json @@ -3,5 +3,17 @@ "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" + "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: ", + "openUSS.error.invalidNode": "open() called from invalid node.", + "refreshUSS.error.invalidNode": "refreshPS() called from invalid node.", + "refreshUSS.error.notFound": "not found", + "refreshUSS.file1": "Unable to find file: ", + "refreshUSS.file2": " was probably deleted.", + "openUSS.log.info.failedToOpenAsText.yes": "Yes, re-download", + "openUSS.log.info.failedToOpenAsText.no": "No", + "openUSS.log.info.failedToOpenAsText": "Failed to open file as text. Do you want to try with re-downloading it as binary?" } \ No newline at end of file diff --git a/i18n/sample/src/extension.i18n.json b/i18n/sample/src/extension.i18n.json index 7f6befa032..afe7392b22 100644 --- a/i18n/sample/src/extension.i18n.json +++ b/i18n/sample/src/extension.i18n.json @@ -77,10 +77,6 @@ "refreshPS.error.notFound": "not found", "refreshPS.file1": "Unable to find file: ", "refreshPS.file2": " was probably deleted.", - "refreshUSS.error.invalidNode": "refreshPS() called from invalid node.", - "refreshUSS.error.notFound": "not found", - "refreshUSS.file1": "Unable to find file: ", - "refreshUSS.file2": " was probably deleted.", "saveFile.log.debug.request": "requested to save data set: ", "saveFile.log.debug.path": "path.relative returned a non-blank directory.", "saveFile.log.debug.directory": "Assuming we are not in the DS_DIR directory: ", @@ -95,12 +91,6 @@ "saveUSSFile.log.debug.saveRequest": "save requested for USS file ", "saveUSSFile.response.title": "Saving file...", "saveUSSFile.log.error.save": "Error encountered when saving USS file: ", - "openUSS.error.invalidNode": "open() called from invalid node.", - "openUSS.log.debug.request": "requesting to open a uss file ", - "openUSS.log.error.openFile": "Error encountered when opening USS file: ", - "openUSS.log.info.failedToOpenAsText.yes": "Yes, re-download", - "openUSS.log.info.failedToOpenAsText.no": "No", - "openUSS.log.info.failedToOpenAsText": "Failed to open file as text. Do you want to try with re-downloading it as binary?", "modifyCommand.command.prompt": "Modify Command", "modifyCommand.response": "Command response: ", "stopCommand.response": "Command response: ", diff --git a/i18n/sample/src/uss/ussNodeActions.i18n.json b/i18n/sample/src/uss/ussNodeActions.i18n.json index 9cdd53d521..ed3698b7e6 100644 --- a/i18n/sample/src/uss/ussNodeActions.i18n.json +++ b/i18n/sample/src/uss/ussNodeActions.i18n.json @@ -2,10 +2,6 @@ "createUSSNode.name": "Name of file or directory", "createUSSNode.error.create": "Unable to create node: ", "ussNodeActions.error": "Error encountered in ", - "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: ", "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 b53ddabe5c..66ca9bf157 100644 --- a/src/DatasetTree.ts +++ b/src/DatasetTree.ts @@ -15,12 +15,13 @@ 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 { ZoweExplorerApiRegister } from "./api/ZoweExplorerApiRegister"; import { sortTreeItems, applyIcons, FilterDescriptor, FilterItem, getAppName, resolveQuickPickHelper, errorHandling } from "./utils"; -import { IZoweTree } from "./ZoweTree"; -import { ZoweNode } from "./ZoweNode"; +import { IZoweTree } from "./api/IZoweTree"; +import { IZoweDatasetTreeNode } from "./api/IZoweTreeNode"; +import { ZoweTreeProvider } from "./abstract/ZoweTreeProvider"; +import { ZoweDatasetNode } from "./ZoweDatasetNode"; const localize = nls.config({ messageFormat: nls.MessageFormat.file })(); /** @@ -42,31 +43,41 @@ 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("defaultFilterPrompt.option.prompt.search", "Create a new filter. Comma separate multiple entries (pattern 1, pattern 2, ...)"); - public mSessionNodes: ZoweNode[]; - public mFavoriteSession: ZoweNode; - public mFavorites: ZoweNode[] = []; + public mFavoriteSession: 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; - private treeView: vscode.TreeView; - private mHistory: PersistentFilters; - private log: Logger; - private validProfile: number = -1; + public mSessionNodes: IZoweDatasetTreeNode[] = []; + public mFavorites: IZoweDatasetTreeNode[] = []; + private treeView: vscode.TreeView; constructor() { - this.mFavoriteSession = new ZoweNode(localize("FavoriteSession", "Favorites"), vscode.TreeItemCollapsibleState.Collapsed, null, null); + super(DatasetTree.persistenceSchema, new ZoweDatasetNode(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); this.treeView = vscode.window.createTreeView("zowe.explorer", {treeDataProvider: this}); } + /** + * 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; + } + /** * Initializes the tree based on favorites held in persistent store * @@ -88,12 +99,12 @@ export class DatasetTree implements IZoweTree { try { const profile = Profiles.getInstance().loadNamedProfile(sesName); const session = ZoweExplorerApiRegister.getMvsApi(profile).getSession(); - let node: ZoweNode; + let node: ZoweDatasetNode; if (line.substring(line.indexOf("{") + 1, line.lastIndexOf("}")) === extension.DS_PDS_CONTEXT) { - node = new ZoweNode(line.substring(0, line.indexOf("{")), vscode.TreeItemCollapsibleState.Collapsed, + node = new ZoweDatasetNode(line.substring(0, line.indexOf("{")), vscode.TreeItemCollapsibleState.Collapsed, this.mFavoriteSession, session, undefined, undefined, profile); } else { - node = new ZoweNode(line.substring(0, line.indexOf("{")), vscode.TreeItemCollapsibleState.None, + node = new ZoweDatasetNode(line.substring(0, line.indexOf("{")), vscode.TreeItemCollapsibleState.None, this.mFavoriteSession, session, undefined, undefined, profile); node.command = { command: "zowe.ZoweNode.openPS", title: "", arguments: [node] }; } @@ -127,7 +138,7 @@ export class DatasetTree implements IZoweTree { continue; } const session = ZoweExplorerApiRegister.getMvsApi(profile).getSession(); - const node = new ZoweNode(line.substring(0, line.lastIndexOf("{")), + const node = new ZoweDatasetNode(line.substring(0, line.lastIndexOf("{")), vscode.TreeItemCollapsibleState.None, this.mFavoriteSession, session, undefined, undefined, profile); node.command = { command: "zowe.pattern", title: "", arguments: [node] }; const light = path.join(__dirname, "..", "..", "resources", "light", "pattern.svg"); @@ -142,68 +153,15 @@ 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; - } - /** * Returns the tree view for the current DatasetTree * * @returns {vscode.TreeView} */ - public getTreeView(): vscode.TreeView { + public getTreeView(): vscode.TreeView { return this.treeView; } - /** - * 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 * @@ -239,9 +197,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("[")) { @@ -254,27 +212,27 @@ export class DatasetTree implements IZoweTree { /** * Adds a node to the favorites list * - * @param {ZoweNode} node + * @param {IZoweDatasetTreeNode} node */ - public async addFavorite(node: ZoweNode) { - let temp: ZoweNode; + public async addFavorite(node: IZoweDatasetTreeNode) { + let temp: ZoweDatasetNode; 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, - this.mFavoriteSession, node.getSession(), node.contextValue, node.getEtag(), node.profile); + temp = new ZoweDatasetNode("[" + node.getSessionNode().label.trim() + "]: " + node.pattern, vscode.TreeItemCollapsibleState.None, + this.mFavoriteSession, node.getSession(), node.contextValue, node.getEtag(), node.getProfile()); temp.contextValue = extension.DS_SESSION_CONTEXT + extension.FAV_SUFFIX; temp.iconPath = applyIcons(temp); // add a command to execute the search temp.command = { command: "zowe.pattern", title: "", arguments: [temp] }; } else { // pds | ds - temp = new ZoweNode("[" + node.getSessionNode().label.trim() + "]: " + node.label, node.collapsibleState, - this.mFavoriteSession, node.getSession(), node.contextValue, node.getEtag(), node.profile); + temp = new ZoweDatasetNode("[" + node.getSessionNode().label.trim() + "]: " + node.label, node.collapsibleState, + this.mFavoriteSession, node.getSession(), node.contextValue, node.getEtag(), node.getProfile()); temp.contextValue += extension.FAV_SUFFIX; if (temp.contextValue === extension.DS_DS_CONTEXT + extension.FAV_SUFFIX) { temp.command = { command: "zowe.ZoweNode.openPS", title: "", arguments: [temp] }; @@ -313,9 +271,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)) ); @@ -329,19 +287,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); @@ -351,9 +309,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))) ); @@ -370,15 +328,15 @@ export class DatasetTree implements IZoweTree { } 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); + 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); @@ -389,7 +347,7 @@ export class DatasetTree implements IZoweTree { return this.mHistory.getHistory(); } - 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; @@ -478,7 +436,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; @@ -500,57 +458,6 @@ export class DatasetTree 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 - */ - public async flipState(element: ZoweNode, 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) { - await errorHandling(error, element.getProfileName(), localize("datasetTree.error", "Error encountered in ") + `flipState.optionalProfiles!`); - } - 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); - } - } - /** * Adds a single session to the data set tree * @@ -564,7 +471,7 @@ export class DatasetTree implements IZoweTree { // Uses loaded profile to create a session with the MVS API const session = ZoweExplorerApiRegister.getMvsApi(profile).getSession(); // Creates ZoweNode to track new session and pushes it to mSessionNodes - const node = new ZoweNode( + const node = new ZoweDatasetNode( profile.name, vscode.TreeItemCollapsibleState.Collapsed, null, session, undefined, undefined, profile); node.contextValue = extension.DS_SESSION_CONTEXT; node.iconPath = applyIcons(node); diff --git a/src/USSTree.ts b/src/USSTree.ts index 17fa747a3d..794f248766 100644 --- a/src/USSTree.ts +++ b/src/USSTree.ts @@ -12,13 +12,14 @@ import { IProfileLoaded, Logger } from "@brightside/imperative"; import { applyIcons, FilterItem, FilterDescriptor, getAppName, resolveQuickPickHelper, sortTreeItems, errorHandling } from "./utils"; import * as vscode from "vscode"; -import { IZoweTree } from "./ZoweTree"; +import { IZoweTree } from "./api/IZoweTree"; +import { IZoweUSSTreeNode } from "./api/IZoweTreeNode"; import { ZoweUSSNode } from "./ZoweUSSNode"; import { Profiles } from "./Profiles"; -import { PersistentFilters } from "./PersistentFilters"; -import { ZoweExplorerApiRegister } from "./api/ZoweExplorerApiRegister"; import * as extension from "../src/extension"; import * as nls from "vscode-nls"; +import { ZoweTreeProvider } from "./abstract/ZoweTreeProvider"; +import { ZoweExplorerApiRegister } from "./api/ZoweExplorerApiRegister"; const localize = nls.config({ messageFormat: nls.MessageFormat.file })(); @@ -41,60 +42,40 @@ 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 treeView: vscode.TreeView; - - private mHistory: PersistentFilters; - private log: Logger; - private validProfile: number = -1; + public mSessionNodes: IZoweUSSTreeNode[] = []; + public mFavorites: IZoweUSSTreeNode[] = []; + private treeView: vscode.TreeView; 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); + this.mSessionNodes = [this.mFavoriteSession as IZoweUSSTreeNode]; this.treeView = vscode.window.createTreeView("zowe.uss.explorer", {treeDataProvider: this}); } - /** - * 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; - } - /** * Returns the tree view for the current USSTree * * @returns {vscode.TreeView} */ - public getTreeView(): vscode.TreeView { + public getTreeView(): vscode.TreeView { return this.treeView; } /** - * 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; @@ -104,33 +85,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 * @@ -166,9 +120,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("[")) { @@ -181,17 +135,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) { @@ -209,12 +163,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; @@ -232,9 +186,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(); @@ -245,81 +199,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) { - await errorHandling(error, element.getProfileName(), localize("ussTree.error", "Error encountered in ") + `flipState.optionalProfiles!`); - } - 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")); } @@ -330,7 +222,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]; @@ -411,7 +303,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; @@ -425,7 +317,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 53f58c5715..ec82a68ec8 100644 --- a/src/ZosJobsProvider.ts +++ b/src/ZosJobsProvider.ts @@ -10,11 +10,10 @@ */ import * as vscode from "vscode"; -import { ZosmfSession, IJob } 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, @@ -28,7 +27,9 @@ import { errorHandling, labelHack } from "./utils"; -import { IZoweTree } from "./ZoweTree"; +import { IZoweTree } from "./api/IZoweTree"; +import { IZoweJobTreeNode } from "./api/IZoweTreeNode"; +import { ZoweTreeProvider } from "./abstract/ZoweTreeProvider"; import * as extension from "../src/extension"; import * as nls from "vscode-nls"; import { ZoweExplorerApiRegister } from "./api/ZoweExplorerApiRegister"; @@ -50,38 +51,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 treeView: vscode.TreeView; - - private validProfile: number = -1; - private mHistory: PersistentFilters; - private log: Logger; + private treeView: vscode.TreeView; constructor() { - this.mFavoriteSession = new Job(localize("FavoriteSession", "Favorites"), vscode.TreeItemCollapsibleState.Collapsed, null, null, null, null); + super(ZosJobsProvider.persistenceSchema, + new Job(localize("Favorites", "Favorites"), vscode.TreeItemCollapsibleState.Collapsed, null, 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); this.treeView = vscode.window.createTreeView("zowe.jobs", {treeDataProvider: this}); } - 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 === "") { @@ -95,23 +94,15 @@ export class ZosJobsProvider implements IZoweTree { return this.mSessionNodes; } - public getTreeItem(element: Job): vscode.TreeItem | Thenable { - return element; - } - /** * Returns the tree view for the current JobTree * * @returns {vscode.TreeView} */ - public getTreeView(): vscode.TreeView { + public getTreeView(): vscode.TreeView { return this.treeView; } - public getParent(element: Job): Job { - return element.mParent; - } - /** * Adds a session to the data set tree * @@ -144,104 +135,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 ZoweExplorerApiRegister.getJesApi(node.profile).deleteJob(node.job.jobname, node.job.jobid); + await ZoweExplorerApiRegister.getJesApi(node.getProfile()).deleteJob(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) { await errorHandling(error, node.getProfileName(), 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) { - await errorHandling(error, element.getProfileName(), 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 @@ -294,9 +197,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); @@ -309,13 +212,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, node.profile); + vscode.TreeItemCollapsibleState.None, node.getParent(), node.getSession(), node.job, node.getProfile()); favJob.owner = node.owner; favJob.prefix = node.prefix; favJob.searchId = node.searchId; @@ -332,9 +235,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)))); @@ -358,10 +261,10 @@ export class ZosJobsProvider implements IZoweTree { /** * 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; @@ -374,7 +277,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) { @@ -386,9 +289,9 @@ export class ZosJobsProvider implements IZoweTree { await errorHandling(error, node.getProfileName(), 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 { @@ -507,10 +410,10 @@ 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); } @@ -534,10 +437,9 @@ export class ZosJobsProvider implements IZoweTree { } } - 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()); } /** @@ -599,12 +501,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 = "*"; @@ -630,10 +533,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, node.profile); + vscode.TreeItemCollapsibleState.Collapsed, node.getParent(), node.getSession(), node.job, node.getProfile()); 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/ZoweDatasetNode.ts b/src/ZoweDatasetNode.ts new file mode 100644 index 0000000000..97c682fe98 --- /dev/null +++ b/src/ZoweDatasetNode.ts @@ -0,0 +1,202 @@ +/* +* 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 zowe from "@brightside/core"; +import * as vscode from "vscode"; +import { Session, IProfileLoaded } from "@brightside/imperative"; +import * as nls from "vscode-nls"; +import * as utils from "./utils"; +import * as extension from "./extension"; +import { IZoweDatasetTreeNode } from "./api/IZoweTreeNode"; +import { ZoweTreeNode } from "./abstract/ZoweTreeNode"; +import { ZoweExplorerApiRegister } from "./api/ZoweExplorerApiRegister"; +const localize = nls.config({ messageFormat: nls.MessageFormat.file })(); + +/** + * A type of TreeItem used to represent sessions and data sets + * + * @export + * @class ZoweDatasetNode + * @extends {vscode.TreeItem} + */ +export class ZoweDatasetNode extends ZoweTreeNode implements IZoweDatasetTreeNode { + public command: vscode.Command; + public pattern = ""; + public dirty = extension.ISTHEIA; // Make sure this is true for theia instances + public children: ZoweDatasetNode[] = []; + + /** + * Creates an instance of ZoweDatasetNode + * + * @param {string} label - Displayed in the [TreeView] + * @param {vscode.TreeItemCollapsibleState} mCollapsibleState - file/folder + * @param {ZoweDatasetNode} mParent + * @param {Session} session + */ + constructor(label: string, + collapsibleState: vscode.TreeItemCollapsibleState, + mParent: IZoweDatasetTreeNode, + session: Session, + contextOverride?: string, + private etag?: string, + profile?: IProfileLoaded) { + super(label, collapsibleState, mParent, session, profile); + + if (contextOverride) { + this.contextValue = contextOverride; + } else if (collapsibleState !== vscode.TreeItemCollapsibleState.None) { + this.contextValue = extension.DS_PDS_CONTEXT; + } else if (mParent && mParent.getParent()) { + this.contextValue = extension.DS_MEMBER_CONTEXT; + } else { + this.contextValue = extension.DS_DS_CONTEXT; + } + this.tooltip = this.label; + utils.applyIcons(this); + } + + /** + * Implements access to profile name + * for {IZoweDatasetTreeNode}. + * + * @returns {string} + */ + public getProfileName(): string { + return this.getProfile() ? this.getProfile().name : undefined; + } + + /** + * Retrieves child nodes of this ZoweDatasetNode + * + * @returns {Promise} + */ + public async getChildren(): Promise { + if ((!this.pattern && this.contextValue === extension.DS_SESSION_CONTEXT)){ + return [new ZoweDatasetNode(localize("getChildren.search", "Use the search button to display datasets"), + vscode.TreeItemCollapsibleState.None, this, null, extension.INFORMATION_CONTEXT)]; + } + + if (this.contextValue === extension.DS_DS_CONTEXT || + this.contextValue === extension.DS_MEMBER_CONTEXT || + this.contextValue === extension.INFORMATION_CONTEXT) { + return []; + } + + if (!this.dirty || this.label === "Favorites") { + return this.children; + } + + if (!this.label) { + vscode.window.showErrorMessage(localize("getChildren.error.invalidNode", "Invalid node")); + throw Error(localize("getChildren.error.invalidNode", "Invalid node")); + } + + // Gets the datasets from the pattern or members of the dataset and displays any thrown errors + let responses: zowe.IZosFilesResponse[] = []; + responses = await vscode.window.withProgress({ + location: vscode.ProgressLocation.Notification, + title: localize("ZoweJobNode.getJobs.progress", "Get Dataset list command submitted.") + }, () => { + return this.getDatasets(); + }); + + // push nodes to an object with property names to avoid duplicates + const elementChildren = {}; + responses.forEach((response) => { + // Throws reject if the brightside command does not throw an error but does not succeed + if (!response.success) { + throw Error(localize("getChildren.responses.error", "The response from Zowe CLI was not successful")); + } + + // Loops through all the returned dataset members and creates nodes for them + for (const item of response.apiResponse.items) { + const existing = this.children.find((element) => element.label.trim() === item.dsname ); + if (existing) { + elementChildren[existing.label] = existing; + // Creates a ZoweDatasetNode for a PDS + } else if (item.dsorg === "PO" || item.dsorg === "PO-E") { + const temp = new ZoweDatasetNode(item.dsname, vscode.TreeItemCollapsibleState.Collapsed, + this, null, undefined, undefined, this.getProfile()); + elementChildren[temp.label] = temp; + } else if (item.migr && item.migr.toUpperCase() === "YES") { + const temp = new ZoweDatasetNode(item.dsname, vscode.TreeItemCollapsibleState.None, + this, null, extension.DS_MIGRATED_FILE_CONTEXT, + undefined, this.getProfile()); + elementChildren[temp.label] = temp; + } else if (this.contextValue === extension.DS_SESSION_CONTEXT) { + // Creates a ZoweDatasetNode for a PS + const temp = new ZoweDatasetNode(item.dsname, vscode.TreeItemCollapsibleState.None, + this, null, undefined, undefined, this.getProfile()); + temp.command = {command: "zowe.ZoweNode.openPS", title: "", arguments: [temp]}; + elementChildren[temp.label] = temp; + } else { + // Creates a ZoweDatasetNode for a PDS member + const temp = new ZoweDatasetNode(item.member, vscode.TreeItemCollapsibleState.None, + this, null, undefined, undefined, this.getProfile()); + temp.command = {command: "zowe.ZoweNode.openPS", title: "", arguments: [temp]}; + elementChildren[temp.label] = temp; + } + } + }); + + this.dirty = false; + if (Object.keys(elementChildren).length === 0) { + 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]); + } + } + + public getSessionNode(): IZoweDatasetTreeNode { + return this.getParent() ? this.getParent().getSessionNode() : this; + } + /** + * Returns the [etag] for this node + * + * @returns {string} + */ + public getEtag(): string { + return this.etag; + } + + /** + * Set the [etag] for this node + * + * @returns {void} + */ + public setEtag(etagValue): void { + this.etag = etagValue; + } + + private async getDatasets(): Promise { + const 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 ZoweExplorerApiRegister.getMvsApi(this.getProfile()).dataSet(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 ZoweExplorerApiRegister.getMvsApi(this.getProfile()).allMembers(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 5e40072b34..5c643f0736 100644 --- a/src/ZoweJobNode.ts +++ b/src/ZoweJobNode.ts @@ -11,24 +11,26 @@ import * as vscode from "vscode"; import * as zowe from "@brightside/core"; -import { Session, IProfileLoaded, Logger } from "@brightside/imperative"; +import { Session, IProfileLoaded } 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/IZoweTreeNode"; +import { ZoweTreeNode } from "./abstract/ZoweTreeNode"; import * as utils from "./utils"; import { ZoweExplorerApiRegister } from "./api/ZoweExplorerApiRegister"; 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 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 @@ -36,14 +38,13 @@ 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, - public profile: IProfileLoaded) { - super(label, mCollapsibleState); + constructor(label: string, + collapsibleState: vscode.TreeItemCollapsibleState, + mParent: IZoweJobTreeNode, + session: Session, + public job: IJob, + profile: IProfileLoaded) { + super(label, collapsibleState, mParent, session, profile); if (session) { this._owner = session.ISession.user; } @@ -53,28 +54,11 @@ export class Job extends vscode.TreeItem implements IZoweTreeNode { } /** - * Implements access to profile name - * for {IZoweTreeNode}. + * Retrieves child nodes of this IZoweJobTreeNode * - * @returns {string} + * @returns {Promise} */ - public getProfileName(): string { - return this.label.trim(); - } - - 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 { + public async getChildren(): Promise { if (this.dirty) { let spools: zowe.IJobFile[] = []; const elementChildren = []; @@ -83,7 +67,7 @@ export class Job extends vscode.TreeItem implements IZoweTreeNode { location: vscode.ProgressLocation.Notification, title: localize("ZoweJobNode.getJobs.spoolfiles", "Get Job Spool files command submitted.") }, () => { - return ZoweExplorerApiRegister.getJesApi(this.profile).getSpoolFiles(this.job.jobname, this.job.jobid); + return ZoweExplorerApiRegister.getJesApi(this.getProfile()).getSpoolFiles(this.job.jobname, this.job.jobid); }); spools.forEach((spool) => { const existing = this.children.find((element) => element.label.trim() === `${spool.stepname}:${spool.ddname}(${spool.id})` ); @@ -96,7 +80,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); @@ -122,7 +106,7 @@ export class Job extends vscode.TreeItem implements IZoweTreeNode { if (existing) { elementChildren.push(existing); } else { - const jobNode = new Job(nodeTitle, vscode.TreeItemCollapsibleState.Collapsed, this, this.session, job, this.profile); + const jobNode = new Job(nodeTitle, vscode.TreeItemCollapsibleState.Collapsed, this, this.session, job, this.getProfile()); jobNode.command = { command: "zowe.zosJobsSelectjob", title: "", arguments: [jobNode] }; jobNode.contextValue = extension.JOBS_JOB_CONTEXT; if (!jobNode.iconPath) { @@ -143,10 +127,8 @@ export class Job extends vscode.TreeItem implements IZoweTreeNode { return this.children; } - public reset() { - utils.labelHack(this); - this.children = []; - this.dirty = true; + public getSessionNode(): IZoweJobTreeNode { + return this.getParent() ? this.getParent().getSessionNode() : this; } get tooltip(): string { @@ -191,23 +173,23 @@ 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; } private async getJobs(owner, prefix, searchId): Promise { let jobsInternal: zowe.IJob[] = []; if (this.searchId.length > 0 ) { - jobsInternal.push(await ZoweExplorerApiRegister.getJesApi(this.profile).getJob(searchId)); + jobsInternal.push(await ZoweExplorerApiRegister.getJesApi(this.getProfile()).getJob(searchId)); } else { try { - jobsInternal = await ZoweExplorerApiRegister.getJesApi(this.profile).getJobsByOwnerAndPrefix(owner, prefix); + jobsInternal = await ZoweExplorerApiRegister.getJesApi(this.getProfile()).getJobsByOwnerAndPrefix(owner, prefix); } catch (error) { await utils.errorHandling(error, this.label, localize("getChildren.error.response", "Retrieving response from ") + `zowe.GetJobs`); } @@ -218,9 +200,9 @@ export class Job extends vscode.TreeItem implements IZoweTreeNode { // 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) { - super(label, mCollapsibleState, mParent, session, job, parent.profile); + constructor(label: string, mCollapsibleState: vscode.TreeItemCollapsibleState, mParent: IZoweJobTreeNode, + session: Session, spool: IJobFile, job: IJob, parent: IZoweJobTreeNode) { + super(label, mCollapsibleState, mParent, session, job, parent.getProfile()); this.contextValue = extension.JOBS_SPOOL_CONTEXT; utils.applyIcons(this); } diff --git a/src/ZoweUSSNode.ts b/src/ZoweUSSNode.ts index ab123febd0..83a0c4fdd1 100644 --- a/src/ZoweUSSNode.ts +++ b/src/ZoweUSSNode.ts @@ -13,17 +13,20 @@ import * as zowe from "@brightside/core"; import { Session, IProfileLoaded } from "@brightside/imperative"; import * as vscode from "vscode"; import * as nls from "vscode-nls"; -import { IZoweTreeNode } from "./ZoweTree"; -// tslint:disable-next-line: no-duplicate-imports +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 * as path from "path"; +import { ZoweTreeNode } from "./abstract/ZoweTreeNode"; +import { IZoweTree } from "./api/IZoweTree"; import { getIconByNode } from "./generators/icons/index"; import * as moment from "moment"; import { injectAdditionalDataToTooltip } from "./utils/uss"; import { Profiles } from "./Profiles"; import { ZoweExplorerApiRegister } from "./api/ZoweExplorerApiRegister"; - -const localize = nls.config({messageFormat: nls.MessageFormat.file})(); +import { attachRecentSaveListener, disposeRecentSaveListener, getRecentSaveStatus } from "./utils/file"; /** * A type of TreeItem used to represent sessions and USS directories and files @@ -32,15 +35,16 @@ const localize = nls.config({messageFormat: nls.MessageFormat.file})(); * @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 = ""; public downloadedTime = null as string; - public profileName = ""; public profile: IProfileLoaded; // TODO: This reference should be stored instead of the name private downloadedInternal = false; @@ -49,20 +53,23 @@ 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 = "", + profile?: IProfileLoaded) { + super(label, collapsibleState, mParent, session, profile); + this.binary = binary; if (collapsibleState !== vscode.TreeItemCollapsibleState.None) { this.contextValue = extension.USS_DIR_CONTEXT; } else if (binary) { @@ -77,7 +84,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) @@ -88,10 +95,10 @@ export class ZoweUSSNode extends vscode.TreeItem implements IZoweTreeNode { } // TODO: this should not be necessary of each node gets initialized with the profile reference. if (mProfileName) { - this.profile = Profiles.getInstance().loadNamedProfile(mProfileName); + this.setProfile(Profiles.getInstance().loadNamedProfile(mProfileName)); } else if (mParent && mParent.mProfileName) { this.mProfileName = mParent.mProfileName; - this.profile = Profiles.getInstance().loadNamedProfile(mParent.mProfileName); + this.setProfile(Profiles.getInstance().loadNamedProfile(mParent.mProfileName)); } this.etag = etag ? etag : ""; utils.applyIcons(this); @@ -99,7 +106,7 @@ export class ZoweUSSNode extends vscode.TreeItem implements IZoweTreeNode { /** * Implements access to profile name - * for {IZoweTreeNode}. + * for {IZoweUSSTreeNode}. * * @returns {string} */ @@ -107,12 +114,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)) { @@ -138,7 +149,7 @@ export class ZoweUSSNode extends vscode.TreeItem implements IZoweTreeNode { location: vscode.ProgressLocation.Notification, title: localize("ZoweUssNode.getList.progress", "Get USS file list command submitted.") }, () => { - return ZoweExplorerApiRegister.getUssApi(this.profile).fileList(this.fullPath); + return ZoweExplorerApiRegister.getUssApi(this.getProfile()).fileList(this.fullPath); })); } catch (err) { utils.errorHandling(err, this.label, localize("getChildren.error.response", "Retrieving response from ") + `uss-file-list`); @@ -206,24 +217,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) { @@ -233,7 +226,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; } @@ -253,7 +246,7 @@ export class ZoweUSSNode extends vscode.TreeItem implements IZoweTreeNode { */ public get isDirtyInEditor(): boolean { const openedTextDocuments = vscode.workspace.textDocuments; - const currentFilePath = extension.getUSSDocumentFilePath(this); + const currentFilePath = this.getUSSDocumentFilePath(); for (const document of openedTextDocuments) { if (document.fileName === currentFilePath) { @@ -266,7 +259,7 @@ export class ZoweUSSNode extends vscode.TreeItem implements IZoweTreeNode { public get openedDocumentInstance(): vscode.TextDocument { const openedTextDocuments = vscode.workspace.textDocuments; - const currentFilePath = extension.getUSSDocumentFilePath(this); + const currentFilePath = this.getUSSDocumentFilePath(); for (const document of openedTextDocuments) { if (document.fileName === currentFilePath) { @@ -300,6 +293,38 @@ export class ZoweUSSNode extends vscode.TreeItem implements IZoweTreeNode { vscode.commands.executeCommand("zowe.uss.refreshUSSInTree", this); } + 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 * @@ -344,4 +369,197 @@ export class ZoweUSSNode extends vscode.TreeItem implements IZoweTreeNode { this.setIcon(icon.path); } } + /** + * Downloads and displays a file in a text editor view + * + * @param {IZoweTreeNode} node + */ + public async openUSS(download = false, previewFile: boolean, ussFileProvider?: IZoweTree) { + let usrNme: string; + let passWrd: string; + let baseEncd: string; + let validProfile: number = -1; + if ((!this.getSession().ISession.user) || (!this.getSession().ISession.password)) { + try { + const values = await Profiles.getInstance().promptCredentials(this.getProfileName()); + if (values !== undefined) { + usrNme = values[0]; + passWrd = values[1]; + baseEncd = values[2]; + } + } catch (error) { + await utils.errorHandling(error, this.getProfileName(), error.message); + } + if (usrNme !== undefined && passWrd !== undefined && baseEncd !== undefined) { + this.getSession().ISession.user = usrNme; + this.getSession().ISession.password = passWrd; + this.getSession().ISession.base64EncodedAuth = baseEncd; + validProfile = 0; + } else { + return; + } + await ussFileProvider.refreshElement(this); + await ussFileProvider.refresh(); + } else { + validProfile = 0; + } + if (validProfile === 0) { + try { + let label: string; + switch (this.getParent().contextValue) { + case (extension.FAVORITE_CONTEXT): + label = this.label.substring(this.label.indexOf(":") + 1).trim(); + break; + // Handle file path for files in directories and favorited directories + case (extension.USS_DIR_CONTEXT): + case (extension.USS_DIR_CONTEXT + extension.FAV_SUFFIX): + label = this.fullPath; + break; + case (extension.USS_SESSION_CONTEXT): + label = this.label; + break; + default: + vscode.window.showErrorMessage(localize("openUSS.error.invalidNode", "open() called from invalid node.")); + throw Error(localize("openUSS.error.invalidNode", "open() called from invalid node.")); + } + // if local copy exists, open that instead of pulling from mainframe + const documentFilePath = this.getUSSDocumentFilePath(); + if (download || !fs.existsSync(documentFilePath)) { + const profile = this.getProfile(); + const fullPath = this.fullPath; + const chooseBinary = this.binary || + await ZoweExplorerApiRegister.getUssApi(profile).isFileTagBinOrAscii(this.fullPath); + const response = await vscode.window.withProgress({ + location: vscode.ProgressLocation.Notification, + title: "Opening USS file..." + }, + function downloadUSSFile() { + return ZoweExplorerApiRegister.getUssApi(profile).getContents( + fullPath, { + file: documentFilePath, + binary: chooseBinary, + returnEtag: true + }); + } + ); + + this.downloaded = true; + this.setEtag(response.apiResponse.etag); + } + + await this.initializeFileOpening(documentFilePath, previewFile); + } catch (err) { + await utils.errorHandling(err, this.mProfileName, err.message); + throw (err); + } + } + } + /** + * Refreshes the passed node with current mainframe data + * + * @param {ZoweUSSNode} node - The node which represents the file + */ + public async refreshUSS() { + let label; + switch (this.getParent().contextValue) { + case (extension.USS_DIR_CONTEXT + extension.FAV_SUFFIX): + label = this.fullPath; + break; + case (extension.USS_DIR_CONTEXT): + label = this.fullPath; + break; + case (extension.USS_SESSION_CONTEXT): + label = this.label; + break; + default: + vscode.window.showErrorMessage(localize("refreshUSS.error.invalidNode", "refreshUSS() called from invalid node.")); + throw Error(localize("refreshUSS.error.invalidNode", "refreshPS() called from invalid node.")); + } + try { + const ussDocumentFilePath = this.getUSSDocumentFilePath(); + const isDirty = this.isDirtyInEditor; + let wasSaved = false; + + if (isDirty) { + attachRecentSaveListener(); + + vscode.window.showTextDocument(this.openedDocumentInstance); + await vscode.commands.executeCommand("workbench.action.closeActiveEditor"); + wasSaved = getRecentSaveStatus(); + + disposeRecentSaveListener(); + } + + if ((isDirty && !this.isDirtyInEditor && !wasSaved) || !isDirty) { + const response = await ZoweExplorerApiRegister.getUssApi(this.getProfile()).getContents(this.fullPath, { + file: ussDocumentFilePath, + returnEtag: true + }); + this.setEtag(response.apiResponse.etag); + this.downloaded = true; + + if (isDirty) { + await this.initializeFileOpening(ussDocumentFilePath, true); + } + } else if (wasSaved) { + await this.initializeFileOpening(ussDocumentFilePath, true); + } + } catch (err) { + if (err.message.includes(localize("refreshUSS.error.notFound", "not found"))) { + vscode.window.showInformationMessage(localize("refreshUSS.file1", "Unable to find file: ") + label + + localize("refreshUSS.file2", " was probably deleted.")); + } else { + await utils.errorHandling(err, this.mProfileName, err.message); + } + } + } + + public async initializeFileOpening(documentPath: string, previewFile?: boolean) { + let document; + let openingTextFailed = false; + + if (!this.binary) { + try { + document = await vscode.workspace.openTextDocument(documentPath); + } catch (err) { + openingTextFailed = true; + } + + if (openingTextFailed) { + const yesResponse = localize("openUSS.log.info.failedToOpenAsText.yes", "Yes, re-download"); + const noResponse = localize("openUSS.log.info.failedToOpenAsText.no", "No"); + + const response = await vscode.window.showErrorMessage( + localize( + "openUSS.log.info.failedToOpenAsText", + "Failed to open file as text. Do you want to try with re-downloading it as binary?"), + ...[ + yesResponse, + noResponse + ] + ); + + if (response === yesResponse.toString()) { + await vscode.commands.executeCommand("zowe.uss.binary", this); + } + } else { + if (previewFile === true) { + await vscode.window.showTextDocument(document); + } else { + await vscode.window.showTextDocument(document, {preview: false}); + } + } + } else { + const uriPath = vscode.Uri.file(documentPath); + await vscode.commands.executeCommand("vscode.open", uriPath); + } + } + + /** + * Returns the local file path for the ZoweUSSNode + * + */ + public getUSSDocumentFilePath() { + return path.join(extension.USS_DIR || "", "/" + this.getSessionNode().getProfileName() + "/", this.fullPath); + } } 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 new file mode 100644 index 0000000000..263327ee29 --- /dev/null +++ b/src/abstract/ZoweTreeNode.ts @@ -0,0 +1,110 @@ +/* +* 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, IProfileLoaded } from "@brightside/imperative"; +import { IZoweTreeNode } from "../api/IZoweTreeNode"; + +/** + * Common implementation of functions and methods associated with the + * IZoweTreeNode + * + * @export + * @class ZoweDatasetNode + * @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 ZoweDatasetNode + * + * @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, + protected profile: IProfileLoaded) { + super(label, collapsibleState); + // TODO Check this + if (!profile && mParent && mParent.getProfile()) { + this.profile = mParent.getProfile(); + } + } + + /** + * 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); + } + + /** + * Returns the IProfileLoaded profile for this node + * + * @returns {IProfileLoaded} + */ + public getProfile(): IProfileLoaded { + return (this.profile) ? this.profile : this.getParent() ? this.getParent().getProfile() : undefined; + } + + /** + * Implements access to profile name + * + * @returns {string} + */ + public getProfileName(): string { + if (this.profile) { + return this.profile.name; + } + return 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(); + } + + /** + * Sets the IProfileLoaded profile for this node. + * Only used by ZoweTreeNode and should be refactored out + * + * @param {IProfileLoaded} + */ + protected setProfile(aProfile: IProfileLoaded) { + this.profile = aProfile; + } +} diff --git a/src/abstract/ZoweTreeProvider.ts b/src/abstract/ZoweTreeProvider.ts new file mode 100644 index 0000000000..cb72efb7e0 --- /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/IZoweTreeNode"; +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/IZoweTree.ts b/src/api/IZoweTree.ts new file mode 100644 index 0000000000..0762ed88e1 --- /dev/null +++ b/src/api/IZoweTree.ts @@ -0,0 +1,72 @@ +/* +* 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; + /** + * Event Emitters used to notify subscribers that the refresh event has fired + */ + onDidChangeConfiguration(e: vscode.ConfigurationChangeEvent); + /** + * Change the state of an expandable node + * @param element the node being flipped + * @param isOpen the intended state of the the tree view provider, true or false + */ + flipState(element: IZoweTreeNode, isOpen: boolean); +} diff --git a/src/api/IZoweTreeNode.ts b/src/api/IZoweTreeNode.ts new file mode 100644 index 0000000000..d93f4ddf49 --- /dev/null +++ b/src/api/IZoweTreeNode.ts @@ -0,0 +1,250 @@ +/* +* 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, IProfileLoaded } from "@brightside/imperative"; +import { IJob } from "@brightside/core"; +import { IZoweTree } from "./IZoweTree"; + +/** + * The base interface for Zowe tree nodes that are implemented by vscode.TreeItem. + * + * @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; + /** + * Retrieves the profile object in use with this node + */ + getProfile(): IProfileLoaded; +} + +/** + * 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; + /** + * Specific profile name in use with this node + */ + mProfileName?: string; + /** + * 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); + /** + * Specifies the field as binary + * @param binary true is a binary file otherwise false + */ + setBinary?(binary: boolean); + // /** + // * Opens the text document + // * @return vscode.TextDocument + // */ + // getOpenedDocumentInstance?(): vscode.TextDocument; + /** + * Downloads and displays a file in a text editor view + * + * @param download Download the file default false + * @param preview the file, true or false + * @param ussFileProvider the tree provider + */ + openUSS?(download: boolean, previewFile: boolean, ussFileProvider: IZoweTree); + /** + * Returns the local file path for the ZoweUSSNode + * + */ + getUSSDocumentFilePath?(): string; + /** + * Refreshes the node with current mainframe data + * + */ + refreshUSS?(); + /** + * + * @param ussFileProvider Deletes the USS tree node + * @param filePath + */ + deleteUSSNode?(ussFileProvider: IZoweTree, filePath: string); + /** + * Process for renaming a USS Node. This could be a Favorite Node + * + * @param {USSTree} ussFileProvider + * @param {string} filePath + */ + renameUSSNode?(ussFileProvider: IZoweTree, filePath: string); + /** + * Adds a search node to the USS favorites list + * + * @param {USSTree} ussFileProvider + */ + addUSSSearchFavorite?(ussFileProvider: IZoweTree); +} + +/** + * 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 9ac77d07f7..db194871e7 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -15,18 +15,10 @@ import * as os from "os"; import { moveSync } from "fs-extra"; import * as path from "path"; import * as vscode from "vscode"; -import { IZoweTree, IZoweTreeNode } from "./ZoweTree"; -import { ZoweNode } from "./ZoweNode"; -import { - Logger, - TextUtils, - IProfileLoaded, - ImperativeConfig, - Session, - CredentialManagerFactory, - ImperativeError, - DefaultCredentialManager -} from "@brightside/imperative"; +import { IZoweTreeNode, IZoweJobTreeNode, IZoweUSSTreeNode, IZoweDatasetTreeNode } from "./api/IZoweTreeNode"; +import { ZoweDatasetNode } from "./ZoweDatasetNode"; +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"; @@ -41,7 +33,6 @@ import { Profiles } from "./Profiles"; import * as nls from "vscode-nls"; import * as utils from "./utils"; import SpoolProvider, { encodeJobFile } from "./SpoolProvider"; -import { attachRecentSaveListener, disposeRecentSaveListener, getRecentSaveStatus } from "./utils/file"; import { ZoweExplorerApiRegister } from "./api/ZoweExplorerApiRegister"; // Localization support @@ -240,29 +231,30 @@ export async function activate(context: vscode.ExtensionContext): Promise ussFileProvider.addUSSFavorite(node)); - vscode.commands.registerCommand("zowe.uss.removeFavorite", async (node) => ussFileProvider.removeUSSFavorite(node)); + vscode.commands.registerCommand("zowe.uss.addFavorite", async (node: IZoweUSSTreeNode) => ussFileProvider.addFavorite(node)); + vscode.commands.registerCommand("zowe.uss.removeFavorite", async (node: IZoweUSSTreeNode) => 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)); - vscode.commands.registerCommand("zowe.uss.refreshUSSInTree", (node) => refreshUSSInTree(node, ussFileProvider)); - vscode.commands.registerCommand("zowe.uss.fullPath", (node) => ussFileProvider.ussFilterPrompt(node)); - vscode.commands.registerCommand("zowe.uss.ZoweUSSNode.open", (node) => openUSS(node, false, true, ussFileProvider)); - 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.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", - async (node) => ussActions.renameUSSNode(node, ussFileProvider, getUSSDocumentFilePath(node))); - vscode.commands.registerCommand("zowe.uss.uploadDialog", async (node) => ussActions.uploadDialog(node, ussFileProvider)); - vscode.commands.registerCommand("zowe.uss.createNode", async (node) => ussActions.createUSSNodeDialog(node, ussFileProvider)); - vscode.commands.registerCommand("zowe.uss.copyPath", async (node) => ussActions.copyPath(node)); - vscode.commands.registerCommand("zowe.uss.editFile", (node) => openUSS(node, false, false, ussFileProvider)); - 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.refreshUSS", (node: IZoweUSSTreeNode) => node.refreshUSS()); + vscode.commands.registerCommand("zowe.uss.refreshUSSInTree", (node: IZoweUSSTreeNode) => refreshUSSInTree(node, ussFileProvider)); + vscode.commands.registerCommand("zowe.uss.fullPath", (node: IZoweUSSTreeNode) => ussFileProvider.ussFilterPrompt(node)); + vscode.commands.registerCommand("zowe.uss.ZoweUSSNode.open", (node: IZoweUSSTreeNode) => node.openUSS(false, true, ussFileProvider)); + vscode.commands.registerCommand("zowe.uss.removeSession", async (node: IZoweUSSTreeNode) => ussFileProvider.deleteSession(node)); + vscode.commands.registerCommand("zowe.uss.createFile", async (node: IZoweUSSTreeNode) => ussActions.createUSSNode(node, ussFileProvider, "file")); + vscode.commands.registerCommand("zowe.uss.createFolder", async (node: IZoweUSSTreeNode) => ussActions.createUSSNode(node, ussFileProvider, "directory")); + vscode.commands.registerCommand("zowe.uss.deleteNode", async (node: IZoweUSSTreeNode) => + node.deleteUSSNode(ussFileProvider, node.getUSSDocumentFilePath())); + vscode.commands.registerCommand("zowe.uss.binary", async (node: IZoweUSSTreeNode) => changeFileType(node, true, ussFileProvider)); + vscode.commands.registerCommand("zowe.uss.text", async (node: IZoweUSSTreeNode) => changeFileType(node, false, ussFileProvider)); + vscode.commands.registerCommand("zowe.uss.renameNode", async (node: IZoweUSSTreeNode) => + node.renameUSSNode(ussFileProvider, node.getUSSDocumentFilePath())); + vscode.commands.registerCommand("zowe.uss.uploadDialog", async (node: IZoweUSSTreeNode) => ussActions.uploadDialog(node, ussFileProvider)); + vscode.commands.registerCommand("zowe.uss.createNode", async (node: IZoweUSSTreeNode) => + ussActions.createUSSNodeDialog(node, ussFileProvider)); + vscode.commands.registerCommand("zowe.uss.copyPath", async (node: IZoweUSSTreeNode) => ussActions.copyPath(node)); + vscode.commands.registerCommand("zowe.uss.editFile", (node: IZoweUSSTreeNode) => node.openUSS(false, false, ussFileProvider)); + vscode.commands.registerCommand("zowe.uss.saveSearch", async (node: IZoweUSSTreeNode) => node.addUSSSearchFavorite(ussFileProvider)); + vscode.commands.registerCommand("zowe.uss.removeSavedSearch", async (node: IZoweUSSTreeNode) => ussFileProvider.removeFavorite(node)); vscode.workspace.onDidChangeConfiguration(async (e) => { ussFileProvider.onDidChangeConfiguration(e); }); @@ -293,7 +285,10 @@ export async function activate(context: vscode.ExtensionContext): Promise { jobsProvider.mSessionNodes.forEach((jobNode) => { if (jobNode.contextValue === JOBS_SESSION_CONTEXT) { - jobNode.reset(); + // reset + utils.labelHack(jobNode); + jobNode.children = []; + jobNode.dirty = true; } }); jobsProvider.refresh(); @@ -321,7 +316,7 @@ export async function activate(context: vscode.ExtensionContext): Promise { return jobNode.job.jobid === jobid; }); - jobsProvider.setJob(jobsProvider.getTreeView(), job); + jobsProvider.setItem(theTreeView, job); }); vscode.commands.registerCommand("zowe.jobs.search", (node) => jobsProvider.searchPrompt(node)); vscode.commands.registerCommand("zowe.issueTsoCmd", async () => MvsCommandHandler.getInstance().issueMvsCommand()); @@ -330,17 +325,17 @@ export async function activate(context: vscode.ExtensionContext): Promise { 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 theTreeView = jobsProvider.getTreeView(); context.subscriptions.push(theTreeView); if (!ISTHEIA) { - theTreeView.onDidCollapseElement(async (e: { element: Job; }) => { + theTreeView.onDidCollapseElement( async (e: { element: IZoweJobTreeNode; }) => { jobsProvider.flipState(e.element, false); }); - theTreeView.onDidExpandElement(async (e: { element: Job; }) => { + theTreeView.onDidExpandElement( async (e: { element: IZoweJobTreeNode; }) => { jobsProvider.flipState(e.element, true); }); } @@ -410,7 +405,6 @@ export function getZoweDir(): string { defaultHome: path.join(os.homedir(), ".zowe"), envVariablePrefix: "ZOWE" }; - const ti = ImperativeConfig.instance; return ImperativeConfig.instance.cliHome; } @@ -465,7 +459,7 @@ export function moveTempFolder(previousTempPath: string, currentTempPath: string * * @param job The job to download the spool content from */ -export async function downloadSpool(job: Job) { +export async function downloadSpool(job: IZoweJobTreeNode){ try { const dirUri = await vscode.window.showOpenDialog({ openLabel: localize("downloadSpool.select", "Select"), @@ -474,7 +468,7 @@ export async function downloadSpool(job: Job) { canSelectMany: false }); if (dirUri !== undefined) { - ZoweExplorerApiRegister.getJesApi(job.profile).downloadSpoolContent({ + ZoweExplorerApiRegister.getJesApi(job.getProfile()).downloadSpoolContent({ jobid: job.job.jobid, jobname: job.job.jobname, outDir: dirUri[0].fsPath @@ -488,7 +482,7 @@ export async function downloadSpool(job: Job) { export async function downloadJcl(job: Job) { try { - const jobJcl = await ZoweExplorerApiRegister.getJesApi(job.profile).getJclForJob(job.job); + const jobJcl = await ZoweExplorerApiRegister.getJesApi(job.getProfile()).getJclForJob(job.job); const jclDoc = await vscode.workspace.openTextDocument({language: "jcl", content: jobJcl}); await vscode.window.showTextDocument(jclDoc); } catch (error) { @@ -503,9 +497,9 @@ export async function downloadJcl(job: Job) { * @param binary Whether the file should be downloaded as binary or not * @param ussFileProvider Our USSTree object */ -export async function changeFileType(node: ZoweUSSNode, binary: boolean, ussFileProvider: USSTree) { +export async function changeFileType(node: IZoweUSSTreeNode, binary: boolean, ussFileProvider: IZoweTree) { node.setBinary(binary); - await openUSS(node, true, true, ussFileProvider); + await node.openUSS(true, true, ussFileProvider); ussFileProvider.refresh(); } @@ -555,7 +549,7 @@ export async function submitJcl(datasetProvider: DatasetTree) { let sessProfile: IProfileLoaded; const sesNode = (await datasetProvider.getChildren()).find((child) => child.label.trim() === sessProfileName); if (sesNode) { - sessProfile = sesNode.profile; + sessProfile = sesNode.getProfile(); } else { // if submitting from favorites, a session might not exist for this node sessProfile = profiles.loadNamedProfile(sessProfileName); @@ -580,35 +574,35 @@ 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; let sessProfile; let regex; const profiles = await Profiles.getInstance(); - switch (node.mParent.contextValue) { + switch (node.getParent().contextValue) { case (FAVORITE_CONTEXT): - regex = labelregex.exec(node.label); + regex = labelregex.exec(node.getLabel()); sesName = regex[1]; label = regex[2]; sessProfile = profiles.loadNamedProfile(sesName); break; case (DS_PDS_CONTEXT + FAV_SUFFIX): - regex = labelregex.exec(node.mParent.label); + regex = labelregex.exec(node.getParent().getLabel()); sesName = regex[1]; - label = regex[2] + "(" + node.label.trim() + ")"; - sessProfile = node.mParent.profile; + label = regex[2] + "(" + node.label.trim()+ ")"; + sessProfile = node.getParent().getProfile(); break; case (DS_SESSION_CONTEXT): - sesName = node.mParent.label; + sesName = node.getParent().getLabel(); label = node.label; - sessProfile = node.mParent.profile; + sessProfile = node.getParent().getProfile(); break; case (DS_PDS_CONTEXT): - sesName = node.mParent.mParent.label; - label = node.mParent.label.trim() + "(" + node.label.trim() + ")"; - sessProfile = node.mParent.mParent.profile; + sesName = node.getParent().getParent().getLabel(); + label = node.getParent().getLabel() + "(" + node.label.trim()+ ")"; + sessProfile = node.getParent().getParent().getProfile(); break; default: vscode.window.showErrorMessage(localize("submitMember.invalidNode", "submitMember() called from invalid node.")); @@ -746,10 +740,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, @@ -833,7 +827,7 @@ export async function createFile(node: ZoweNode, datasetProvider: DatasetTree) { name = name.toUpperCase(); try { - await ZoweExplorerApiRegister.getMvsApi(node.profile).createDataSet(typeEnum, name, createOptions); + await ZoweExplorerApiRegister.getMvsApi(node.getProfile()).createDataSet(typeEnum, name, createOptions); node.dirty = true; // Store previous filters (before refreshing) @@ -889,11 +883,11 @@ 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) { - const name = await vscode.window.showInputBox({placeHolder: localize("createMember.inputBox", "Name of Member")}); +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) { let label = parent.label.trim(); @@ -902,7 +896,7 @@ export async function createMember(parent: ZoweNode, datasetProvider: DatasetTre } try { - await ZoweExplorerApiRegister.getMvsApi(parent.profile).createDataSetMember(label + "(" + name + ")"); + await ZoweExplorerApiRegister.getMvsApi(parent.getProfile()).createDataSetMember(label + "(" + name + ")"); } catch (err) { log.error(localize("createMember.log.error", "Error encountered when creating member! ") + JSON.stringify(err)); await utils.errorHandling(err, label, localize("createMember.error", "Unable to create member: ") + err.message); @@ -911,7 +905,7 @@ export async function createMember(parent: ZoweNode, datasetProvider: DatasetTre parent.dirty = true; datasetProvider.refreshElement(parent); openPS( - new ZoweNode(name, vscode.TreeItemCollapsibleState.None, parent, null, undefined, undefined, parent.profile), + new ZoweDatasetNode(name, vscode.TreeItemCollapsibleState.None, parent, null, undefined, undefined, parent.getProfile()), true, datasetProvider); datasetProvider.refresh(); } @@ -922,10 +916,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) { @@ -935,7 +929,7 @@ export async function showDSAttributes(parent: ZoweNode, datasetProvider: Datase log.debug(localize("showDSAttributes.debug", "showing attributes of data set ") + label); let attributes: any; try { - attributes = await ZoweExplorerApiRegister.getMvsApi(parent.profile).dataSet(label, {attributes: true}); + attributes = await ZoweExplorerApiRegister.getMvsApi(parent.getProfile()).dataSet(label, { attributes: true }); attributes = attributes.apiResponse.items; attributes = attributes.filter((dataSet) => { return dataSet.dsname.toUpperCase() === label.toUpperCase(); @@ -986,10 +980,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; @@ -1004,7 +998,7 @@ export async function renameDataSet(node: ZoweNode, datasetProvider: DatasetTree log.debug(localize("renameDataSet.log.debug", "Renaming data set ") + afterDataSetName); if (afterDataSetName) { try { - await ZoweExplorerApiRegister.getMvsApi(node.profile).renameDataSet(beforeDataSetName, afterDataSetName); + await ZoweExplorerApiRegister.getMvsApi(node.getProfile()).renameDataSet(beforeDataSetName, afterDataSetName); node.label = `${favPrefix}${afterDataSetName}`; } catch (err) { log.error(localize("renameDataSet.log.error", "Error encountered when renaming data set! ") + JSON.stringify(err)); @@ -1020,28 +1014,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); } @@ -1051,9 +1045,9 @@ function getNodeLabels(node: ZoweNode) { * 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))); } @@ -1061,11 +1055,11 @@ 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) { - const {profileName, dataSetName} = getNodeLabels(node); +export async function pasteDataSet(node: ZoweDatasetNode, datasetProvider: DatasetTree) { + const { profileName, dataSetName } = getNodeLabels(node); let memberName; let beforeDataSetName; let beforeProfileName; @@ -1091,7 +1085,7 @@ export async function pasteDataSet(node: ZoweNode, datasetProvider: DatasetTree) if (beforeProfileName === profileName) { if (memberName) { try { - await ZoweExplorerApiRegister.getMvsApi(node.profile).getContents(`${dataSetName}(${memberName})`); + await ZoweExplorerApiRegister.getMvsApi(node.getProfile()).getContents(`${dataSetName}(${memberName})`); throw Error(`${dataSetName}(${memberName}) already exists. You cannot replace a member`); } catch (err) { if (!err.message.includes("Member not found")) { @@ -1099,9 +1093,9 @@ export async function pasteDataSet(node: ZoweNode, datasetProvider: DatasetTree) } } } - await ZoweExplorerApiRegister.getMvsApi(node.profile).copyDataSetMember( - {dataSetName: beforeDataSetName, memberName: beforeMemberName}, - {dataSetName, memberName}, + await ZoweExplorerApiRegister.getMvsApi(node.getProfile()).copyDataSetMember( + { dataSetName: beforeDataSetName, memberName: beforeMemberName }, + { dataSetName, memberName }, ); if (memberName) { @@ -1125,34 +1119,34 @@ 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}); log.debug(localize("renameDataSet.log.debug", "Renaming data set ") + afterMemberName); if (afterMemberName) { try { - await ZoweExplorerApiRegister.getMvsApi(node.profile).renameDataSetMember(dataSetName, beforeMemberName, afterMemberName); + await ZoweExplorerApiRegister.getMvsApi(node.getProfile()).renameDataSetMember(dataSetName, beforeMemberName, afterMemberName); node.label = `${profileLabel}${afterMemberName}`; } catch (err) { log.error(localize("renameDataSet.log.error", "Error encountered when renaming data set! ") + JSON.stringify(err)); await utils.errorHandling(err, profileLabel, 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) { @@ -1161,7 +1155,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) { @@ -1170,7 +1164,7 @@ export async function renameDataSetMember(node: ZoweNode, datasetProvider: Datas } } } - datasetProvider.refreshElement(node.mParent); + datasetProvider.refreshElement(node.getParent()); } } @@ -1225,10 +1219,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, @@ -1245,25 +1239,25 @@ 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.")); } - await ZoweExplorerApiRegister.getMvsApi(node.profile).deleteDataSet(label); + await ZoweExplorerApiRegister.getMvsApi(node.getProfile()).deleteDataSet(label); } catch (err) { log.error(localize("deleteDataSet.delete.log.error", "Error encountered when deleting data set! ") + JSON.stringify(err)); if (err.message.includes(localize("deleteDataSet.error.notFound", "not found"))) { @@ -1278,8 +1272,9 @@ export async function deleteDataset(node: ZoweNode, datasetProvider: DatasetTree // remove node from tree 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) { + if (node.label.substring(node.label.indexOf("[") + 1, node.label.indexOf("]")) === ses.label.trim()|| + node.getParent().getLabel().substring(node.getParent().getLabel().indexOf("["), + node.getParent().getLabel().indexOf("]")) === ses.label) { ses.dirty = true; } }); @@ -1293,13 +1288,13 @@ export async function deleteDataset(node: ZoweNode, datasetProvider: DatasetTree } // refresh Tree View & favorites - if (node.mParent && node.mParent.contextValue !== DS_SESSION_CONTEXT) { - datasetProvider.refreshElement(node.mParent); - if (node.mParent.contextValue.includes(FAV_SUFFIX) || node.mParent.contextValue === FAVORITE_CONTEXT) { - const nonFavNode = datasetProvider.findNonFavoritedNode(node.mParent); + if (node.getParent() && node.getParent().contextValue !== DS_SESSION_CONTEXT) { + datasetProvider.refreshElement(node.getParent()); + if (node.getParent().contextValue.includes(FAV_SUFFIX) || node.getParent().contextValue === FAVORITE_CONTEXT) { + const nonFavNode = datasetProvider.findNonFavoritedNode(node.getParent()); if (nonFavNode) { datasetProvider.refreshElement(nonFavNode); } } else { - const favNode = datasetProvider.findFavoritedNode(node.mParent); + const favNode = datasetProvider.findFavoritedNode(node.getParent()); if (favNode) { datasetProvider.refreshElement(favNode); } } } else { @@ -1320,11 +1315,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")); } @@ -1366,9 +1361,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("[")) { @@ -1383,9 +1378,8 @@ export function getProfile(node: ZoweNode) { * @export * @param {ZoweUSSNode} node */ -export function getUSSProfile(node: ZoweUSSNode) { - const profile = node.getSessionNode().mProfileName; - return profile; +export function getUSSProfile(node: IZoweUSSTreeNode) { + return node.getSessionNode().getProfileName(); } /** @@ -1436,37 +1430,27 @@ 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) { - return path.join(DS_DIR, "/" + getProfile(node) + "/" + appendSuffix(label)); -} - -/** - * Returns the local file path for the ZoweUSSNode - * - * @export - * @param {ZoweUSSNode} node + * @param {ZoweDatasetNode} node */ -export function getUSSDocumentFilePath(node: ZoweUSSNode) { - return path.join(USS_DIR || "", "/" + getUSSProfile(node) + "/", node.fullPath); +export function getDocumentFilePath(label: string, node: IZoweTreeNode) { + return path.join(DS_DIR, "/" + getProfile(node) + "/" + appendSuffix(label) ); } /** * Downloads and displays a PS in a text editor view * - * @param {ZoweNode} node + * @param {IZoweDatasetTreeNode} node */ -export async function openPS(node: ZoweNode, previewMember: boolean, datasetProvider?: DatasetTree) { +export async function openPS(node: IZoweDatasetTreeNode, previewMember: boolean, datasetProvider?: IZoweTree) { 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 { @@ -1495,18 +1479,18 @@ export async function openPS(node: ZoweNode, previewMember: boolean, datasetProv 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.")); @@ -1520,7 +1504,7 @@ export async function openPS(node: ZoweNode, previewMember: boolean, datasetProv location: vscode.ProgressLocation.Notification, title: "Opening data set..." }, function downloadDataset() { - return ZoweExplorerApiRegister.getMvsApi(node.profile).getContents(label, { + return ZoweExplorerApiRegister.getMvsApi(node.getProfile()).getContents(label, { file: documentFilePath, returnEtag: true }); @@ -1562,29 +1546,29 @@ 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: IZoweDatasetTreeNode) { 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.")); } const documentFilePath = getDocumentFilePath(label, node); - const response = await ZoweExplorerApiRegister.getMvsApi(node.profile).getContents(label, { + const response = await ZoweExplorerApiRegister.getMvsApi(node.getProfile()).getContents(label, { file: documentFilePath, returnEtag: true }); @@ -1608,67 +1592,7 @@ export async function refreshPS(node: ZoweNode) { } } -/** - * Refreshes the passed node with current mainframe data - * - * @param {ZoweUSSNode} node - The node which represents the file - */ -export async function refreshUSS(node: ZoweUSSNode) { - let label; - switch (node.mParent.contextValue) { - case (USS_DIR_CONTEXT + FAV_SUFFIX): - label = node.fullPath; - break; - case (USS_DIR_CONTEXT): - label = node.fullPath; - break; - case (USS_SESSION_CONTEXT): - label = node.label; - break; - default: - vscode.window.showErrorMessage(localize("refreshUSS.error.invalidNode", "refreshUSS() called from invalid node.")); - throw Error(localize("refreshUSS.error.invalidNode", "refreshPS() called from invalid node.")); - } - try { - const ussDocumentFilePath = getUSSDocumentFilePath(node); - const isDirty = node.isDirtyInEditor; - let wasSaved = false; - - if (isDirty) { - attachRecentSaveListener(); - - vscode.window.showTextDocument(node.openedDocumentInstance); - await vscode.commands.executeCommand("workbench.action.closeActiveEditor"); - wasSaved = getRecentSaveStatus(); - - disposeRecentSaveListener(); - } - - if ((isDirty && !node.isDirtyInEditor && !wasSaved) || !isDirty) { - const response = await ZoweExplorerApiRegister.getUssApi(node.profile).getContents(node.fullPath, { - file: ussDocumentFilePath, - returnEtag: true - }); - node.setEtag(response.apiResponse.etag); - node.downloaded = true; - - if (isDirty) { - await initializeFileOpening(node, ussDocumentFilePath, true); - } - } else if (wasSaved) { - await initializeFileOpening(node, ussDocumentFilePath, true); - } - } catch (err) { - if (err.message.includes(localize("refreshUSS.error.notFound", "not found"))) { - vscode.window.showInformationMessage(localize("refreshUSS.file1", "Unable to find file: ") + label + - localize("refreshUSS.file2", " was probably deleted.")); - } else { - await utils.errorHandling(err, node.mProfileName, err.message); - } - } -} - -export async function refreshUSSInTree(node: ZoweUSSNode, ussFileProvider: USSTree) { +export async function refreshUSSInTree(node: IZoweUSSTreeNode, ussFileProvider: IZoweTree) { await ussFileProvider.refreshElement(node); } @@ -1687,7 +1611,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, ".."); @@ -1708,7 +1632,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) { @@ -1737,7 +1661,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 @@ -1780,20 +1704,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.getProfile(): 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.getProfile(): 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.")); @@ -1824,7 +1750,7 @@ export async function saveFile(doc: vscode.TextDocument, datasetProvider: Datase * @param {Session} session - Desired session * @param {vscode.TextDocument} doc - TextDocument that is being saved */ -export async function saveUSSFile(doc: vscode.TextDocument, ussFileProvider: USSTree) { +export async function saveUSSFile(doc: vscode.TextDocument, ussFileProvider: IZoweTree) { log.debug(localize("saveUSSFile.log.debug.saveRequest", "save requested for USS file ") + doc.fileName); const start = path.join(USS_DIR + path.sep).length; const ending = doc.fileName.substring(start); @@ -1834,25 +1760,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: IZoweUSSTreeNode; + 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: IZoweUSSTreeNode[]; 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; } }); @@ -1872,7 +1799,7 @@ export async function saveUSSFile(doc: vscode.TextDocument, ussFileProvider: USS location: vscode.ProgressLocation.Notification, title: localize("saveUSSFile.response.title", "Saving file...") }, () => { - return ZoweExplorerApiRegister.getUssApi(sesNode.profile).putContents( + return ZoweExplorerApiRegister.getUssApi(sesNode.getProfile()).putContents( doc.fileName, remote, binary, null, etagToUpload, returnEtag); // TODO MISSED TESTING }); if (uploadResponse.success) { @@ -1889,9 +1816,9 @@ export async function saveUSSFile(doc: vscode.TextDocument, ussFileProvider: USS // Store old document text in a separate variable, to be used on merge conflict const oldDocText = doc.getText(); const oldDocLineCount = doc.lineCount; - const downloadResponse = await ZoweExplorerApiRegister.getUssApi(node.profile).getContents( + const downloadResponse = await ZoweExplorerApiRegister.getUssApi(node.getProfile()).getContents( node.fullPath, { - file: getUSSDocumentFilePath(node), + file: node.getUSSDocumentFilePath(), binary, returnEtag: true }); @@ -1900,7 +1827,7 @@ export async function saveUSSFile(doc: vscode.TextDocument, ussFileProvider: USS if (downloadEtag !== etagToUpload) { node.setEtag(downloadEtag); } - node.downloaded = true; + this.downloaded = true; vscode.window.showWarningMessage(localize("saveFile.error.etagMismatch", "Remote file has been modified in the meantime.\nSelect 'Compare' to resolve the conflict.")); const startPosition = new vscode.Position(0, 0); @@ -1919,134 +1846,11 @@ export async function saveUSSFile(doc: vscode.TextDocument, ussFileProvider: USS } } -/** - * Downloads and displays a file in a text editor view - * - * @param {ZoweUSSNode} node - */ -export async function openUSS(node: ZoweUSSNode, download = false, previewFile: boolean, ussFileProvider?: USSTree) { - if ((!node.getSession().ISession.user) || (!node.getSession().ISession.password)) { - try { - const values = await Profiles.getInstance().promptCredentials(node.mProfileName); - if (values !== undefined) { - usrNme = values[0]; - passWrd = values[1]; - baseEncd = values[2]; - } - } catch (error) { - await utils.errorHandling(error, node.mProfileName, error.message); - } - if (usrNme !== undefined && passWrd !== undefined && baseEncd !== undefined) { - node.getSession().ISession.user = usrNme; - node.getSession().ISession.password = passWrd; - node.getSession().ISession.base64EncodedAuth = baseEncd; - validProfile = 0; - } else { - return; - } - await ussFileProvider.refreshElement(node); - await ussFileProvider.refresh(); - } else { - validProfile = 0; - } - if (validProfile === 0) { - try { - let label: string; - switch (node.mParent.contextValue) { - case (FAVORITE_CONTEXT): - label = node.label.substring(node.label.indexOf(":") + 1).trim(); - break; - // Handle file path for files in directories and favorited directories - case (USS_DIR_CONTEXT): - case (USS_DIR_CONTEXT + FAV_SUFFIX): - label = node.fullPath; - break; - case (USS_SESSION_CONTEXT): - label = node.label; - break; - default: - vscode.window.showErrorMessage(localize("openUSS.error.invalidNode", "open() called from invalid node.")); - throw Error(localize("openUSS.error.invalidNode", "open() called from invalid node.")); - } - log.debug(localize("openUSS.log.debug.request", "requesting to open a uss file ") + label); - // if local copy exists, open that instead of pulling from mainframe - const documentFilePath = getUSSDocumentFilePath(node); - if (download || !fs.existsSync(documentFilePath)) { - const chooseBinary = node.binary || - await ZoweExplorerApiRegister.getUssApi(node.profile).isFileTagBinOrAscii(node.fullPath); - const response = await vscode.window.withProgress({ - location: vscode.ProgressLocation.Notification, - title: "Opening USS file..." - }, - function downloadUSSFile() { - return ZoweExplorerApiRegister.getUssApi(node.profile).getContents( - node.fullPath, { - file: documentFilePath, - binary: chooseBinary, - returnEtag: true - }); - } - ); - - node.downloaded = true; - node.setEtag(response.apiResponse.etag); - } - - await initializeFileOpening(node, documentFilePath, previewFile); - } catch (err) { - log.error(localize("openUSS.log.error.openFile", "Error encountered when opening USS file: ") + JSON.stringify(err)); - await utils.errorHandling(err, node.mProfileName, err.message); - throw (err); - } - } -} - -export async function initializeFileOpening(node: ZoweUSSNode, documentPath: string, previewFile?: boolean) { - let document; - let openingTextFailed = false; - - if (!node.binary) { - try { - document = await vscode.workspace.openTextDocument(documentPath); - } catch (err) { - openingTextFailed = true; - } - - if (openingTextFailed) { - const yesResponse = localize("openUSS.log.info.failedToOpenAsText.yes", "Yes, re-download"); - const noResponse = localize("openUSS.log.info.failedToOpenAsText.no", "No"); - - const response = await vscode.window.showErrorMessage( - localize( - "openUSS.log.info.failedToOpenAsText", - "Failed to open file as text. Do you want to try with re-downloading it as binary?"), - ...[ - yesResponse, - noResponse - ] - ); - - if (response === yesResponse.toString()) { - await vscode.commands.executeCommand("zowe.uss.binary", node); - } - } else { - if (previewFile === true) { - await vscode.window.showTextDocument(document); - } else { - await vscode.window.showTextDocument(document, {preview: false}); - } - } - } else { - const uriPath = vscode.Uri.file(documentPath); - await vscode.commands.executeCommand("vscode.open", uriPath); - } -} - 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) { @@ -2056,7 +1860,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) { await utils.errorHandling(error, null, error.message); @@ -2097,26 +1901,26 @@ export async function getSpoolContent(session: string, spool: IJobFile) { } } -export async function setOwner(job: Job, jobsProvider: ZosJobsProvider) { - const newOwner = await vscode.window.showInputBox({prompt: localize("setOwner.newOwner.prompt.owner", "Owner")}); +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) { - const newPrefix = await vscode.window.showInputBox({prompt: localize("setOwner.newOwner.prompt.prefix", "Prefix")}); +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, jobsProvider: ZosJobsProvider) { +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("]")); } 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) { @@ -2128,9 +1932,9 @@ export async function refreshJobsServer(node: Job, jobsProvider: ZosJobsProvider await utils.errorHandling(error, node.getProfileName(), 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/generators/icons/index.ts b/src/generators/icons/index.ts index eb1250b8ba..640d33627b 100644 --- a/src/generators/icons/index.ts +++ b/src/generators/icons/index.ts @@ -11,7 +11,7 @@ import { TreeItem } from "vscode"; import { ZoweUSSNode } from "../../ZoweUSSNode"; -import { ZoweNode } from "../../ZoweNode"; +import { ZoweTreeNode } from "../../abstract/ZoweTreeNode"; export enum IconId { "document" = "document", @@ -24,7 +24,7 @@ export enum IconHierarchyType { "derived" = "derived" } -type CombinedNode = TreeItem | ZoweUSSNode | ZoweNode; +type CombinedNode = TreeItem | ZoweUSSNode | ZoweTreeNode; export interface IIconItem { id: IconId; type: IconHierarchyType; diff --git a/src/mvs/mvsNodeActions.ts b/src/mvs/mvsNodeActions.ts index cbc835796e..f952f0ceeb 100644 --- a/src/mvs/mvsNodeActions.ts +++ b/src/mvs/mvsNodeActions.ts @@ -10,13 +10,13 @@ */ import * as vscode from "vscode"; -import * as utils from "../utils"; -import { ZoweNode } from "../ZoweNode"; +import { ZoweDatasetNode } from "../ZoweDatasetNode"; import { DatasetTree } from "../DatasetTree"; import * as extension from "../../src/extension"; +import * as utils from "../utils"; import { ZoweExplorerApiRegister } from "../api/ZoweExplorerApiRegister"; -export async function uploadDialog(node: ZoweNode, datasetProvider: DatasetTree) { +export async function uploadDialog(node: ZoweDatasetNode, datasetProvider: DatasetTree) { const fileOpenOptions = { canSelectFiles: true, openLabel: "Upload File", @@ -35,7 +35,7 @@ export async function uploadDialog(node: ZoweNode, datasetProvider: DatasetTree) // refresh Tree View & favorites datasetProvider.refreshElement(node); - if (node.contextValue.includes(extension.FAV_SUFFIX) || node.mParent.contextValue === extension.FAVORITE_CONTEXT) { + if (node.contextValue.includes(extension.FAV_SUFFIX) || node.getParent().contextValue === extension.FAVORITE_CONTEXT) { const nonFavNode = datasetProvider.findNonFavoritedNode(node); if (nonFavNode) { datasetProvider.refreshElement(nonFavNode); } } else { @@ -44,8 +44,8 @@ export async function uploadDialog(node: ZoweNode, datasetProvider: DatasetTree) } } -export function getDatasetLabel(node: ZoweNode) { - if (node.mParent && node.mParent.contextValue === extension.FAVORITE_CONTEXT) { +export function getDatasetLabel(node: ZoweDatasetNode) { + 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); @@ -53,10 +53,10 @@ 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 ZoweExplorerApiRegister.getMvsApi(node.profile).putContents(doc.fileName, datasetName); + await ZoweExplorerApiRegister.getMvsApi(node.getProfile()).putContents(doc.fileName, datasetName); } catch (e) { await utils.errorHandling(e, node.getProfileName(), e.message); } diff --git a/src/uss/ussNodeActions.ts b/src/uss/ussNodeActions.ts index 026f9788a4..abce985747 100644 --- a/src/uss/ussNodeActions.ts +++ b/src/uss/ussNodeActions.ts @@ -22,6 +22,8 @@ import * as extension from "../../src/extension"; import * as path from "path"; import { ISTHEIA } from "../extension"; import { Profiles } from "../Profiles"; +import { IZoweTree } from "../api/IZoweTree"; +import { IZoweUSSTreeNode } from "../api/IZoweTreeNode"; import { ZoweExplorerApiRegister } from "../api/ZoweExplorerApiRegister"; import { isBinaryFileSync } from "isbinaryfile"; @@ -32,7 +34,7 @@ import { isBinaryFileSync } from "isbinaryfile"; * @param {ussTree} ussFileProvider - Current ussTree used to populate the TreeView * @returns {Promise} */ -export async function createUSSNode(node: ZoweUSSNode, ussFileProvider: USSTree, nodeType: string, isTopLevel?: boolean) { +export async function createUSSNode(node: IZoweUSSTreeNode, ussFileProvider: IZoweTree, nodeType: string, isTopLevel?: boolean) { const name = await vscode.window.showInputBox({ placeHolder: localize("createUSSNode.name", "Name of file or directory") @@ -40,7 +42,7 @@ export async function createUSSNode(node: ZoweUSSNode, ussFileProvider: USSTree, if (name) { try { const filePath = `${node.fullPath}/${name}`; - await ZoweExplorerApiRegister.getUssApi(node.profile).create(filePath, nodeType); + await ZoweExplorerApiRegister.getUssApi(node.getProfile()).create(filePath, nodeType); if (isTopLevel) { refreshAllUSS(ussFileProvider); } else { @@ -54,7 +56,7 @@ export async function createUSSNode(node: ZoweUSSNode, ussFileProvider: USSTree, } } -export async function createUSSNodeDialog(node: ZoweUSSNode, ussFileProvider: USSTree) { +export async function createUSSNodeDialog(node: IZoweUSSTreeNode, ussFileProvider: IZoweTree) { let usrNme: string; let passWrd: string; let baseEncd: string; @@ -96,39 +98,12 @@ export async function createUSSNodeDialog(node: ZoweUSSNode, ussFileProvider: US } } -export async function deleteUSSNode(node: ZoweUSSNode, ussFileProvider: USSTree, filePath: string) { - 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 ZoweExplorerApiRegister.getUssApi(node.profile).delete(node.fullPath, isRecursive); - node.mParent.dirty = true; - deleteFromDisk(node, filePath); - } catch (err) { - const errMessage: string = localize("deleteUSSNode.error.node", "Unable to delete node: ") + err.message; - utils.errorHandling(err, node.mProfileName, errMessage); - throw (err); - } - - // Remove node from the USS Favorites tree - ussFileProvider.removeUSSFavorite(node); - ussFileProvider.refresh(); -} - /** * Refreshes treeView * * @param {USSTree} ussFileProvider */ -export async function refreshAllUSS(ussFileProvider: USSTree) { +export async function refreshAllUSS(ussFileProvider: IZoweTree) { ussFileProvider.mSessionNodes.forEach((sessNode) => { if (sessNode.contextValue === extension.USS_SESSION_CONTEXT) { utils.labelHack(sessNode); @@ -143,11 +118,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; @@ -161,13 +136,12 @@ export async function renameUSSNode(originalNode: ZoweUSSNode, ussFileProvider: try { const newNamePath = path.join(parentPath + newName); await ZoweExplorerApiRegister.getUssApi( - originalNode.profile).rename(originalNode.fullPath, newNamePath); - originalNode.rename(newNamePath); - + originalNode.getProfile()).rename(originalNode.fullPath, newNamePath); + ussFileProvider.refresh(); if (oldFavorite) { - ussFileProvider.removeUSSFavorite(oldFavorite); + ussFileProvider.removeFavorite(oldFavorite); oldFavorite.rename(newNamePath); - ussFileProvider.addUSSFavorite(oldFavorite); + ussFileProvider.addFavorite(oldFavorite); } } catch (err) { utils.errorHandling(err, originalNode.mProfileName, localize("renameUSSNode.error", "Unable to rename node: ") + err.message); @@ -192,7 +166,7 @@ export async function deleteFromDisk(node: ZoweUSSNode, filePath: string) { } } -export async function uploadDialog(node: ZoweUSSNode, ussFileProvider: USSTree) { +export async function uploadDialog(node: IZoweUSSTreeNode, ussFileProvider: IZoweTree) { const fileOpenOptions = { canSelectFiles: true, openLabel: "Upload Files", @@ -216,7 +190,7 @@ export async function uploadDialog(node: ZoweUSSNode, ussFileProvider: USSTree) ussFileProvider.refresh(); } -export async function uploadBinaryFile(node: ZoweUSSNode, filePath: string) { +export async function uploadBinaryFile(node: IZoweUSSTreeNode, filePath: string) { try { const localFileName = path.parse(filePath).base; const ussName = `${node.fullPath}/${localFileName}`; @@ -226,11 +200,11 @@ export async function uploadBinaryFile(node: ZoweUSSNode, filePath: string) { } } -export async function uploadFile(node: ZoweUSSNode, doc: vscode.TextDocument) { +export async function uploadFile(node: IZoweUSSTreeNode, doc: vscode.TextDocument) { try { const localFileName = path.parse(doc.fileName).base; const ussName = `${node.fullPath}/${localFileName}`; - await ZoweExplorerApiRegister.getUssApi(node.profile).putContents(doc.fileName, ussName); + await ZoweExplorerApiRegister.getUssApi(node.getProfile()).putContents(doc.fileName, ussName); } catch (e) { utils.errorHandling(e, node.mProfileName, e.message); } @@ -241,7 +215,7 @@ export async function uploadFile(node: ZoweUSSNode, doc: vscode.TextDocument) { * * @param {ZoweUSSNode} node */ -export async function copyPath(node: ZoweUSSNode) { +export async function copyPath(node: IZoweUSSTreeNode) { if (extension.ISTHEIA) { // Remove when Theia supports VS Code API for accessing system clipboard vscode.window.showInformationMessage(localize("copyPath.infoMessage", "Copy Path is not yet supported in Theia.")); diff --git a/src/utils.ts b/src/utils.ts index 2738e8ee2f..625970569b 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -13,8 +13,7 @@ import * as path from "path"; import { TreeItem, QuickPickItem, QuickPick, window } 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/IZoweTreeNode"; const localize = nls.config({ messageFormat: nls.MessageFormat.file })(); /* @@ -145,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)); diff --git a/stringUpdateScript.js b/stringUpdateScript.js index a801a57483..91e489f25f 100644 --- a/stringUpdateScript.js +++ b/stringUpdateScript.js @@ -31,7 +31,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 = {}; @@ -58,6 +58,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));