Skip to content

Commit

Permalink
Merge pull request #959 from zowe/allocate-like
Browse files Browse the repository at this point in the history
Issue #904: Implement Allocate Like in Explorer
  • Loading branch information
zFernand0 authored Sep 9, 2020
2 parents 33f9088 + 83ed019 commit 3c3c671
Show file tree
Hide file tree
Showing 23 changed files with 353 additions and 110 deletions.
2 changes: 1 addition & 1 deletion __mocks__/mockCreators/datasets.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ export function createDatasetTree(sessionNode: ZoweDatasetNode, treeView: any):
createFilterString: jest.fn(),
setItem: jest.fn(),
getTreeView: jest.fn().mockImplementation(() => treeView),
searchInLoadedItems: jest.fn(),
getAllLoadedItems: jest.fn(),
removeFavorite: jest.fn(),
deleteSession: jest.fn(),
removeFileHistory: jest.fn(),
Expand Down
2 changes: 1 addition & 1 deletion __mocks__/mockCreators/uss.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ export function createUSSTree(favoriteNodes: ZoweUSSNode[], sessionNodes: ZoweUS
newTree.removeFavorite = jest.fn().mockImplementation((badFavorite) => removeNodeFromArray(badFavorite, newTree.mFavorites));
newTree.openItemFromPath = jest.fn();
newTree.deleteSession = jest.fn().mockImplementation((badSession) => removeNodeFromArray(badSession, newTree.mSessionNodes));
newTree.searchInLoadedItems = jest.fn();
newTree.getAllLoadedItems = jest.fn();
newTree.getTreeView = jest.fn().mockImplementation(() => treeView);
newTree.getTreeItem = jest.fn().mockImplementation(() => new vscode.TreeItem('test'));
newTree.getTreeType = jest.fn().mockImplementation(() => globals.PersistenceSchemaEnum.USS);
Expand Down
4 changes: 2 additions & 2 deletions __tests__/__unit__/dataset/DatasetTree.unit.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -863,7 +863,7 @@ describe("Dataset Tree Unit Tests - Function editSession", () => {
expect(node.getProfile().profile).toBe("testProfile");
});
});
describe("Dataset Tree Unit Tests - Function searchInLoadedItems", () => {
describe("Dataset Tree Unit Tests - Function getAllLoadedItems", () => {
function createBlockMocks() {
const session = createISession();
const imperativeProfile = createIProfile();
Expand All @@ -888,7 +888,7 @@ describe("Dataset Tree Unit Tests - Function searchInLoadedItems", () => {
testTree.mSessionNodes[1], blockMocks.session, globals.DS_DS_CONTEXT);
testTree.mSessionNodes[1].children.push(node);

const items = await testTree.searchInLoadedItems();
const items = await testTree.getAllLoadedItems();

expect(items).toEqual([node]);
});
Expand Down
115 changes: 114 additions & 1 deletion __tests__/__unit__/dataset/actions.unit.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ import {
createBasicZosmfSession, createInstanceOfProfile,
createIProfile,
createISession, createISessionWithoutCredentials, createTextDocument,
createTreeView
createTreeView,
createQuickPickContent
} from "../../../__mocks__/mockCreators/shared";
import {
createDatasetAttributes,
Expand Down Expand Up @@ -56,6 +57,7 @@ function createGlobalMocks() {
Object.defineProperty(vscode.workspace, "getConfiguration", { value: jest.fn(), configurable: true });
Object.defineProperty(vscode.window, "showTextDocument", { value: jest.fn(), configurable: true });
Object.defineProperty(vscode.window, "showQuickPick", { value: jest.fn(), configurable: true });
Object.defineProperty(vscode.window, "createQuickPick", { value: jest.fn(), configurable: true });
Object.defineProperty(vscode.commands, "executeCommand", { value: jest.fn(), configurable: true });
Object.defineProperty(globals, "LOG", { value: jest.fn(), configurable: true });
Object.defineProperty(globals.LOG, "debug", { value: jest.fn(), configurable: true });
Expand All @@ -66,6 +68,7 @@ function createGlobalMocks() {
Object.defineProperty(zowe.Delete, "dataSet", { value: jest.fn(), configurable: true });
Object.defineProperty(zowe, "Create", { value: jest.fn(), configurable: true });
Object.defineProperty(zowe.Create, "dataSet", { value: jest.fn(), configurable: true });
Object.defineProperty(zowe.Create, "dataSetLike", { value: jest.fn(), configurable: true });
Object.defineProperty(fs, "unlinkSync", { value: jest.fn(), configurable: true });
Object.defineProperty(fs, "existsSync", { value: jest.fn(), configurable: true });
Object.defineProperty(sharedUtils, "concatChildNodes", { value: jest.fn(), configurable: true });
Expand Down Expand Up @@ -1968,3 +1971,113 @@ describe("Dataset Actions Unit Tests - Function openPS", () => {
expect(mocked(vscode.workspace.openTextDocument)).toBeCalledWith(sharedUtils.getDocumentFilePath(child.label, child));
});
});

describe("Dataset Actions Unit Tests - Function allocateLike", () => {
function createBlockMocks() {
const session = createISession();
const imperativeProfile = createIProfile();
const treeView = createTreeView();
const datasetSessionNode = createDatasetSessionNode(session, imperativeProfile);
const testDatasetTree = createDatasetTree(datasetSessionNode, treeView);
const testNode = new ZoweDatasetNode("nodePDS", vscode.TreeItemCollapsibleState.None, datasetSessionNode, null);
const testSDSNode = new ZoweDatasetNode("nodeSDS", vscode.TreeItemCollapsibleState.None, datasetSessionNode, null);
const profileInstance = createInstanceOfProfile(imperativeProfile);
const mvsApi = createMvsApi(imperativeProfile);
const quickPickItem = new utils.FilterDescriptor(datasetSessionNode.label);
const quickPickContent = createQuickPickContent("", [quickPickItem], "");

bindMvsApi(mvsApi);
testNode.contextValue = globals.DS_PDS_CONTEXT;
testSDSNode.contextValue = globals.DS_DS_CONTEXT;

mocked(vscode.window.createQuickPick).mockReturnValue(quickPickContent);
mocked(Profiles.getInstance).mockReturnValue(profileInstance);
mocked(vscode.window.showInputBox).mockResolvedValue("test");
jest.spyOn(datasetSessionNode, "getChildren").mockResolvedValue([testNode, testSDSNode]);
testDatasetTree.createFilterString.mockResolvedValue("test");
jest.spyOn(utils, "resolveQuickPickHelper").mockResolvedValue(quickPickItem);
jest.spyOn(dsActions, "openPS").mockImplementation(() => null);

return {
session,
treeView,
testNode,
quickPickContent,
testSDSNode,
quickPickItem,
profileInstance,
imperativeProfile,
datasetSessionNode,
mvsApi,
testDatasetTree
};
}

it("Tests that allocateLike works if called from the command palette", async () => {
createGlobalMocks();
const blockMocks = createBlockMocks();

const errorHandlingSpy = jest.spyOn(utils, "errorHandling");

await dsActions.allocateLike(blockMocks.testDatasetTree);

expect(errorHandlingSpy).toHaveBeenCalledTimes(0);
expect(blockMocks.quickPickContent.show).toHaveBeenCalledTimes(1);
});
it("Tests that allocateLike works if called from the context menu", async () => {
createGlobalMocks();
const blockMocks = createBlockMocks();

const errorHandlingSpy = jest.spyOn(utils, "errorHandling");

await dsActions.allocateLike(blockMocks.testDatasetTree, blockMocks.testNode);

expect(errorHandlingSpy).toHaveBeenCalledTimes(0);
expect(blockMocks.quickPickContent.show).toHaveBeenCalledTimes(0);
});
it("Tests that the dataset filter string is updated on the session, to include the new node's name", async () => {
createGlobalMocks();
const blockMocks = createBlockMocks();

await dsActions.allocateLike(blockMocks.testDatasetTree, blockMocks.testNode);

expect(blockMocks.datasetSessionNode.pattern).toEqual("TEST");
});
it("Tests that allocateLike fails if no profile is selected", async () => {
createGlobalMocks();
const blockMocks = createBlockMocks();

jest.spyOn(utils, "resolveQuickPickHelper").mockResolvedValueOnce(null);

await dsActions.allocateLike(blockMocks.testDatasetTree);

expect(mocked(vscode.window.showInformationMessage)).toHaveBeenCalledWith("You must select a profile.");
});
it("Tests that allocateLike fails if no new dataset name is provided", async () => {
createGlobalMocks();
const blockMocks = createBlockMocks();

mocked(vscode.window.showInputBox).mockResolvedValueOnce(null);

await dsActions.allocateLike(blockMocks.testDatasetTree, blockMocks.testNode);

expect(mocked(vscode.window.showInformationMessage)).toHaveBeenCalledWith("You must enter a new data set name.");
});
it("Tests that allocateLike fails if error is thrown", async () => {
createGlobalMocks();
const blockMocks = createBlockMocks();

const errorHandlingSpy = jest.spyOn(utils, "errorHandling");
const errorMessage = new Error("Test error");
jest.spyOn(blockMocks.mvsApi, "allocateLikeDataSet").mockRejectedValue(errorMessage);

try {
await dsActions.allocateLike(blockMocks.testDatasetTree);
} catch (err) {
// do nothing
}

expect(errorHandlingSpy).toHaveBeenCalledTimes(1);
expect(errorHandlingSpy).toHaveBeenCalledWith(errorMessage, "test", "Unable to create data set: Test error");
});
});
1 change: 1 addition & 0 deletions __tests__/__unit__/extension.unit.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ async function createGlobalMocks() {
"zowe.createMember",
"zowe.deleteDataset",
"zowe.deletePDS",
"zowe.allocateLike",
"zowe.uploadDialog",
"zowe.deleteMember",
"zowe.editMember",
Expand Down
20 changes: 10 additions & 10 deletions __tests__/__unit__/shared/actions.unit.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,8 +82,8 @@ describe("Shared Actions Unit Tests - Function searchForLoadedItems", () => {
const testNode = new ZoweDatasetNode("HLQ.PROD2.STUFF", null,
blockMocks.datasetSessionNode, blockMocks.session, globals.DS_PDS_CONTEXT);
testNode.collapsibleState = vscode.TreeItemCollapsibleState.Collapsed;
blockMocks.testDatasetTree.searchInLoadedItems.mockResolvedValueOnce([testNode]);
blockMocks.testUssTree.searchInLoadedItems.mockResolvedValueOnce([]);
blockMocks.testDatasetTree.getAllLoadedItems.mockResolvedValueOnce([testNode]);
blockMocks.testUssTree.getAllLoadedItems.mockResolvedValueOnce([]);
blockMocks.testDatasetTree.getChildren.mockImplementation((arg) => {
if (arg) {
return Promise.resolve([testNode]);
Expand Down Expand Up @@ -115,8 +115,8 @@ describe("Shared Actions Unit Tests - Function searchForLoadedItems", () => {
blockMocks.testDatasetTree.getChildren.mockReturnValue([blockMocks.datasetSessionNode]);

jest.spyOn(dsActions, "openPS").mockResolvedValueOnce(null);
blockMocks.testDatasetTree.searchInLoadedItems.mockResolvedValueOnce([testMember]);
blockMocks.testUssTree.searchInLoadedItems.mockResolvedValueOnce([]);
blockMocks.testDatasetTree.getAllLoadedItems.mockResolvedValueOnce([testMember]);
blockMocks.testUssTree.getAllLoadedItems.mockResolvedValueOnce([]);
blockMocks.testDatasetTree.getChildren.mockImplementation((arg) => {
if (arg === testNode) {
return Promise.resolve([testMember]);
Expand All @@ -142,8 +142,8 @@ describe("Shared Actions Unit Tests - Function searchForLoadedItems", () => {
const folder = new ZoweUSSNode("folder", vscode.TreeItemCollapsibleState.Collapsed, blockMocks.ussSessionNode, null, "/");
blockMocks.testDatasetTree.getChildren.mockReturnValue([blockMocks.ussSessionNode]);

blockMocks.testDatasetTree.searchInLoadedItems.mockResolvedValueOnce([]);
blockMocks.testUssTree.searchInLoadedItems.mockResolvedValueOnce([folder]);
blockMocks.testDatasetTree.getAllLoadedItems.mockResolvedValueOnce([]);
blockMocks.testUssTree.getAllLoadedItems.mockResolvedValueOnce([folder]);
jest.spyOn(folder, "getProfileName").mockImplementationOnce(() => "firstName");
jest.spyOn(blockMocks.ussSessionNode, "getChildren").mockResolvedValueOnce([folder]);

Expand All @@ -166,8 +166,8 @@ describe("Shared Actions Unit Tests - Function searchForLoadedItems", () => {
const file = new ZoweUSSNode("file", vscode.TreeItemCollapsibleState.None, folder, null, "/folder");
blockMocks.testDatasetTree.getChildren.mockReturnValue([blockMocks.ussSessionNode]);

blockMocks.testDatasetTree.searchInLoadedItems.mockResolvedValueOnce([]);
blockMocks.testUssTree.searchInLoadedItems.mockResolvedValueOnce([file]);
blockMocks.testDatasetTree.getAllLoadedItems.mockResolvedValueOnce([]);
blockMocks.testUssTree.getAllLoadedItems.mockResolvedValueOnce([file]);
jest.spyOn(blockMocks.ussSessionNode, "getChildren").mockResolvedValueOnce([folder]);
jest.spyOn(folder, "getChildren").mockResolvedValueOnce([file]);

Expand All @@ -187,8 +187,8 @@ describe("Shared Actions Unit Tests - Function searchForLoadedItems", () => {
const globalMocks = await createGlobalMocks();
const blockMocks = createBlockMocks();

blockMocks.testDatasetTree.searchInLoadedItems.mockResolvedValueOnce([]);
blockMocks.testUssTree.searchInLoadedItems.mockResolvedValueOnce([]);
blockMocks.testDatasetTree.getAllLoadedItems.mockResolvedValueOnce([]);
blockMocks.testUssTree.getAllLoadedItems.mockResolvedValueOnce([]);
const qpItem = null;
const quickPickContent = createQuickPickContent(qpItem, qpItem, globalMocks.qpPlaceholder);
quickPickContent.placeholder = "Select a filter";
Expand Down
6 changes: 3 additions & 3 deletions __tests__/__unit__/uss/USSTree.unit.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -540,8 +540,8 @@ describe("USSTree Unit Tests - Function USSTree.filterPrompt()", () => {
});
});

describe("USSTree Unit Tests - Function USSTree.searchInLoadedItems()", () => {
it("Testing that searchInLoadedItems() returns the correct array", async () => {
describe("USSTree Unit Tests - Function USSTree.getAllLoadedItems()", () => {
it("Testing that getAllLoadedItems() returns the correct array", async () => {
const globalMocks = await createGlobalMocks();

const folder = new ZoweUSSNode("folder", vscode.TreeItemCollapsibleState.Collapsed, globalMocks.testTree.mSessionNodes[1], null, "/");
Expand All @@ -556,7 +556,7 @@ describe("USSTree Unit Tests - Function USSTree.searchInLoadedItems()", () => {
() => Promise.resolve(globalMocks.testTree.mSessionNodes[1].children)
);

const loadedItems = await globalMocks.testTree.searchInLoadedItems();
const loadedItems = await globalMocks.testTree.getAllLoadedItems();
expect(loadedItems).toStrictEqual([file, folder]);
});
});
Expand Down
1 change: 1 addition & 0 deletions i18n/sample/package.i18n.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
"deleteDataset": "Delete Data Set",
"deleteMember": "Delete Member",
"deletePDS": "Delete PDS",
"allocateLike": "Allocate Like (New File with Same Attributes)",
"editMember": "Edit",
"issueCmd": "Issue Command",
"uploadDialog": "Upload Member...",
Expand Down
10 changes: 8 additions & 2 deletions i18n/sample/src/dataset/actions.i18n.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,11 @@
{
"allocateLike.options.prompt": "Select the profile to which the original data set belongs",
"allocateLike.noSelection": "You must select a profile.",
"allocateLike.enterLikePattern": "Enter the name of the data set to copy attributes from",
"allocateLike.enterPattern": "Enter a name for the new data set",
"allocateLike.noNewName": "You must enter a new data set name.",
"createDataSet.log.error": "Error encountered when creating data set! ",
"createDataSet.error": "Error encountered when creating data set! ",
"enterPattern.pattern": "You must enter a pattern.",
"createMember.inputBox": "Name of Member",
"createMember.log.debug.createNewDataSet": "creating new data set member of name ",
Expand All @@ -8,16 +15,15 @@
"openPS.error.invalidNode": "openPS() called from invalid node. ",
"openPS.log.debug.openDataSet": "opening physical sequential data set from label ",
"openPS.log.error.openDataSet": "Error encountered when opening data set! ",
"createFile.quickPickOption.dataSetType": "Type of Data Set to be Created",
"createFile.dataSetBinary": "Data Set Binary",
"createFile.dataSetC": "Data Set C",
"createFile.dataSetClassic": "Data Set Classic",
"createFile.dataSetPartitioned": "Data Set Partitioned",
"createFile.dataSetSequential": "Data Set Sequential",
"createFile.quickPickOption.dataSetType": "Type of Data Set to be Created",
"createFile.log.debug.noValidTypeSelected": "No valid data type selected",
"createFile.log.debug.creatingNewDataSet": "Creating new data set",
"dataset.name": "Name of Data Set",
"createDataSet.error": "Error encountered when creating data set! ",
"showDSAttributes.debug": "showing attributes of data set ",
"showDSAttributes.lengthError": "No matching data set names found for query: ",
"showDSAttributes.log.error": "Error encountered when listing attributes! ",
Expand Down
2 changes: 2 additions & 0 deletions i18n/sample/src/uss/USSTree.i18n.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
{
"Favorites": "Favorites",
"renameUSSNode.enterName": "Enter a new name for the {0}",
"renameUSSNode.duplicateName": "A {0} already exists with this name. Please choose a different one.",
"renameUSSNode.error": "Unable to rename node: ",
"enterPattern.log.debug.prompt": "Prompting the user to choose a member from the filtered list",
"filterPrompt.log.debug.promptUSSPath": "Prompting the user for a USS path",
Expand Down
20 changes: 10 additions & 10 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 3c3c671

Please sign in to comment.