Skip to content

Commit

Permalink
fix: TypeError when listing data sets after opening one w/ encoding (#…
Browse files Browse the repository at this point in the history
…3348)

* fix: call setEncoding after context value

Signed-off-by: Trae Yelovich <[email protected]>

* tests: add test for setEncoding in ds constructor

Signed-off-by: Trae Yelovich <[email protected]>

* move setEncoding call and fix tests

Signed-off-by: Trae Yelovich <[email protected]>

* update changelog

Signed-off-by: Trae Yelovich <[email protected]>

* remove unrelated comment from test block

Signed-off-by: Trae Yelovich <[email protected]>

---------

Signed-off-by: Trae Yelovich <[email protected]>
  • Loading branch information
traeok authored Dec 6, 2024
1 parent 7f253c1 commit dda72a0
Show file tree
Hide file tree
Showing 5 changed files with 48 additions and 16 deletions.
1 change: 1 addition & 0 deletions packages/zowe-explorer/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ All notable changes to the "vscode-extension-for-zowe" extension will be documen
- Fixed an issue where a migrated data set is unusable after it is recalled through Zowe Explorer. [#3294](https://github.com/zowe/zowe-explorer-vscode/issues/3294)
- Fixed an issue where a recalled PDS is expandable after it is migrated through Zowe Explorer. [#3294](https://github.com/zowe/zowe-explorer-vscode/issues/3294)
- Fixed an issue where data set nodes did not update if migrated or recalled outside of Zowe Explorer. [#3294](https://github.com/zowe/zowe-explorer-vscode/issues/3294)
- Fixed an issue where listing data sets resulted in an error after opening a data set with an encoding. [#3347](https://github.com/zowe/zowe-explorer-vscode/issues/3347)

## `3.0.3`

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3297,30 +3297,31 @@ describe("Dataset Tree Unit Tests - Sorting and Filtering operations", () => {

describe("Dataset Tree Unit Tests - Function openWithEncoding", () => {
it("sets binary encoding if selection was made", async () => {
const setEncodingMock = jest.spyOn(DatasetFSProvider.instance, "setEncodingForFile").mockImplementation();
const node = new ZoweDatasetNode({ label: "encodingTest", collapsibleState: vscode.TreeItemCollapsibleState.None });
const setEncodingMock = jest.spyOn(node, "setEncoding").mockImplementation();
node.openDs = jest.fn();
jest.spyOn(SharedUtils, "promptForEncoding").mockResolvedValueOnce({ kind: "binary" });
await DatasetTree.prototype.openWithEncoding(node);
expect(setEncodingMock).toHaveBeenCalledWith(node.resourceUri, { kind: "binary" });
expect(setEncodingMock).toHaveBeenCalledWith({ kind: "binary" });
expect(node.openDs).toHaveBeenCalledTimes(1);
setEncodingMock.mockRestore();
});

it("sets text encoding if selection was made", async () => {
const setEncodingMock = jest.spyOn(DatasetFSProvider.instance, "setEncodingForFile").mockImplementation();
jest.spyOn(DatasetFSProvider.instance, "exists").mockReturnValueOnce(true);
const node = new ZoweDatasetNode({ label: "encodingTest", collapsibleState: vscode.TreeItemCollapsibleState.None });
const setEncodingMock = jest.spyOn(node, "setEncoding").mockImplementation();
node.openDs = jest.fn();
jest.spyOn(SharedUtils, "promptForEncoding").mockResolvedValueOnce({ kind: "text" });
await DatasetTree.prototype.openWithEncoding(node);
expect(setEncodingMock).toHaveBeenCalledWith(node.resourceUri, { kind: "text" });
expect(setEncodingMock).toHaveBeenCalledWith({ kind: "text" });
expect(node.openDs).toHaveBeenCalledTimes(1);
setEncodingMock.mockRestore();
});

it("does not set encoding if prompt was cancelled", async () => {
const setEncodingSpy = jest.spyOn(DatasetFSProvider.instance, "setEncodingForFile");
const node = new ZoweDatasetNode({ label: "encodingTest", collapsibleState: vscode.TreeItemCollapsibleState.None });
const setEncodingSpy = jest.spyOn(node, "setEncoding");
node.openDs = jest.fn();
jest.spyOn(SharedUtils, "promptForEncoding").mockResolvedValueOnce(undefined);
await DatasetTree.prototype.openWithEncoding(node);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
*/

import * as vscode from "vscode";
import { DsEntry, Gui, imperative, PdsEntry, Validation, ZoweScheme } from "@zowe/zowe-explorer-api";
import { BaseProvider, DsEntry, Gui, imperative, PdsEntry, Validation, ZoweScheme } from "@zowe/zowe-explorer-api";
import * as zosfiles from "@zowe/zos-files-for-zowe-sdk";
import {
createSessCfgFromArgs,
Expand Down Expand Up @@ -124,6 +124,26 @@ describe("ZoweDatasetNode Unit Tests", () => {
expect(testNode.getSession()).toBeDefined();
});

it("calls setEncoding when constructing a node with encoding", () => {
jest.spyOn(BaseProvider.prototype, "setEncodingForFile").mockImplementationOnce(() => {});
const makeEmptyDsWithEncodingMock = jest.spyOn(DatasetFSProvider.instance, "makeEmptyDsWithEncoding").mockImplementationOnce(() => {});
const setEncodingSpy = jest.spyOn(ZoweDatasetNode.prototype, "setEncoding");
const testNode = new ZoweDatasetNode({
label: "BRTVS99",
collapsibleState: vscode.TreeItemCollapsibleState.None,
contextOverride: Constants.DS_DS_CONTEXT,
encoding: { kind: "binary" },
profile: createIProfile(),
parentNode: createDatasetSessionNode(createISession(), createIProfile()),
});

expect(testNode.label).toBe("BRTVS99");
expect(testNode.collapsibleState).toBe(vscode.TreeItemCollapsibleState.None);
expect(setEncodingSpy).toHaveBeenCalled();
expect(makeEmptyDsWithEncodingMock).toHaveBeenCalled();
setEncodingSpy.mockRestore();
});

/*************************************************************************************************************
* Checks that returning an unsuccessful response results in an error being thrown and caught
*************************************************************************************************************/
Expand Down Expand Up @@ -635,9 +655,16 @@ describe("ZoweDatasetNode Unit Tests - Function node.openDs()", () => {
});

describe("ZoweDatasetNode Unit Tests - Function node.setEncoding()", () => {
const setEncodingForFileMock = jest.spyOn(DatasetFSProvider.instance, "setEncodingForFile").mockImplementation();
let setEncodingForFileMock: jest.SpyInstance;
let existsMock: jest.SpyInstance;

beforeAll(() => {
setEncodingForFileMock = jest.spyOn(DatasetFSProvider.instance, "setEncodingForFile").mockImplementation();
existsMock = jest.spyOn(DatasetFSProvider.instance, "exists").mockReturnValue(true);
});

afterAll(() => {
existsMock.mockRestore();
setEncodingForFileMock.mockRestore();
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -528,7 +528,9 @@ describe("Shared utils unit tests - function promptForEncoding", () => {
parentNode,
contextOverride: Constants.DS_MEMBER_CONTEXT,
});
const existsMock = jest.spyOn(DatasetFSProvider.instance, "exists").mockReturnValueOnce(true);
node.setEncoding(otherEncoding);
expect(existsMock).toHaveBeenCalled();
blockMocks.getEncodingForFile.mockReturnValueOnce(undefined);
await SharedUtils.promptForEncoding(node);
expect(blockMocks.showQuickPick).toHaveBeenCalled();
Expand Down
19 changes: 10 additions & 9 deletions packages/zowe-explorer/src/trees/dataset/ZoweDatasetNode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,9 +71,6 @@ export class ZoweDatasetNode extends ZoweTreeNode implements IZoweDatasetTreeNod

public constructor(opts: Definitions.IZoweDatasetTreeOpts) {
super(opts.label, opts.collapsibleState, opts.parentNode, opts.session, opts.profile);
if (opts.encoding != null) {
this.setEncoding(opts.encoding);
}
const isBinary = opts.encoding?.kind === "binary";
if (opts.contextOverride) {
this.contextValue = opts.contextOverride;
Expand Down Expand Up @@ -134,7 +131,7 @@ export class ZoweDatasetNode extends ZoweTreeNode implements IZoweDatasetTreeNod
}

if (opts.encoding != null) {
DatasetFSProvider.instance.makeEmptyDsWithEncoding(this.resourceUri, opts.encoding);
this.setEncoding(opts.encoding);
}
}
}
Expand Down Expand Up @@ -313,8 +310,8 @@ export class ZoweDatasetNode extends ZoweTreeNode implements IZoweDatasetTreeNod
} else if (!SharedContext.isMigrated(dsNode) && item.migr?.toUpperCase() === "YES") {
dsNode.datasetMigrated();
}
// Creates a ZoweDatasetNode for a PDS
} else if (item.migr && item.migr.toUpperCase() === "YES") {
// Creates a ZoweDatasetNode for a migrated dataset
dsNode = new ZoweDatasetNode({
label: item.dsname,
collapsibleState: vscode.TreeItemCollapsibleState.None,
Expand All @@ -323,17 +320,17 @@ export class ZoweDatasetNode extends ZoweTreeNode implements IZoweDatasetTreeNod
profile: cachedProfile,
});
elementChildren[dsNode.label.toString()] = dsNode;
// Creates a ZoweDatasetNode for a VSAM file
} else if (item.dsorg === "PO" || item.dsorg === "PO-E") {
// Creates a ZoweDatasetNode for a PDS
dsNode = new ZoweDatasetNode({
label: item.dsname,
collapsibleState: vscode.TreeItemCollapsibleState.Collapsed,
parentNode: this,
profile: cachedProfile,
});
elementChildren[dsNode.label.toString()] = dsNode;
// Creates a ZoweDatasetNode for a dataset with imperative errors
} else if (item.error instanceof imperative.ImperativeError) {
// Creates a ZoweDatasetNode for a dataset with imperative errors
dsNode = new ZoweDatasetNode({
label: item.dsname,
collapsibleState: vscode.TreeItemCollapsibleState.None,
Expand All @@ -344,8 +341,8 @@ export class ZoweDatasetNode extends ZoweTreeNode implements IZoweDatasetTreeNod
dsNode.command = { command: "zowe.placeholderCommand", title: "" };
dsNode.errorDetails = item.error; // Save imperative error to avoid extra z/OS requests
elementChildren[dsNode.label.toString()] = dsNode;
// Creates a ZoweDatasetNode for a migrated dataset
} else if (item.dsorg === "VS") {
// Creates a ZoweDatasetNode for a VSAM file
let altLabel = item.dsname;
let endPoint = altLabel.indexOf(".DATA");
if (endPoint === -1) {
Expand Down Expand Up @@ -713,7 +710,11 @@ export class ZoweDatasetNode extends ZoweTreeNode implements IZoweDatasetTreeNod
} else {
this.contextValue = isMemberNode ? Constants.DS_MEMBER_CONTEXT : Constants.DS_DS_CONTEXT;
}
DatasetFSProvider.instance.setEncodingForFile(this.resourceUri, encoding);
if (DatasetFSProvider.instance.exists(this.resourceUri)) {
DatasetFSProvider.instance.setEncodingForFile(this.resourceUri, encoding);
} else {
DatasetFSProvider.instance.makeEmptyDsWithEncoding(this.resourceUri, encoding);
}
const fullPath = isMemberNode ? `${this.getParent().label as string}(${this.label as string})` : (this.label as string);
if (encoding != null) {
this.updateEncodingInMap(fullPath, encoding);
Expand Down

0 comments on commit dda72a0

Please sign in to comment.