diff --git a/__tests__/__integration__/extension.integration.test.ts b/__tests__/__integration__/extension.integration.test.ts index 9688d3dfbe..1bf247ca97 100644 --- a/__tests__/__integration__/extension.integration.test.ts +++ b/__tests__/__integration__/extension.integration.test.ts @@ -758,7 +758,8 @@ describe("Extension Integration Tests", () => { await vscode.workspace.getConfiguration().update("Zowe-Temp-Folder-Location", { folderPath: `${testingPath}` }, vscode.ConfigurationTarget.Global); - expect(extension.BRIGHTTEMPFOLDER).to.equal(`${testingPath}/temp`); + // expect(extension.BRIGHTTEMPFOLDER).to.equal(`${testingPath}/temp`); + expect(extension.BRIGHTTEMPFOLDER).to.equal(path.join(testingPath, "temp")); // Remove directory for subsequent tests extension.cleanDir(testingPath); @@ -776,7 +777,8 @@ describe("Extension Integration Tests", () => { await vscode.workspace.getConfiguration().update("Zowe-Temp-Folder-Location", { folderPath: `${providedPathTwo}` }, vscode.ConfigurationTarget.Global); - expect(extension.BRIGHTTEMPFOLDER).to.equal(`${providedPathTwo}/temp`); + // expect(extension.BRIGHTTEMPFOLDER).to.equal(`${providedPathTwo}/temp`); + expect(extension.BRIGHTTEMPFOLDER).to.equal(path.join(providedPathTwo, "temp")); // Remove directory for subsequent tests extension.cleanDir(providedPathOne); diff --git a/__tests__/__unit__/DatasetTree.unit.test.ts b/__tests__/__unit__/DatasetTree.unit.test.ts index 53a85ddd11..b0b59dbc2c 100644 --- a/__tests__/__unit__/DatasetTree.unit.test.ts +++ b/__tests__/__unit__/DatasetTree.unit.test.ts @@ -54,6 +54,16 @@ describe("DatasetTree Unit Tests", () => { const filters = jest.fn(); const getFilters = jest.fn(); const createQuickPick = jest.fn(); + const createBasicZosmfSession = jest.fn(); + const ZosmfSession = jest.fn(); + Object.defineProperty(zowe, "ZosmfSession", { value: ZosmfSession }); + Object.defineProperty(ZosmfSession, "createBasicZosmfSession", { + value: jest.fn(() => { + return { + ISession: {user: "fake", password: "fake", base64EncodedAuth: "fake"} + }; + }) + }); Object.defineProperty(vscode.window, "showInformationMessage", {value: showInformationMessage}); Object.defineProperty(vscode.window, "showInformationMessage", {value: showInformationMessage}); Object.defineProperty(vscode.window, "showQuickPick", {value: showQuickPick}); @@ -365,9 +375,50 @@ describe("DatasetTree Unit Tests", () => { *************************************************************************************************************/ it("Testing that expand tree is executed successfully", async () => { const refresh = jest.fn(); + createBasicZosmfSession.mockReturnValue(session); Object.defineProperty(testTree, "refresh", {value: refresh}); refresh.mockReset(); - const pds = new ZoweNode("BRTVS99.PUBLIC", vscode.TreeItemCollapsibleState.Collapsed, testTree.mSessionNodes[1], null); + const pds = new ZoweNode("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); + expect(JSON.stringify(pds.iconPath)).toContain("folder-closed.svg"); + await testTree.flipState(pds, true); + expect(JSON.stringify(pds.iconPath)).toContain("folder-open.svg"); + }); + + it("Testing that expand tree is executed for favorites", async () => { + const pds = new ZoweNode("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); + expect(JSON.stringify(pds.iconPath)).toContain("folder-closed.svg"); + await testTree.flipState(pds, true); + expect(JSON.stringify(pds.iconPath)).toContain("folder-open.svg"); + }); + + it("Testing that expand tree with credential prompt is executed successfully", async () => { + const sessionwocred = new Session({ + user: "", + password: "", + hostname: "fake", + port: 443, + protocol: "https", + type: "basic", + }); + Object.defineProperty(Profiles, "getInstance", { + value: jest.fn(() => { + return { + allProfiles: [{name: "firstName", profile: {user:undefined, password: undefined}}, {name: "secondName"}], + defaultProfile: {name: "firstName"}, + loadNamedProfile: mockLoadNamedProfile, + promptCredentials: jest.fn(()=> { + return [{values: "fake"}, {values: "fake"}, {values: "fake"}]; + }), + }; + }) + }); + const pds = new ZoweNode("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); @@ -376,6 +427,60 @@ describe("DatasetTree Unit Tests", () => { expect(JSON.stringify(pds.iconPath)).toContain("folder-open.svg"); }); + it("Testing that expand tree with credential prompt is executed successfully for favorites", async () => { + const sessionwocred = new Session({ + user: "", + password: "", + hostname: "fake", + port: 443, + protocol: "https", + type: "basic", + }); + Object.defineProperty(Profiles, "getInstance", { + value: jest.fn(() => { + return { + allProfiles: [{name: "firstName", profile: {user:undefined, password: undefined}}, {name: "secondName"}], + defaultProfile: {name: "firstName"}, + loadNamedProfile: mockLoadNamedProfile, + promptCredentials: jest.fn(()=> { + return [{values: "fake"}, {values: "fake"}, {values: "fake"}]; + }), + }; + }) + }); + const pds = new ZoweNode("[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"); + }); + + it("Testing that expand tree with credential prompt ends in error", async () => { + const sessionwocred = new Session({ + user: "", + password: "", + hostname: "fake", + port: 443, + protocol: "https", + type: "basic", + }); + Object.defineProperty(Profiles, "getInstance", { + value: jest.fn(() => { + return { + allProfiles: [{name: "firstName", profile: {user:undefined, password: undefined}}, {name: "secondName"}], + defaultProfile: {name: "firstName"}, + loadNamedProfile: mockLoadNamedProfile + }; + }) + }); + const pds = new ZoweNode("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); + expect(JSON.stringify(pds.iconPath)).not.toEqual("folder-closed.svg"); + await testTree.flipState(pds, true); + expect(JSON.stringify(pds.iconPath)).not.toEqual("folder-open.svg"); + }); + /************************************************************************************************************* * Dataset Filter prompts *************************************************************************************************************/ @@ -422,7 +527,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", - vscode.TreeItemCollapsibleState.None, testTree.mFavoriteSession, null); + vscode.TreeItemCollapsibleState.None, testTree.mSessionNodes[1], session); favoriteSearch.contextValue = extension.DS_SESSION_CONTEXT + extension.FAV_SUFFIX; const checkSession = jest.spyOn(testTree, "addSession"); expect(checkSession).not.toHaveBeenCalled(); @@ -612,6 +717,55 @@ describe("DatasetTree Unit Tests", () => { }); + it("tests the dataset filter prompt credentials, favorite route", async () => { + showQuickPick.mockReset(); + showInputBox.mockReset(); + testTree.initialize(Logger.getAppLogger()); + const sessionwocred = new Session({ + user: "", + password: "", + hostname: "fake", + port: 443, + protocol: "https", + type: "basic", + }); + const sessNode = new ZoweNode("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); + dsNode.contextValue = extension.DS_SESSION_CONTEXT + extension.FAV_SUFFIX; + testTree.mSessionNodes.push(dsNode); + const dsNode2 = new ZoweNode("testSess2", vscode.TreeItemCollapsibleState.Expanded, sessNode, sessionwocred); + dsNode2.contextValue = extension.DS_SESSION_CONTEXT + extension.FAV_SUFFIX; + testTree.mSessionNodes.push(dsNode2); + Object.defineProperty(Profiles, "getInstance", { + value: jest.fn(() => { + return { + allProfiles: [{name: "firstName", profile: {user:undefined, password: undefined}}, {name: "secondName"}], + defaultProfile: {name: "firstName"}, + loadNamedProfile: mockLoadNamedProfile, + promptCredentials: jest.fn(()=> { + return ["", "", ""]; + }), + }; + }) + }); + + const spyMe = new DatasetTree(); + Object.defineProperty(spyMe, "datasetFilterPrompt", { + value: jest.fn(() => { + return { + tempNode: dsNode2, + mSessionNodes: {Session: {ISession: {user: "", password: "", base64EncodedAuth: ""}}} + }; + }) + }); + + await testTree.datasetFilterPrompt(dsNode); + + expect(showInformationMessage.mock.calls[0][0]).toEqual("No selection made."); + + }); + it("tests the dataset filter prompt credentials error", async () => { showQuickPick.mockReset(); showInputBox.mockReset(); diff --git a/__tests__/__unit__/USSTree.unit.test.ts b/__tests__/__unit__/USSTree.unit.test.ts index 68f2583fa0..b83c0696a7 100644 --- a/__tests__/__unit__/USSTree.unit.test.ts +++ b/__tests__/__unit__/USSTree.unit.test.ts @@ -15,6 +15,7 @@ jest.mock("@brightside/imperative"); jest.mock("@brightside/core/lib/zosfiles/src/api/methods/list/doc/IListOptions"); jest.mock("Session"); jest.mock("../../src/Profiles"); +import * as brightside from "@brightside/core"; import { Session, Logger } from "@brightside/imperative"; import * as vscode from "vscode"; import { USSTree, createUSSTree } from "../../src/USSTree"; @@ -363,6 +364,63 @@ describe("Unit Tests (Jest)", () => { expect(JSON.stringify(folder.iconPath)).toContain("folder-open.svg"); }); + it("Testing that expand tree with credential prompt is executed successfully", async () => { + const sessionwocred = new Session({ + user: "", + password: "", + hostname: "fake", + port: 443, + protocol: "https", + type: "basic", + }); + Object.defineProperty(Profiles, "getInstance", { + value: jest.fn(() => { + return { + allProfiles: [{name: "firstName", profile: {user:undefined, password: undefined}}, {name: "secondName"}], + defaultProfile: {name: "firstName"}, + promptCredentials: jest.fn(()=> { + return [{values: "fake"}, {values: "fake"}, {values: "fake"}]; + }), + }; + }) + }); + const folder = new ZoweUSSNode("/u/myuser", vscode.TreeItemCollapsibleState.Collapsed, testTree.mSessionNodes[0], sessionwocred, null); + folder.contextValue = extension.USS_DIR_CONTEXT; + await testTree.flipState(folder, true); + expect(JSON.stringify(folder.iconPath)).toContain("folder-open.svg"); + await testTree.flipState(folder, false); + expect(JSON.stringify(folder.iconPath)).toContain("folder-closed.svg"); + await testTree.flipState(folder, true); + expect(JSON.stringify(folder.iconPath)).toContain("folder-open.svg"); + }); + + it("Testing that expand tree with credential prompt ends in error", async () => { + const sessionwocred = new Session({ + user: "", + password: "", + hostname: "fake", + port: 443, + protocol: "https", + type: "basic", + }); + Object.defineProperty(Profiles, "getInstance", { + value: jest.fn(() => { + return { + allProfiles: [{name: "firstName", profile: {user:undefined, password: undefined}}, {name: "secondName"}], + defaultProfile: {name: "firstName"} + }; + }) + }); + const folder = new ZoweUSSNode("/u/myuser", vscode.TreeItemCollapsibleState.Collapsed, testTree.mSessionNodes[0], sessionwocred, null); + folder.contextValue = extension.USS_DIR_CONTEXT; + await testTree.flipState(folder, true); + expect(JSON.stringify(folder.iconPath)).not.toEqual("folder-open.svg"); + await testTree.flipState(folder, false); + expect(JSON.stringify(folder.iconPath)).not.toEqual("folder-closed.svg"); + await testTree.flipState(folder, true); + expect(JSON.stringify(folder.iconPath)).not.toEqual("folder-open.svg"); + }); + it("initialize USSTree is executed successfully", async () => { const mockLoadNamedProfile = jest.fn(); mockLoadNamedProfile.mockReturnValue({name:"aProfile", profile: {name:"aProfile", type:"zosmf", profile:{name:"aProfile", type:"zosmf"}}}); @@ -605,6 +663,134 @@ describe("Unit Tests (Jest)", () => { }); + it("tests the uss filter prompt credentials, favorites route", async () => { + showQuickPick.mockReset(); + showInputBox.mockReset(); + + const sessionwocred = new Session({ + user: "", + password: "", + hostname: "fake", + port: 443, + protocol: "https", + type: "basic", + }); + const ZosmfSession = jest.fn(); + Object.defineProperty(brightside, "ZosmfSession", { value: ZosmfSession }); + const createBasicZosmfSession = jest.fn(); + Object.defineProperty(ZosmfSession, "createBasicZosmfSession", { value: createBasicZosmfSession }); + createBasicZosmfSession.mockReturnValue(sessionwocred); + const dsNode = new ZoweUSSNode("[ussTestSess]: /u/myFile.txt", vscode.TreeItemCollapsibleState.Expanded, null, sessionwocred, null, false, "ussTestSess"); + Object.defineProperty(Profiles, "getInstance", { + value: jest.fn(() => { + return { + allProfiles: [{name: "firstName", profile: {user:undefined, password: undefined}}, {name: "secondName"}], + defaultProfile: {name: "firstName"}, + loadNamedProfile: mockLoadNamedProfile, + promptCredentials: jest.fn(()=> { + return ["fake", "fake", "fake"]; + }), + }; + }) + }); + dsNode.mProfileName = "ussTestSess"; + dsNode.getSession().ISession.user = ""; + dsNode.getSession().ISession.password = ""; + dsNode.getSession().ISession.base64EncodedAuth = ""; + dsNode.contextValue = extension.USS_SESSION_CONTEXT + extension.FAV_SUFFIX; + testTree.mSessionNodes.push(dsNode); + const qpItem: vscode.QuickPickItem = new utils.FilterDescriptor("\uFF0B " + "Create a new filter"); + + const resolveQuickPickHelper = jest.spyOn(utils, "resolveQuickPickHelper").mockImplementation( + () => Promise.resolve(qpItem) + ); + const spyMe = new USSTree(); + Object.defineProperty(spyMe, "ussFilterPrompt", { + value: jest.fn(() => { + return { + tempNode: dsNode, + mSessionNodes: {Session: {ISession: {user: "", password: "", base64EncodedAuth: ""}}, mProfileName: "ussTestSess"} + }; + }) + }); + createQuickPick.mockReturnValue({ + placeholder: "Select a filter", + activeItems: [qpItem], + ignoreFocusOut: true, + items: [qpItem], + value: "", + show: jest.fn(()=>{ + return {}; + }), + hide: jest.fn(()=>{ + return {}; + }), + onDidAccept: jest.fn(()=>{ + return {}; + }) + }); + + await testTree.ussFilterPrompt(dsNode); + + const nodeLength = testTree.mSessionNodes.length - 1; + expect(testTree.mSessionNodes[nodeLength].fullPath).toEqual("/u/myFile.txt"); + + }); + + it("tests the uss filter, favorites route", async () => { + showQuickPick.mockReset(); + showInputBox.mockReset(); + + const sessionwocred = new Session({ + user: "", + password: "", + hostname: "fake", + port: 443, + protocol: "https", + type: "basic", + }); + const ZosmfSession = jest.fn(); + Object.defineProperty(brightside, "ZosmfSession", { value: ZosmfSession }); + const createBasicZosmfSession = jest.fn(); + Object.defineProperty(ZosmfSession, "createBasicZosmfSession", { value: createBasicZosmfSession }); + createBasicZosmfSession.mockReturnValue(sessionwocred); + const dsNode = new ZoweUSSNode("[ussTestSess2]: /u/myFile.txt", vscode.TreeItemCollapsibleState.Expanded, null, sessionwocred, null, false, "ussTestSess2"); + Object.defineProperty(Profiles, "getInstance", { + value: jest.fn(() => { + return { + allProfiles: [{name: "firstName"}, {name: "secondName"}], + defaultProfile: {name: "firstName"}, + loadNamedProfile: mockLoadNamedProfile, + promptCredentials: jest.fn(()=> { + return ["", "", ""]; + }), + }; + }) + }); + dsNode.mProfileName = "ussTestSess2"; + dsNode.getSession().ISession.user = ""; + dsNode.getSession().ISession.password = ""; + dsNode.getSession().ISession.base64EncodedAuth = ""; + dsNode.contextValue = extension.USS_SESSION_CONTEXT + extension.FAV_SUFFIX; + testTree.mSessionNodes.push(dsNode); + + const spyMe = new USSTree(); + Object.defineProperty(spyMe, "ussFilterPrompt", { + value: jest.fn(() => { + return { + tempNode: dsNode, + mSessionNodes: {Session: {ISession: {user: "", password: "", base64EncodedAuth: ""}}} + }; + }) + }); + + await testTree.ussFilterPrompt(dsNode); + + const nodeLength = testTree.mSessionNodes.length - 1; + expect(testTree.mSessionNodes[nodeLength].fullPath).toEqual("/u/myFile.txt"); + + }); + it("tests the uss filter prompt credentials error", async () => { showQuickPick.mockReset(); showInputBox.mockReset(); diff --git a/__tests__/__unit__/ZoweJobNode.unit.test.ts b/__tests__/__unit__/ZoweJobNode.unit.test.ts index e51b8edfcd..dc6009577a 100644 --- a/__tests__/__unit__/ZoweJobNode.unit.test.ts +++ b/__tests__/__unit__/ZoweJobNode.unit.test.ts @@ -21,6 +21,7 @@ import * as profileLoader from "../../src/Profiles"; import * as utils from "../../src/utils"; import { Job } from "../../src/ZoweJobNode"; import { ZosJobsProvider, createJobsTree } from "../../src/ZosJobsProvider"; +import { ZoweUSSNode } from "../../src/ZoweUSSNode"; describe("Zos Jobs Unit Tests", () => { @@ -79,6 +80,14 @@ describe("Zos Jobs Unit Tests", () => { type: "basic", }); + const sessionwocred = new Session({ + user: "", + password: "", + hostname: "fake", + protocol: "https", + type: "basic", + }); + Object.defineProperty(profileLoader, "loadNamedProfile", { value: jest.fn((name: string) => { return { name }; @@ -175,7 +184,10 @@ describe("Zos Jobs Unit Tests", () => { return { allProfiles: [{name: "firstProfileName"}, {name: "fake"}], defaultProfile: {name: "firstProfileName"}, - loadNamedProfile: mockLoadNamedProfile + loadNamedProfile: mockLoadNamedProfile, + promptCredentials: jest.fn(()=> { + return ["fakeUser","","fakeEncoding"]; + }), }; }) }); @@ -195,6 +207,16 @@ describe("Zos Jobs Unit Tests", () => { expect(testJobsProvider.mSessionNodes[sessions].tooltip).toEqual("fake - owner: fake prefix: *"); }); + it("should add another session to the tree", async () => { + createBasicZosmfSession.mockReturnValue(sessionwocred); + const testJobsProvider = await createJobsTree(Logger.getAppLogger()); + const sessions = testJobsProvider.mSessionNodes.length; + await testJobsProvider.addSession("fake"); + expect(testJobsProvider.mSessionNodes[sessions]).toBeDefined(); + expect(testJobsProvider.mSessionNodes[sessions].label).toEqual("fake"); + expect(testJobsProvider.mSessionNodes[sessions].tooltip).toEqual("fake - owner: prefix: *"); + }); + it("tests that the user is informed when a job is deleted", async () => { showInformationMessage.mockReset(); const testJobsProvider = await createJobsTree(Logger.getAppLogger()); @@ -276,6 +298,7 @@ describe("Zos Jobs Unit Tests", () => { it("Testing that expand tree is executed successfully", async () => { const refresh = jest.fn(); + createBasicZosmfSession.mockReturnValue(session); const testJobsProvider = await createJobsTree(Logger.getAppLogger()); Object.defineProperty(testJobsProvider, "refresh", {value: refresh}); refresh.mockReset(); @@ -301,33 +324,62 @@ describe("Zos Jobs Unit Tests", () => { expect(job.iconPath).not.toBeDefined(); }); - /************************************************************************************************************* - * Jobs Filter prompts - *************************************************************************************************************/ - it("Testing that prompt credentials is called when searchPrompt is triggered", async () => { + it("Testing that prompt credentials work", async () => { + const refresh = jest.fn(); + createBasicZosmfSession.mockReturnValue(sessionwocred); + const newjobNode = new Job("[fake]: Owner:fakeUser Prefix:*", vscode.TreeItemCollapsibleState.Expanded, jobNode, sessionwocred, iJob); + const testJobsProvider = await createJobsTree(Logger.getAppLogger()); + Object.defineProperty(testJobsProvider, "refresh", {value: refresh}); + refresh.mockReset(); + jest.spyOn(testJobsProvider, "flipState"); + newjobNode.contextValue = extension.JOBS_SESSION_CONTEXT + extension.FAV_SUFFIX; + await testJobsProvider.flipState(newjobNode, true); + expect(testJobsProvider.flipState).toHaveBeenCalled(); + + const job = new Job("JOB1283", vscode.TreeItemCollapsibleState.Collapsed, testJobsProvider.mSessionNodes[0], + sessionwocred, iJob); + job.contextValue = "job"; + await testJobsProvider.flipState(job, true); + expect(JSON.stringify(job.iconPath)).toContain("folder-open.svg"); + + job.contextValue = "jobber"; + await testJobsProvider.flipState(job, true); + expect(job.iconPath).not.toBeDefined(); + }); + + it("Testing that prompt credentials will have an error", async () => { Object.defineProperty(profileLoader.Profiles, "getInstance", { value: jest.fn(() => { return { allProfiles: [{name: "firstName"}, {name: "secondName"}], defaultProfile: {name: "firstName"}, - promptCredentials: jest.fn(()=> { - return [{values: "fake"}, {values: "fake"}, {values: "fake"}]; - }), + promptCredentials: undefined }; }) }); + const refresh = jest.fn(); + createBasicZosmfSession.mockReturnValue(sessionwocred); + const newjobNode = new Job("[fake]: Owner:fakeUser Prefix:*", vscode.TreeItemCollapsibleState.Expanded, jobNode, sessionwocred, iJob); + const testJobsProvider = await createJobsTree(Logger.getAppLogger()); + Object.defineProperty(testJobsProvider, "refresh", {value: refresh}); + refresh.mockReset(); + jest.spyOn(testJobsProvider, "flipState"); + newjobNode.contextValue = extension.JOBS_SESSION_CONTEXT + extension.FAV_SUFFIX; + await testJobsProvider.flipState(newjobNode, true); + expect(testJobsProvider.flipState).toHaveBeenCalled(); + + newjobNode.label = "Favorites"; + await testJobsProvider.flipState(newjobNode, true); + expect(testJobsProvider.flipState).toHaveBeenCalled(); + }); - const sessionwocred = new Session({ - user: "", - password: "", - hostname: "fake", - protocol: "https", - type: "basic", - }); + /************************************************************************************************************* + * Jobs Filter prompts + *************************************************************************************************************/ + 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); - newjobNode.contextValue = "server"; - newjobNode.contextValue = "server"; + 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( @@ -361,6 +413,54 @@ describe("Zos Jobs Unit Tests", () => { expect(newjobNode.searchId).toEqual(""); }); + 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); + newjobNode.contextValue = extension.JOBS_SESSION_CONTEXT + extension.FAV_SUFFIX; + newjobNode.session.ISession.user = ""; + newjobNode.session.ISession.password = ""; + newjobNode.session.ISession.base64EncodedAuth = ""; + const testJobsProvider = await createJobsTree(Logger.getAppLogger()); + const qpItem: vscode.QuickPickItem = testJobsProvider.createOwner; + const resolveQuickPickHelper = jest.spyOn(utils, "resolveQuickPickHelper").mockImplementation( + () => Promise.resolve(qpItem) + ); + const spyMe = new ZosJobsProvider(); + Object.defineProperty(spyMe, "searchPrompt", { + value: jest.fn(() => { + return { + tempNode: newjobNode, + mSessionNodes: {Session: {user: "", password: "", base64EncodedAuth: ""}} + }; + }) + }); + 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(""); + await testJobsProvider.searchPrompt(newjobNode); + expect(newjobNode.contextValue).toEqual(extension.JOBS_SESSION_CONTEXT + extension.FAV_SUFFIX); + expect(newjobNode.owner).toEqual("fakeUser"); + expect(newjobNode.prefix).toEqual("*"); + expect(newjobNode.searchId).toEqual(""); + }); + it("Testing that prompt credentials error", async () => { Object.defineProperty(profileLoader.Profiles, "getInstance", { value: jest.fn(() => { @@ -371,17 +471,9 @@ describe("Zos Jobs Unit Tests", () => { }) }); - const sessionwocred = new Session({ - user: "", - password: "", - hostname: "fake", - protocol: "https", - type: "basic", - }); createBasicZosmfSession.mockReturnValue(sessionwocred); const newjobNode = new Job("jobtest", vscode.TreeItemCollapsibleState.Expanded, jobNode, sessionwocred, iJob); - newjobNode.contextValue = "server"; - newjobNode.contextValue = "server"; + newjobNode.contextValue = extension.JOBS_SESSION_CONTEXT; const testJobsProvider = await createJobsTree(Logger.getAppLogger()); testJobsProvider.initializeJobsTree(Logger.getAppLogger()); await testJobsProvider.searchPrompt(newjobNode); diff --git a/__tests__/__unit__/extension.unit.test.ts b/__tests__/__unit__/extension.unit.test.ts index 95be1083ef..b3b2c143eb 100644 --- a/__tests__/__unit__/extension.unit.test.ts +++ b/__tests__/__unit__/extension.unit.test.ts @@ -1234,6 +1234,67 @@ describe("Extension Unit Tests", () => { expect(dataSetCreate.mock.calls.length).toBe(5); }); + it("tests the createFile for prompt credentials, favorite route", async () => { + Object.defineProperty(profileLoader.Profiles, "getInstance", { + value: jest.fn(() => { + return { + allProfiles: [{name: "firstName", profile: {user:undefined, password: undefined}}, {name: "secondName"}], + defaultProfile: {name: "firstName"}, + promptCredentials: jest.fn(()=> { + return [{values: "fake"}, {values: "fake"}, {values: "fake"}]; + }), + }; + }) + }); + const sessionwocred = new brtimperative.Session({ + user: "", + password: "", + hostname: "fake", + protocol: "https", + type: "basic", + }); + + createBasicZosmfSession.mockReturnValue(sessionwocred); + const newsessNode = new ZoweNode("sestest", vscode.TreeItemCollapsibleState.Expanded, null, sessionwocred); + newsessNode.contextValue = extension.DS_SESSION_CONTEXT + extension.FAV_SUFFIX; + + showQuickPick.mockReset(); + getConfiguration.mockReset(); + showInputBox.mockReset(); + dataSetCreate.mockReset(); + + getConfiguration.mockReturnValue("FakeConfig"); + showInputBox.mockReturnValueOnce("FakeName"); + + + showQuickPick.mockResolvedValueOnce("Data Set Binary"); + await extension.createFile(newsessNode, testTree); + showQuickPick.mockResolvedValueOnce("Data Set C"); + await extension.createFile(newsessNode, testTree); + showQuickPick.mockResolvedValueOnce("Data Set Classic"); + await extension.createFile(newsessNode, testTree); + showQuickPick.mockResolvedValueOnce("Data Set Partitioned"); + await extension.createFile(newsessNode, testTree); + showQuickPick.mockResolvedValueOnce("Data Set Sequential"); + await extension.createFile(newsessNode, testTree); + + // tslint:disable-next-line: no-magic-numbers + expect(showQuickPick.mock.calls.length).toBe(5); + // tslint:disable-next-line: no-magic-numbers + expect(getConfiguration.mock.calls.length).toBe(5); + expect(getConfiguration.mock.calls[0][0]).toBe("Zowe-Default-Datasets-Binary"); + expect(getConfiguration.mock.calls[1][0]).toBe("Zowe-Default-Datasets-C"); + expect(getConfiguration.mock.calls[2][0]).toBe("Zowe-Default-Datasets-Classic"); + // tslint:disable-next-line: no-magic-numbers + expect(getConfiguration.mock.calls[3][0]).toBe("Zowe-Default-Datasets-PDS"); + // tslint:disable-next-line: no-magic-numbers + expect(getConfiguration.mock.calls[4][0]).toBe("Zowe-Default-Datasets-PS"); + // tslint:disable-next-line: no-magic-numbers + expect(showInputBox.mock.calls.length).toBe(5); + // tslint:disable-next-line: no-magic-numbers + expect(dataSetCreate.mock.calls.length).toBe(5); + }); + it("tests the createFile for prompt credentials error", async () => { Object.defineProperty(profileLoader.Profiles, "getInstance", { value: jest.fn(() => { @@ -1661,6 +1722,108 @@ describe("Extension Unit Tests", () => { showErrorMessage.mockReset(); }); + it("Testing that that openPS credentials prompt is executed successfully", async () => { + showQuickPick.mockReset(); + showInputBox.mockReset(); + showTextDocument.mockReset(); + openTextDocument.mockReset(); + const sessionwocred = new brtimperative.Session({ + user: "", + password: "", + hostname: "fake", + port: 443, + protocol: "https", + type: "basic", + }); + const dsNode = new ZoweNode("testSess", vscode.TreeItemCollapsibleState.Expanded, sessNode, sessionwocred); + dsNode.contextValue = extension.DS_SESSION_CONTEXT; + Object.defineProperty(profileLoader.Profiles, "getInstance", { + value: jest.fn(() => { + return { + allProfiles: [{name: "firstName", profile: {user:undefined, password: undefined}}, {name: "secondName"}], + defaultProfile: {name: "firstName"}, + promptCredentials: jest.fn(()=> { + return [{values: "fake"}, {values: "fake"}, {values: "fake"}]; + }), + }; + }) + }); + + showInputBox.mockReturnValueOnce("fake"); + showInputBox.mockReturnValueOnce("fake"); + + await extension.openPS(dsNode, true); + expect(openTextDocument.mock.calls.length).toBe(1); + expect(showTextDocument.mock.calls.length).toBe(1); + }); + + it("Testing that that openPS credentials prompt works with favorites", async () => { + showTextDocument.mockReset(); + openTextDocument.mockReset(); + showQuickPick.mockReset(); + showInputBox.mockReset(); + const sessionwocred = new brtimperative.Session({ + user: "", + password: "", + hostname: "fake", + port: 443, + protocol: "https", + type: "basic", + }); + const dsNode = new ZoweNode("[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(() => { + return { + allProfiles: [{name: "firstName", profile: {user:undefined, password: undefined}}, {name: "secondName"}], + defaultProfile: {name: "firstName"}, + promptCredentials: jest.fn(()=> { + return [{values: "fake"}, {values: "fake"}, {values: "fake"}]; + }), + }; + }) + }); + + showInputBox.mockReturnValueOnce("fake"); + showInputBox.mockReturnValueOnce("fake"); + + await extension.openPS(dsNode, true); + expect(openTextDocument.mock.calls.length).toBe(1); + expect(showTextDocument.mock.calls.length).toBe(1); + }); + + it("Testing that that openPS credentials prompt ends in error", async () => { + showTextDocument.mockReset(); + openTextDocument.mockReset(); + showQuickPick.mockReset(); + showInputBox.mockReset(); + const sessionwocred = new brtimperative.Session({ + user: "", + password: "", + hostname: "fake", + port: 443, + protocol: "https", + type: "basic", + }); + const dsNode = new ZoweNode("testSess", vscode.TreeItemCollapsibleState.Expanded, sessNode, sessionwocred); + dsNode.contextValue = extension.DS_SESSION_CONTEXT; + Object.defineProperty(profileLoader.Profiles, "getInstance", { + value: jest.fn(() => { + return { + allProfiles: [{name: "firstName", profile: {user:undefined, password: undefined}}, {name: "secondName"}], + defaultProfile: {name: "firstName"} + }; + }) + }); + + await extension.openPS(dsNode, true); + expect(showErrorMessage.mock.calls.length).toBe(1); + showQuickPick.mockReset(); + showInputBox.mockReset(); + showInformationMessage.mockReset(); + showErrorMessage.mockReset(); + }); + it("Testing that safeSave is executed successfully", async () => { dataSet.mockReset(); openTextDocument.mockReset(); @@ -2288,6 +2451,109 @@ describe("Extension Unit Tests", () => { expect(showTextDocument.mock.calls[0][0]).toBe("test.doc"); }); + it("Testing that that openUSS credentials prompt is executed successfully", async () => { + showQuickPick.mockReset(); + showInputBox.mockReset(); + showTextDocument.mockReset(); + openTextDocument.mockReset(); + const sessionwocred = new brtimperative.Session({ + user: "", + password: "", + hostname: "fake", + port: 443, + protocol: "https", + type: "basic", + }); + const dsNode = new ZoweUSSNode("testSess", vscode.TreeItemCollapsibleState.Expanded, ussNode, sessionwocred, null); + dsNode.contextValue = extension.USS_SESSION_CONTEXT; + Object.defineProperty(profileLoader.Profiles, "getInstance", { + value: jest.fn(() => { + return { + allProfiles: [{name: "firstName", profile: {user:undefined, password: undefined}}, {name: "secondName"}], + defaultProfile: {name: "firstName"}, + promptCredentials: jest.fn(()=> { + return [{values: "fake"}, {values: "fake"}, {values: "fake"}]; + }), + }; + }) + }); + + showInputBox.mockReturnValueOnce("fake"); + showInputBox.mockReturnValueOnce("fake"); + + await extension.openUSS(dsNode, false, true); + expect(openTextDocument.mock.calls.length).toBe(1); + expect(showTextDocument.mock.calls.length).toBe(1); + }); + + it("Testing that that openUSS credentials prompt works with favorites", async () => { + showTextDocument.mockReset(); + openTextDocument.mockReset(); + showQuickPick.mockReset(); + showInputBox.mockReset(); + const sessionwocred = new brtimperative.Session({ + user: "", + password: "", + hostname: "fake", + port: 443, + protocol: "https", + type: "basic", + }); + const dsNode = new ZoweUSSNode("testSess", vscode.TreeItemCollapsibleState.Expanded, ussNode, sessionwocred, null); + dsNode.contextValue = extension.USS_DIR_CONTEXT + extension.FAV_SUFFIX; + Object.defineProperty(profileLoader.Profiles, "getInstance", { + value: jest.fn(() => { + return { + allProfiles: [{name: "firstName", profile: {user:undefined, password: undefined}}, {name: "secondName"}], + defaultProfile: {name: "firstName"}, + promptCredentials: jest.fn(()=> { + return [{values: "fake"}, {values: "fake"}, {values: "fake"}]; + }), + }; + }) + }); + + showInputBox.mockReturnValueOnce("fake"); + showInputBox.mockReturnValueOnce("fake"); + + await extension.openUSS(dsNode, false, true); + expect(openTextDocument.mock.calls.length).toBe(1); + expect(showTextDocument.mock.calls.length).toBe(1); + }); + + it("Testing that that openUSS credentials prompt ends in error", async () => { + showTextDocument.mockReset(); + openTextDocument.mockReset(); + showQuickPick.mockReset(); + showInputBox.mockReset(); + const sessionwocred = new brtimperative.Session({ + user: "", + password: "", + hostname: "fake", + port: 443, + protocol: "https", + type: "basic", + }); + const dsNode = new ZoweUSSNode("testSess", vscode.TreeItemCollapsibleState.Expanded, ussNode, sessionwocred, null); + dsNode.contextValue = extension.USS_SESSION_CONTEXT; + Object.defineProperty(profileLoader.Profiles, "getInstance", { + value: jest.fn(() => { + return { + allProfiles: [{name: "firstName", profile: {user:undefined, password: undefined}}, {name: "secondName"}], + defaultProfile: {name: "firstName"} + }; + }) + }); + + await extension.openUSS(dsNode, false, true); + expect(showErrorMessage.mock.calls.length).toBe(1); + showQuickPick.mockReset(); + showInputBox.mockReset(); + showInformationMessage.mockReset(); + showErrorMessage.mockReset(); + }); + + it("Testing that saveUSSFile is executed successfully", async () => { const testDoc: vscode.TextDocument = { fileName: path.join(extension.USS_DIR, ussNode.label, "testFile"), @@ -2456,6 +2722,35 @@ describe("Extension Unit Tests", () => { expect(extension.refreshJobsServer).toHaveBeenCalled(); }); + it("tests the refresh Jobs Server for prompt credentials, favorites route", async () => { + showQuickPick.mockReset(); + showInputBox.mockReset(); + const addJobsSession = jest.spyOn(extension, "refreshJobsServer"); + Object.defineProperty(profileLoader.Profiles, "getInstance", { + value: jest.fn(() => { + return { + allProfiles: [{name: "firstName", profile: {user:undefined, password: undefined}}, {name: "secondName"}], + defaultProfile: {name: "firstName"}, + promptCredentials: jest.fn(()=> { + return [{values: "fake"}, {values: "fake"}, {values: "fake"}]; + }), + }; + }) + }); + const sessionwocred = new brtimperative.Session({ + user: "", + password: "", + hostname: "fake", + protocol: "https", + type: "basic", + }); + createBasicZosmfSession.mockReturnValue(sessionwocred); + const newjobNode = new Job("jobtest", vscode.TreeItemCollapsibleState.Expanded, jobNode, sessionwocred, iJob); + newjobNode.contextValue = extension.JOBS_SESSION_CONTEXT + extension.FAV_SUFFIX; + await extension.refreshJobsServer(newjobNode); + expect(extension.refreshJobsServer).toHaveBeenCalled(); + }); + it("tests the refresh Jobs Server", async () => { showQuickPick.mockReset(); showInputBox.mockReset(); @@ -2777,6 +3072,69 @@ describe("Extension Unit Tests", () => { expect(showErrorMessage.mock.calls.length).toBe(1); }); + it("tests that the spool content credentials prompt is executed successfully", async () => { + showTextDocument.mockReset(); + openTextDocument.mockReset(); + const sessionwocred = new brtimperative.Session({ + user: "", + password: "", + hostname: "fake", + port: 443, + protocol: "https", + type: "basic", + }); + createBasicZosmfSession.mockReturnValue(sessionwocred); + const newjobNode = new Job("jobtest", vscode.TreeItemCollapsibleState.Expanded, jobNode, sessionwocred, iJob); + newjobNode.contextValue = extension.JOBS_SESSION_CONTEXT; + Object.defineProperty(profileLoader.Profiles, "getInstance", { + value: jest.fn(() => { + return { + allProfiles: [{name: "firstName", profile: {user:undefined, password: undefined}}, {name: "secondName"}], + defaultProfile: {name: "firstName"}, + loadNamedProfile: mockLoadNamedProfile, + promptCredentials: jest.fn(()=> { + return [{values: "fake"}, {values: "fake"}, {values: "fake"}]; + }), + }; + }) + }); + + showInputBox.mockReturnValueOnce("fake"); + showInputBox.mockReturnValueOnce("fake"); + + await extension.getSpoolContent(newjobNode.label, iJobFile); + expect(showTextDocument.mock.calls.length).toBe(1); + }); + + it("tests that the spool content credentials prompt ends in error", async () => { + showTextDocument.mockReset(); + openTextDocument.mockReset(); + const sessionwocred = new brtimperative.Session({ + user: "", + password: "", + hostname: "fake", + port: 443, + protocol: "https", + type: "basic", + }); + createBasicZosmfSession.mockReturnValue(sessionwocred); + const newjobNode = new Job("jobtest", vscode.TreeItemCollapsibleState.Expanded, jobNode, sessionwocred, iJob); + newjobNode.contextValue = extension.JOBS_SESSION_CONTEXT; + Object.defineProperty(profileLoader.Profiles, "getInstance", { + value: jest.fn(() => { + return { + allProfiles: [{name: "firstName", profile: {user:undefined, password: undefined}}, {name: "secondName"}], + defaultProfile: {name: "firstName"}, + loadNamedProfile: mockLoadNamedProfile + }; + }) + }); + + await extension.getSpoolContent(newjobNode.label, iJobFile); + expect(showErrorMessage.mock.calls.length).toBe(1); + showErrorMessage.mockReset(); + }); + it("tests that a stop command is issued", async () => { showInformationMessage.mockReset(); issueSimple.mockReturnValueOnce({commandResponse: "fake response"}); diff --git a/__tests__/__unit__/uss/ussNodeActions.unit.test.ts b/__tests__/__unit__/uss/ussNodeActions.unit.test.ts index e20267d578..c7ea782c07 100644 --- a/__tests__/__unit__/uss/ussNodeActions.unit.test.ts +++ b/__tests__/__unit__/uss/ussNodeActions.unit.test.ts @@ -213,6 +213,40 @@ describe("ussNodeActions", () => { }); + it("tests the uss create node credentials operation cancelled", async () => { + showQuickPick.mockReset(); + showInputBox.mockReset(); + showInformationMessage.mockReset(); + const sessionwocred = new brtimperative.Session({ + user: "", + password: "", + hostname: "fake", + port: 443, + protocol: "https", + type: "basic", + }); + const sessNode = new ZoweUSSNode("sestest", vscode.TreeItemCollapsibleState.Expanded, null, session, null); + sessNode.contextValue = extension.USS_SESSION_CONTEXT; + const dsNode = new ZoweUSSNode("testSess", vscode.TreeItemCollapsibleState.Expanded, sessNode, sessionwocred, null); + dsNode.contextValue = extension.USS_SESSION_CONTEXT; + Object.defineProperty(Profiles, "getInstance", { + value: jest.fn(() => { + return { + allProfiles: [{name: "firstName", profile: {user:undefined, password: undefined}}, {name: "secondName"}], + defaultProfile: {name: "firstName"}, + promptCredentials: jest.fn(()=> { + return [undefined, undefined, undefined]; + }), + }; + }) + }); + + await ussNodeActions.createUSSNodeDialog(dsNode, testUSSTree); + + expect(testUSSTree.refresh).not.toHaveBeenCalled(); + + }); + it("tests the uss filter prompt credentials error", async () => { showQuickPick.mockReset(); showInputBox.mockReset(); diff --git a/src/DatasetTree.ts b/src/DatasetTree.ts index 531da58334..139c939de8 100644 --- a/src/DatasetTree.ts +++ b/src/DatasetTree.ts @@ -108,8 +108,11 @@ export class DatasetTree implements vscode.TreeDataProvider { continue; } } else if (favoriteSearchPattern.test(line)) { + const sesName = line.substring(1, line.lastIndexOf("]")).trim(); + const zosmfProfile = Profiles.getInstance().loadNamedProfile(sesName); + const session = zowe.ZosmfSession.createBasicZosmfSession(zosmfProfile.profile); const node = new ZoweNode(line.substring(0, line.lastIndexOf("{")), - vscode.TreeItemCollapsibleState.None, this.mFavoriteSession, null); + vscode.TreeItemCollapsibleState.None, this.mFavoriteSession, session); node.command = { command: "zowe.pattern", title: "", arguments: [node] }; const light = path.join(__dirname, "..", "..", "resources", "light", "pattern.svg"); const dark = path.join(__dirname, "..", "..", "resources", "dark", "pattern.svg"); @@ -364,31 +367,35 @@ export class DatasetTree implements vscode.TreeDataProvider { let usrNme: string; let passWrd: string; let baseEncd: string; - try { - if ((!node.getSession().ISession.user) || (!node.getSession().ISession.password)) { - try { - const values = await Profiles.getInstance().promptCredentials(node.label); - 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) { - node.getSession().ISession.user = usrNme; - node.getSession().ISession.password = passWrd; - node.getSession().ISession.base64EncodedAuth = baseEncd; - this.validProfile = 0; + let sesNamePrompt: string; + if (node.contextValue.endsWith(extension.FAV_SUFFIX)) { + sesNamePrompt = node.label.substring(1, node.label.indexOf("]")); + } else { + sesNamePrompt = node.label; + } + if ((!node.getSession().ISession.user) || (!node.getSession().ISession.password)) { + try { + const values = await Profiles.getInstance().promptCredentials(sesNamePrompt); + if (values !== undefined) { + usrNme = values [0]; + passWrd = values [1]; + baseEncd = values [2]; } - await this.refreshElement(node); - await this.refresh(); - } else { + } catch (error) { + vscode.window.showErrorMessage(error.message); + } + if (usrNme !== undefined && passWrd !== undefined && baseEncd !== undefined) { + node.getSession().ISession.user = usrNme; + node.getSession().ISession.password = passWrd; + node.getSession().ISession.base64EncodedAuth = baseEncd; this.validProfile = 0; + } else { + return; } - } catch (error) { - vscode.window.showErrorMessage(error.message); + await this.refreshElement(node); + await this.refresh(); + } else { + this.validProfile = 0; } if (this.validProfile === 0) { if (node.contextValue === extension.DS_SESSION_CONTEXT) { @@ -446,7 +453,13 @@ export class DatasetTree implements vscode.TreeDataProvider { pattern = node.label.trim().substring(node.label.trim().indexOf(":") + 2); const session = node.label.trim().substring(node.label.trim().indexOf("[") + 1, node.label.trim().indexOf("]")); await this.addSession(session); + const faveNode = node; node = this.mSessionNodes.find((tempNode) => tempNode.label.trim() === session); + 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; + } } // update the treeview with the new pattern node.label = node.label.trim()+ " "; @@ -466,9 +479,48 @@ export class DatasetTree implements vscode.TreeDataProvider { * @param isOpen the intended state of the the tree view provider, true or false */ public async flipState(element: ZoweNode, isOpen: boolean = false) { - element.iconPath = applyIcons(element, isOpen ? extension.ICON_STATE_OPEN : extension.ICON_STATE_CLOSED); - element.dirty = true; - this.mOnDidChangeTreeData.fire(element); + 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); + } } /** diff --git a/src/USSTree.ts b/src/USSTree.ts index dca29fed0f..5f39fa662d 100644 --- a/src/USSTree.ts +++ b/src/USSTree.ts @@ -246,9 +246,42 @@ export class USSTree implements vscode.TreeDataProvider { * @param isOpen the intended state of the the tree view provider, true or false */ public async flipState(element: ZoweUSSNode, isOpen: boolean = false) { - element.iconPath = applyIcons(element, isOpen ? extension.ICON_STATE_OPEN : extension.ICON_STATE_CLOSED); - element.dirty = true; - this.mOnDidChangeTreeData.fire(element); + if (element.label !== "Favorites") { + let usrNme: string; + let passWrd: string; + let baseEncd: string; + if ((!element.getSession().ISession.user) || (!element.getSession().ISession.password)) { + try { + const values = await Profiles.getInstance().promptCredentials(element.mProfileName); + if (values !== undefined) { + usrNme = values [0]; + passWrd = values [1]; + baseEncd = values [2]; + } + } catch (error) { + vscode.window.showErrorMessage(error.message); + } + if (usrNme !== undefined && passWrd !== undefined && baseEncd !== undefined) { + element.getSession().ISession.user = usrNme; + element.getSession().ISession.password = passWrd; + element.getSession().ISession.base64EncodedAuth = baseEncd; + this.validProfile = 1; + } else { + return; + } + await this.refreshElement(element); + await this.refresh(); + } else { + this.validProfile = 1; + } + } else { + this.validProfile = 1; + } + if (this.validProfile === 1) { + element.iconPath = applyIcons(element, isOpen ? extension.ICON_STATE_OPEN : extension.ICON_STATE_CLOSED); + element.dirty = true; + this.mOnDidChangeTreeData.fire(element); + } } public async onDidChangeConfiguration(e) { @@ -285,7 +318,7 @@ export class USSTree implements vscode.TreeDataProvider { let baseEncd: string; if ((!(node.getSession().ISession.user).trim()) || (!(node.getSession().ISession.password).trim())) { try { - const values = await Profiles.getInstance().promptCredentials(node.label); + const values = await Profiles.getInstance().promptCredentials(node.mProfileName); if (values !== undefined) { usrNme = values [0]; passWrd = values [1]; @@ -299,6 +332,8 @@ export class USSTree implements vscode.TreeDataProvider { node.getSession().ISession.password = passWrd; node.getSession().ISession.base64EncodedAuth = baseEncd; this.validProfile = 0; + } else { + return; } await this.refreshElement(node); await this.refresh(); @@ -362,9 +397,15 @@ export class USSTree implements vscode.TreeDataProvider { remotepath = node.label.trim().substring(node.label.trim().indexOf(":") + 2); const session = node.label.trim().substring(node.label.trim().indexOf("[") + 1, node.label.trim().indexOf("]")); await this.addSession(session); + const faveNode = node; sessionNode = this.mSessionNodes.find((tempNode) => tempNode.mProfileName === session ); + if ((!sessionNode.getSession().ISession.user) || (!sessionNode.getSession().ISession.password)) { + sessionNode.getSession().ISession.user = faveNode.getSession().ISession.user; + sessionNode.getSession().ISession.password = faveNode.getSession().ISession.password; + sessionNode.getSession().ISession.base64EncodedAuth = faveNode.getSession().ISession.base64EncodedAuth; + } } // Sanitization: Replace multiple preceding forward slashes with just one forward slash const sanitizedPath = remotepath.replace(/\/\/+/, "/"); diff --git a/src/ZosJobsProvider.ts b/src/ZosJobsProvider.ts index 249a175050..cccace97f0 100644 --- a/src/ZosJobsProvider.ts +++ b/src/ZosJobsProvider.ts @@ -67,6 +67,10 @@ export class ZosJobsProvider implements vscode.TreeDataProvider { public getChildren(element?: Job | undefined): vscode.ProviderResult { if (element) { + // solution for optional credentials. Owner is having error on initialization. + if (element.owner === "") { + return; + } if (element.contextValue === extension.FAVORITE_CONTEXT) { return this.mFavorites; } @@ -168,9 +172,49 @@ export class ZosJobsProvider implements vscode.TreeDataProvider { * @param isOpen the intended state of the the tree view provider, true or false */ public async flipState(element: Job, isOpen: boolean = false) { - element.iconPath = applyIcons(element, isOpen ? extension.ICON_STATE_OPEN : extension.ICON_STATE_CLOSED); - element.dirty = true; - this.mOnDidChangeTreeData.fire(element); + if (element.label !== "Favorites") { + let usrNme: string; + let passWrd: string; + let baseEncd: string; + let sesNamePrompt: string; + if (element.contextValue.endsWith(extension.FAV_SUFFIX)) { + sesNamePrompt = element.label.substring(1, element.label.indexOf("]")); + } else { + sesNamePrompt = element.label; + } + if ((!element.session.ISession.user) || (!element.session.ISession.password)) { + try { + const values = await Profiles.getInstance().promptCredentials(sesNamePrompt); + if (values !== undefined) { + usrNme = values [0]; + passWrd = values [1]; + baseEncd = values [2]; + } + } catch (error) { + vscode.window.showErrorMessage(error.message); + } + if (usrNme !== undefined && passWrd !== undefined && baseEncd !== undefined) { + element.session.ISession.user = usrNme; + element.session.ISession.password = passWrd; + element.session.ISession.base64EncodedAuth = baseEncd; + element.owner = usrNme; + this.validProfile = 1; + } else { + return; + } + await this.refreshElement(element); + await this.refresh(); + } else { + this.validProfile = 1; + } + } else { + this.validProfile = 1; + } + if (this.validProfile === 1) { + element.iconPath = applyIcons(element, isOpen ? extension.ICON_STATE_OPEN : extension.ICON_STATE_CLOSED); + element.dirty = true; + this.mOnDidChangeTreeData.fire(element); + } } /** @@ -297,9 +341,15 @@ export class ZosJobsProvider implements vscode.TreeDataProvider { let usrNme: string; let passWrd: string; let baseEncd: string; + let sesNamePrompt: string; + if (node.contextValue.endsWith(extension.FAV_SUFFIX)) { + sesNamePrompt = node.label.substring(1, node.label.indexOf("]")); + } else { + sesNamePrompt = node.label; + } if ((!node.session.ISession.user) || (!node.session.ISession.password)) { try { - const values = await Profiles.getInstance().promptCredentials(node.label); + const values = await Profiles.getInstance().promptCredentials(sesNamePrompt); if (values !== undefined) { usrNme = values [0]; passWrd = values [1]; @@ -312,7 +362,10 @@ export class ZosJobsProvider implements vscode.TreeDataProvider { node.session.ISession.user = usrNme; node.session.ISession.password = passWrd; node.session.ISession.base64EncodedAuth = baseEncd; + node.owner = usrNme; this.validProfile = 0; + } else { + return; } await this.refreshElement(node); await this.refresh(); @@ -423,8 +476,14 @@ export class ZosJobsProvider implements vscode.TreeDataProvider { // executing search from saved search in favorites searchCriteria = node.label.trim().substring(node.label.trim().indexOf(":") + 2); const session = node.label.trim().substring(node.label.trim().indexOf("[") + 1, node.label.trim().indexOf("]")); + 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; + } this.applySearchLabelToNode(node, searchCriteria); } this.addHistory(searchCriteria); diff --git a/src/extension.ts b/src/extension.ts index fd47257574..da91ef0f6a 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -770,10 +770,16 @@ export async function createFile(node: ZoweNode, datasetProvider: DatasetTree) { localize("createFile.dataSetPartitioned", "Data Set Partitioned"), localize("createFile.dataSetSequential", "Data Set Sequential") ]; + let sesNamePrompt: string; + if (node.contextValue.endsWith(FAV_SUFFIX)) { + sesNamePrompt = node.label.substring(1, node.label.indexOf("]")); + } else { + sesNamePrompt = node.label; + } if ((!node.getSession().ISession.user) || (!node.getSession().ISession.password)) { try { - const values = await Profiles.getInstance().promptCredentials(node.label); + const values = await Profiles.getInstance().promptCredentials(sesNamePrompt); if (values !== undefined) { usrNme = values [0]; passWrd = values [1]; @@ -787,6 +793,8 @@ export async function createFile(node: ZoweNode, datasetProvider: DatasetTree) { node.getSession().ISession.password = passWrd; node.getSession().ISession.base64EncodedAuth = baseEncd; validProfile = 0; + } else { + return; } await datasetProvider.refreshElement(node); await datasetProvider.refresh(); @@ -1409,48 +1417,81 @@ export function getUSSDocumentFilePath(node: ZoweUSSNode) { * @param {ZoweNode} node */ export async function openPS(node: ZoweNode, previewMember: boolean) { - try { - let label: string; - switch (node.mParent.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()+ ")"; - break; - case (DS_SESSION_CONTEXT): - label = node.label.trim(); - break; - case (DS_PDS_CONTEXT): - label = node.mParent.label.trim() + "(" + node.label.trim()+ ")"; - break; - default: - vscode.window.showErrorMessage(localize("openPS.invalidNode", "openPS() called from invalid node.")); - throw Error(localize("openPS.error.invalidNode", "openPS() called from invalid node.")); + const datasetProvider = new DatasetTree(); + let sesNamePrompt: string; + if (node.contextValue.endsWith(FAV_SUFFIX)) { + sesNamePrompt = node.label.substring(1, node.label.indexOf("]")); + } else { + sesNamePrompt = node.label; + } + if ((!node.getSession().ISession.user) || (!node.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); } - log.debug(localize("openPS.log.debug.openDataSet", "opening physical sequential data set from label ") + label); - // if local copy exists, open that instead of pulling from mainframe - if (!fs.existsSync(getDocumentFilePath(label, node))) { - await vscode.window.withProgress({ - location: vscode.ProgressLocation.Notification, - title: "Opening data set..." - }, function downloadDataset() { - return zowe.Download.dataSet(node.getSession(), label, { // TODO MISSED TESTING - file: getDocumentFilePath(label, node) - }); - }); + 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; } - const document = await vscode.workspace.openTextDocument(getDocumentFilePath(label, node)); - if (previewMember === true) { - await vscode.window.showTextDocument(document); + await datasetProvider.refreshElement(node); + await datasetProvider.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; + case (DS_PDS_CONTEXT + FAV_SUFFIX): + label = node.mParent.label.substring(node.mParent.label.indexOf(":") + 1).trim() + "(" + node.label.trim()+ ")"; + break; + case (DS_SESSION_CONTEXT): + label = node.label.trim(); + break; + case (DS_PDS_CONTEXT): + label = node.mParent.label.trim() + "(" + node.label.trim()+ ")"; + break; + default: + vscode.window.showErrorMessage(localize("openPS.invalidNode", "openPS() called from invalid node.")); + throw Error(localize("openPS.error.invalidNode", "openPS() called from invalid node.")); } - else { - await vscode.window.showTextDocument(document, {preview: false}); + log.debug(localize("openPS.log.debug.openDataSet", "opening physical sequential data set from label ") + label); + // if local copy exists, open that instead of pulling from mainframe + if (!fs.existsSync(getDocumentFilePath(label, node))) { + await vscode.window.withProgress({ + location: vscode.ProgressLocation.Notification, + title: "Opening data set..." + }, function downloadDataset() { + return zowe.Download.dataSet(node.getSession(), label, { // TODO MISSED TESTING + file: getDocumentFilePath(label, node) + }); + }); } - } catch (err) { - log.error(localize("openPS.log.error.openDataSet", "Error encountered when opening data set! ") + JSON.stringify(err)); - vscode.window.showErrorMessage(err.message); - throw (err); + const document = await vscode.workspace.openTextDocument(getDocumentFilePath(label, node)); + if (previewMember === true) { + await vscode.window.showTextDocument(document); + } + else { + await vscode.window.showTextDocument(document, {preview: false}); + } + } catch (err) { + log.error(localize("openPS.log.error.openDataSet", "Error encountered when opening data set! ") + JSON.stringify(err)); + vscode.window.showErrorMessage(err.message); + throw (err); + } } } @@ -1754,50 +1795,77 @@ export async function saveUSSFile(doc: vscode.TextDocument, ussFileProvider: USS * @param {ZoweUSSNode} node */ export async function openUSS(node: ZoweUSSNode, download = false, previewFile: boolean) { - 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 - if (download || !fs.existsSync(getUSSDocumentFilePath(node))) { - const chooseBinary = node.binary || await zowe.Utilities.isFileTagBinOrAscii(node.getSession(), node.fullPath); - await vscode.window.withProgress({ - location: vscode.ProgressLocation.Notification, - title: "Opening USS file...", - }, function downloadUSSFile() { - return zowe.Download.ussFile(node.getSession(), node.fullPath, { // TODO MISSED TESTING - file: getUSSDocumentFilePath(node), - binary: chooseBinary - }); + const ussFileProvider = new 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) { + vscode.window.showErrorMessage(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; } - const document = await vscode.workspace.openTextDocument(getUSSDocumentFilePath(node)); - if (previewFile === true) { - await vscode.window.showTextDocument(document); + 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.")); } - else { - await vscode.window.showTextDocument(document, {preview: false}); + 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 + if (download || !fs.existsSync(getUSSDocumentFilePath(node))) { + const chooseBinary = node.binary || await zowe.Utilities.isFileTagBinOrAscii(node.getSession(), node.fullPath); + await vscode.window.withProgress({ + location: vscode.ProgressLocation.Notification, + title: "Opening USS file...", + }, function downloadUSSFile() { + return zowe.Download.ussFile(node.getSession(), node.fullPath, { // TODO MISSED TESTING + file: getUSSDocumentFilePath(node), + binary: chooseBinary + }); } - } catch (err) { - log.error(localize("openUSS.log.error.openFile", "Error encountered when opening USS file: ") + JSON.stringify(err)); - vscode.window.showErrorMessage(err.message); - throw (err); + ); + } + const document = await vscode.workspace.openTextDocument(getUSSDocumentFilePath(node)); + if (previewFile === true) { + await vscode.window.showTextDocument(document); + } + else { + await vscode.window.showTextDocument(document, {preview: false}); + } + } catch (err) { + log.error(localize("openUSS.log.error.openFile", "Error encountered when opening USS file: ") + JSON.stringify(err)); + vscode.window.showErrorMessage(err.message); + throw (err); + } } } @@ -1823,12 +1891,36 @@ export async function stopCommand(job: Job) { } export async function getSpoolContent(session: string, spool: IJobFile) { - try { - const uri = encodeJobFile(session, spool); - const document = await vscode.workspace.openTextDocument(uri); - await vscode.window.showTextDocument(document); - } catch (error) { - vscode.window.showErrorMessage(error.message); + const zosmfProfile = Profiles.getInstance().loadNamedProfile(session); + const spoolSess = zowe.ZosmfSession.createBasicZosmfSession(zosmfProfile.profile); + if ((!spoolSess.ISession.user) || (!spoolSess.ISession.password)) { + try { + const values = await Profiles.getInstance().promptCredentials(session); + 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) { + spoolSess.ISession.user = usrNme; + spoolSess.ISession.password = passWrd; + spoolSess.ISession.base64EncodedAuth = baseEncd; + validProfile = 0; + } + } else { + validProfile = 0; + } + if (validProfile === 0) { + try { + const uri = encodeJobFile(session, spool); + const document = await vscode.workspace.openTextDocument(uri); + await vscode.window.showTextDocument(document); + } catch (error) { + vscode.window.showErrorMessage(error.message); + } } } @@ -1846,9 +1938,15 @@ export async function setPrefix(job: Job, jobsProvider: ZosJobsProvider) { export async function refreshJobsServer(node: Job) { const jobsProvider = new ZosJobsProvider(); + 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)) { try { - const values = await Profiles.getInstance().promptCredentials(node.label); + const values = await Profiles.getInstance().promptCredentials(sesNamePrompt); if (values !== undefined) { usrNme = values [0]; passWrd = values [1]; diff --git a/src/uss/ussNodeActions.ts b/src/uss/ussNodeActions.ts index fe0b8045be..8af0b82ae4 100644 --- a/src/uss/ussNodeActions.ts +++ b/src/uss/ussNodeActions.ts @@ -56,7 +56,7 @@ export async function createUSSNodeDialog(node: ZoweUSSNode, ussFileProvider: US let validProfile: number = -1; if ((!node.getSession().ISession.user.trim()) || (!node.getSession().ISession.password.trim())) { try { - const values = await Profiles.getInstance().promptCredentials(node.label); + const values = await Profiles.getInstance().promptCredentials(node.mProfileName); if (values !== undefined) { usrNme = values [0]; passWrd = values [1]; @@ -71,6 +71,8 @@ export async function createUSSNodeDialog(node: ZoweUSSNode, ussFileProvider: US node.getSession().ISession.password = passWrd; node.getSession().ISession.base64EncodedAuth = baseEncd; validProfile = 0; + } else { + return; } await ussFileProvider.refreshElement(node); await ussFileProvider.refresh();