Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix 401 error when opening PDS members after cred change #3157

Merged
merged 34 commits into from
Oct 8, 2024
Merged
Show file tree
Hide file tree
Changes from 27 commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
d9e9703
Temporarily disable ON_VAULT_CHANGED event to prevent double refresh
t1m0thyj Sep 26, 2024
b70c0ab
Propagate profile updates to child nodes
t1m0thyj Sep 26, 2024
bbdb79f
Skip vault change events triggered by ZE
t1m0thyj Sep 27, 2024
9b468e8
Merge branch 'main' into fix/update-credentials-desync2
t1m0thyj Sep 27, 2024
abd2b18
Update changelog
t1m0thyj Sep 27, 2024
cdd7d7c
fix(tests): Add EventProcessor stub to imperative module mock
traeok Sep 27, 2024
b492163
refactor: Move logic into separate functions; tests: add patch coverage
traeok Sep 27, 2024
6c4f8af
chore: update ZE API changelog
traeok Sep 27, 2024
fd31799
ran prepublish
JillieBeanSim Sep 30, 2024
6abd920
Merge branch 'main' into fix/update-credentials-desync2
JillieBeanSim Sep 30, 2024
db860cb
fix: pass processor as function arg instead of bind
traeok Sep 30, 2024
7cb58d1
fix(tests): Pass fake event processor to hook function
traeok Sep 30, 2024
509abc5
Make error handling consistent across all trees
t1m0thyj Sep 30, 2024
52db6de
Move 401 error handling back into node methods
t1m0thyj Oct 1, 2024
d6e32dc
Update unit tests for error handling and placeholder nodes
t1m0thyj Oct 1, 2024
802c192
Merge branch 'main' into fix/update-credentials-desync2
t1m0thyj Oct 1, 2024
2a9f8a8
Fix duplicate expand for jobs, clean up logging, update changelog
t1m0thyj Oct 1, 2024
0f97a77
Fix log statements in wrong place
t1m0thyj Oct 1, 2024
2af831a
Use contextOverride when building session nodes
t1m0thyj Oct 1, 2024
08f7058
Add tests for memberPattern on ds node
t1m0thyj Oct 1, 2024
470c126
Add unit test for USS placeholder node
t1m0thyj Oct 2, 2024
8baff8e
Merge branch 'main' into fix/update-credentials-desync2
t1m0thyj Oct 2, 2024
a8ef66f
Merge branch 'main' into fix/update-credentials-desync2
JillieBeanSim Oct 3, 2024
23c7fa1
Fix extra tree refresh on credential update
t1m0thyj Oct 7, 2024
e5db7df
Merge branch 'main' into fix/update-credentials-desync2
t1m0thyj Oct 7, 2024
fc9cf66
Store saved profile contents by URI path
t1m0thyj Oct 7, 2024
d42cc92
Merge branch 'main' into fix/update-credentials-desync2
JillieBeanSim Oct 7, 2024
cec1890
Fix update creds cancelling and node not refreshing
t1m0thyj Oct 7, 2024
ede8d8d
Merge branch 'main' into fix/update-credentials-desync2
t1m0thyj Oct 7, 2024
f63cb9f
Fix failing USS actions test
t1m0thyj Oct 7, 2024
1d56cb7
Merge branch 'main' into fix/update-credentials-desync2
t1m0thyj Oct 7, 2024
e93c71d
Handle scenario of falsy node to refresh
t1m0thyj Oct 8, 2024
ad07311
Add unit test for syncSessionNode
t1m0thyj Oct 8, 2024
6809327
Don't show placeholder node when there is error
t1m0thyj Oct 8, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions packages/zowe-explorer-api/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ All notable changes to the "zowe-explorer-api" extension will be documented in t

### Bug fixes

- Updated the `ZoweTreeNode.setProfileToChoice` function so that it propagates profile changes to its child nodes. [#3150](https://github.com/zowe/zowe-explorer-vscode/issues/3150)

## `3.0.0`

### New features and enhancements
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ describe("ZoweTreeNode", () => {

it("setProfileToChoice should update profile for associated FSProvider entry", () => {
const node = makeNode("test", vscode.TreeItemCollapsibleState.None, undefined);
node.resourceUri = vscode.Uri.file(__dirname);
const fsEntry = {
metadata: {
profile: { name: "oldProfile" },
Expand All @@ -108,4 +109,23 @@ describe("ZoweTreeNode", () => {
expect(node.getProfileName()).toBe("newProfile");
expect(fsEntry.metadata.profile.name).toBe("newProfile");
});

it("setProfileToChoice should update child nodes with the new profile", () => {
const node = makeNode("test", vscode.TreeItemCollapsibleState.Expanded, undefined);
const nodeChild = makeNode("child", vscode.TreeItemCollapsibleState.None, undefined);
node.children = [nodeChild as any];
const setProfileToChoiceChildMock = jest.spyOn(nodeChild, "setProfileToChoice").mockImplementation();
const fsEntry = {
metadata: {
profile: { name: "oldProfile" },
},
};
const mockNewProfile = { name: "newProfile" } as unknown as imperative.IProfileLoaded;
const mockProvider = {
lookup: jest.fn().mockReturnValue(fsEntry),
} as unknown as BaseProvider;
node.setProfileToChoice(mockNewProfile, mockProvider);
expect(node.getProfileName()).toBe("newProfile");
expect(setProfileToChoiceChildMock).toHaveBeenCalledWith(mockNewProfile, mockProvider);
});
});
1 change: 0 additions & 1 deletion packages/zowe-explorer-api/src/fs/types/abstract.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,6 @@ export type ConflictData = {
export interface IFileSystemEntry extends vscode.FileStat {
name: string;
metadata: EntryMetadata;
type: vscode.FileType;
zFernand0 marked this conversation as resolved.
Show resolved Hide resolved
wasAccessed: boolean;
data?: Uint8Array;
}
Expand Down
10 changes: 10 additions & 0 deletions packages/zowe-explorer-api/src/tree/IZoweTreeNode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,11 @@ export interface IZoweDatasetTreeNode extends IZoweTreeNode {
*/
encoding?: string;

/**
* Use Dataset-specific tree node for children.
*/
children?: IZoweDatasetTreeNode[];
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should we deprecate getChildren() of do we still need an async approach to get them? 😋

Same for USS

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe we still need an async approach to fetch items from the mainframe when we want to update the tree 😋


/**
* Retrieves child nodes of this IZoweDatasetTreeNode
*
Expand Down Expand Up @@ -296,6 +301,11 @@ export interface IZoweUSSTreeNode extends IZoweTreeNode {
*/
onUpdateEmitter?: vscode.EventEmitter<IZoweUSSTreeNode>;

/**
* Use USS-specific tree node for children.
*/
children?: IZoweUSSTreeNode[];

/**
* Event that fires whenever an existing node is updated.
*/
Expand Down
11 changes: 8 additions & 3 deletions packages/zowe-explorer-api/src/tree/ZoweTreeNode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -107,9 +107,14 @@ export class ZoweTreeNode extends vscode.TreeItem {
// Don't reassign profile, we want to keep object reference shared across nodes
this.profile.profile = aProfile.profile;
}
const fsEntry = fsProvider?.lookup(this.resourceUri, true);
if (fsEntry != null) {
fsEntry.metadata.profile = aProfile;
if (this.resourceUri != null) {
const fsEntry = fsProvider?.lookup(this.resourceUri, true);
if (fsEntry != null) {
fsEntry.metadata.profile = aProfile;
}
}
for (const child of this.children) {
(child as unknown as ZoweTreeNode).setProfileToChoice(aProfile, fsProvider);
}
}
/**
Expand Down
1 change: 1 addition & 0 deletions packages/zowe-explorer/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ All notable changes to the "vscode-extension-for-zowe" extension will be documen
- Fixed an issue where opening sequential data sets within favorited searches resulted in an error. [#3163](https://github.com/zowe/zowe-explorer-vscode/pull/3163)
- Fixed an issue where Zowe Explorer displayed a "No Zowe client configurations" prompt when a project user configuration existed but no global configuration was present. [#3168](https://github.com/zowe/zowe-explorer-vscode/issues/3168)
- Fixed an issue where the `ProfilesUtils.getProfileInfo` function returned a new `ProfileInfo` instance that ignored the `ZOWE_CLI_HOME` environment variable and workspace paths. [#3168](https://github.com/zowe/zowe-explorer-vscode/issues/3168)
- Fixed an issue where a 401 error could occur when opening PDS members after updating credentials within the same user session. [#3150](https://github.com/zowe/zowe-explorer-vscode/issues/3150)

## `3.0.0`

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@ import * as os from "os";
import * as path from "path";
const log4js = require("log4js");

export class EventProcessor {
public emitZoweEvent(eventName: string): void {}
}

export enum ProfLocType {
OLD_PROFILE = 0, // an old-school profile
TEAM_CONFIG = 1, // a team configuration
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -160,8 +160,8 @@ export function createJobInfoNode(session: any, profile: imperative.IProfileLoad
collapsibleState: vscode.TreeItemCollapsibleState.None,
parentNode: session.getSessionNode(),
profile,
contextOverride: Constants.INFORMATION_CONTEXT,
});
jobNode.contextValue = Constants.INFORMATION_CONTEXT;
return jobNode;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -276,7 +276,7 @@ describe("Tree Provider unit tests, function getTreeItem", () => {
});
});

describe("Tree Provider unit tests, function getTreeItem", () => {
describe("Tree Provider unit tests, function flipState", () => {
it("Testing that expand tree is executed successfully", async () => {
const globalMocks = await createGlobalMocks();
const spy = jest.spyOn(ZoweLogger, "trace");
Expand All @@ -287,14 +287,17 @@ describe("Tree Provider unit tests, function getTreeItem", () => {
session: globalMocks.testSession,
});
folder.contextValue = Constants.USS_DIR_CONTEXT;
folder.dirty = false;

// Testing flipState to open
await globalMocks.testUSSTree.flipState(folder, true);
expect(JSON.stringify(folder.iconPath)).toContain("folder-open.svg");
expect(folder.dirty).toBe(false);

// Testing flipState to closed
await globalMocks.testUSSTree.flipState(folder, false);
expect(JSON.stringify(folder.iconPath)).toContain("folder-closed.svg");
expect(folder.dirty).toBe(true);
expect(spy).toHaveBeenCalled();
spy.mockClear();
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -871,57 +871,6 @@ describe("Dataset Actions Unit Tests - Function deleteDataset", () => {
});
});

describe("Dataset Actions Unit Tests - Function enterPattern", () => {
afterAll(() => jest.restoreAllMocks());

it("Checking common dataset filter action", async () => {
createGlobalMocks();
const blockMocks = createBlockMocksShared();
const node = new ZoweDatasetNode({
label: "node",
collapsibleState: vscode.TreeItemCollapsibleState.None,
parentNode: blockMocks.datasetSessionNode,
});
node.pattern = "TEST";
node.contextValue = Constants.DS_SESSION_CONTEXT;

const mySpy = mocked(vscode.window.showInputBox).mockResolvedValue("test");
await DatasetActions.enterPattern(node, blockMocks.testDatasetTree);

expect(mySpy).toHaveBeenCalledWith(
expect.objectContaining({
prompt: "Search Data Sets: use a comma to separate multiple patterns",
value: node.pattern,
})
);
expect(mocked(Gui.showMessage)).not.toHaveBeenCalled();
});
it("Checking common dataset filter failed attempt", async () => {
createGlobalMocks();
const blockMocks = createBlockMocksShared();
const node = new ZoweDatasetNode({
label: "node",
collapsibleState: vscode.TreeItemCollapsibleState.None,
parentNode: blockMocks.datasetSessionNode,
});
node.pattern = "TEST";
node.contextValue = Constants.DS_SESSION_CONTEXT;

mocked(vscode.window.showInputBox).mockResolvedValueOnce("");
await DatasetActions.enterPattern(node, blockMocks.testDatasetTree);

expect(mocked(Gui.showMessage)).toHaveBeenCalledWith("You must enter a pattern.");
});
it("Checking favorite dataset filter action", async () => {
createGlobalMocks();
const blockMocks = createBlockMocksShared();
const favoriteSample = new ZoweDatasetNode({ label: "[sestest]: HLQ.TEST", collapsibleState: vscode.TreeItemCollapsibleState.None });

await DatasetActions.enterPattern(favoriteSample, blockMocks.testDatasetTree);
expect(blockMocks.testDatasetTree.addSession).toHaveBeenCalledWith({ sessionName: "sestest" });
});
});

describe("Dataset Actions Unit Tests - Function showAttributes", () => {
function createBlockMocks() {
const session = createISession();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -549,30 +549,6 @@ describe("Dataset Tree Unit Tests - Function getChildren", () => {

expect(loadProfilesForFavoritesSpy).toHaveBeenCalledWith(log, favProfileNode);
});

it("returns 'No data sets found' if there are no children", async () => {
createGlobalMocks();
const blockMocks = createBlockMocks();

mocked(Profiles.getInstance).mockReturnValue(blockMocks.profile);
mocked(vscode.window.createTreeView).mockReturnValueOnce(blockMocks.treeView);
const testTree = new DatasetTree();
testTree.mSessionNodes.push(blockMocks.datasetSessionNode);
const parent = new ZoweDatasetNode({
label: "BRTVS99.PUBLIC",
collapsibleState: vscode.TreeItemCollapsibleState.Collapsed,
parentNode: testTree.mSessionNodes[1],
});
parent.dirty = true;
jest.spyOn(parent, "getChildren").mockResolvedValueOnce([]);

const children = await testTree.getChildren(parent);

// This function should never return undefined.
expect(children).toBeDefined();
expect(children).toHaveLength(1);
expect(children[0].label).toBe("No data sets found");
});
});
describe("Dataset Tree Unit Tests - Function loadProfilesForFavorites", () => {
function createBlockMocks() {
Expand Down Expand Up @@ -3338,7 +3314,6 @@ describe("Dataset Tree Unit Tests - Function applyPatternsToChildren", () => {
const withProfileMock = jest.spyOn(SharedContext, "withProfile").mockImplementation((child) => String(child.contextValue));
testTree.applyPatternsToChildren(fakeChildren as any[], [{ dsn: "HLQ.PROD.PDS", member: "A*" }], fakeSessionNode as any);
expect(SharedContext.isFilterFolder(fakeChildren[0])).toBe(true);
expect(fakeSessionNode.dirty).toBe(true);
withProfileMock.mockRestore();
});
it("applies a closed filter folder icon to the PDS if collapsed", () => {
Expand Down
Loading