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: Only show "No configs detected" prompt if ZE opened #3281

Merged
merged 11 commits into from
Oct 31, 2024
1 change: 1 addition & 0 deletions packages/zowe-explorer/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ All notable changes to the "vscode-extension-for-zowe" extension will be documen
- Fixed an issue during initialization where a broken team configuration file caused the "Show Config" action in the error dialog to stop working. [#3273](https://github.com/zowe/zowe-explorer-vscode/issues/3273)
- Fixed issue where switching the authentication methods would cause `Cannot read properties of undefined` error. [#3142](https://github.com/zowe/zowe-explorer-vscode/issues/3142)
- Fixed an issue where calling `vscode.workspace.fs.readFile` with a PDS member URI would throw an error when the PDS already existed as a filesystem entry. [#3267](https://github.com/zowe/zowe-explorer-vscode/issues/3267)
- Fixed issue where Zowe Explorer would present the "No configs detected" notification when initialized in a workspace without a Zowe team configuration. [#3280](https://github.com/zowe/zowe-explorer-vscode/issues/3280)

## `3.0.2`

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import { SharedContext } from "../../../../src/trees/shared/SharedContext";
import { DatasetActions } from "../../../../src/trees/dataset/DatasetActions";
import { DatasetInit } from "../../../../src/trees/dataset/DatasetInit";
import { SharedInit } from "../../../../src/trees/shared/SharedInit";
import { ProfilesUtils } from "../../../../src/utils/ProfilesUtils";

describe("Test src/dataset/extension", () => {
describe("initDatasetProvider", () => {
Expand All @@ -39,7 +40,9 @@ describe("Test src/dataset/extension", () => {
filterPrompt: jest.fn(),
rename: jest.fn(),
onDidChangeConfiguration: jest.fn(),
getTreeView: jest.fn(),
getTreeView: jest.fn().mockReturnValue({
onDidChangeVisibility: jest.fn(),
}),
sortPdsMembersDialog: jest.fn(),
filterPdsMembersDialog: jest.fn(),
openWithEncoding: jest.fn(),
Expand Down Expand Up @@ -144,15 +147,23 @@ describe("Test src/dataset/extension", () => {
name: "zowe.ds.pasteDataSets:1",
parm: [false],
mock: [
{ spy: jest.spyOn(dsProvider, "getTreeView"), arg: [], ret: { reveal: jest.fn(), selection: [test.value] } },
{
spy: jest.spyOn(dsProvider, "getTreeView"),
arg: [],
ret: { reveal: jest.fn(), onDidChangeVisibility: jest.fn(), selection: [test.value] },
},
{ spy: jest.spyOn(DatasetActions, "pasteDataSetMembers"), arg: [dsProvider, test.value] },
{ spy: jest.spyOn(DatasetActions, "refreshDataset"), arg: ["test", dsProvider] },
],
},
{
name: "zowe.ds.pasteDataSets:2",
mock: [
{ spy: jest.spyOn(dsProvider, "getTreeView"), arg: [], ret: { reveal: jest.fn(), selection: [test.value] } },
{
spy: jest.spyOn(dsProvider, "getTreeView"),
arg: [],
ret: { reveal: jest.fn(), onDidChangeVisibility: jest.fn(), selection: [test.value] },
},
{ spy: jest.spyOn(DatasetActions, "pasteDataSetMembers"), arg: [dsProvider, test.value] },
{ spy: jest.spyOn(DatasetActions, "refreshDataset"), arg: ["test", dsProvider] },
],
Expand Down Expand Up @@ -204,12 +215,11 @@ describe("Test src/dataset/extension", () => {
onDidChangeConfiguration = (fun: () => void) => {
return { onDidChangeConfiguration: fun };
};
spyCreateDatasetTree = jest.spyOn(DatasetInit, "createDatasetTree");
spyCreateDatasetTree = jest.spyOn(DatasetInit, "createDatasetTree").mockResolvedValue(dsProvider as any);
jest.spyOn(SharedInit, "initSubscribers").mockImplementation(jest.fn());
Object.defineProperty(vscode.commands, "registerCommand", { value: registerCommand });
Object.defineProperty(vscode.workspace, "onDidChangeConfiguration", { value: onDidChangeConfiguration });

spyCreateDatasetTree.mockResolvedValue(dsProvider as any);
await DatasetInit.initDatasetProvider(test.context);
});
beforeEach(() => {
Expand All @@ -227,4 +237,12 @@ describe("Test src/dataset/extension", () => {
expect(myProvider).toBe(null);
});
});

describe("datasetTreeVisibilityChanged", () => {
it("calls ProfilesUtils.promptUserWithNoConfigs if visible", async () => {
const promptUserWithNoConfigsMock = jest.spyOn(ProfilesUtils, "promptUserWithNoConfigs").mockImplementation();
await DatasetInit.datasetTreeVisibilityChanged({ visible: true });
expect(promptUserWithNoConfigsMock).toHaveBeenCalled();
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -1270,6 +1270,13 @@ describe("ProfilesUtils unit tests", () => {
});

describe("promptUserWithNoConfigs", () => {
it("returns early if user was already prompted in this session", async () => {
const noConfigDialogShownMock = new MockedProperty(ProfilesUtils, "noConfigDialogShown", { value: true });
const getProfInfoSpy = jest.spyOn(ProfilesUtils, "getProfileInfo");
await ProfilesUtils.promptUserWithNoConfigs();
expect(getProfInfoSpy).not.toHaveBeenCalled();
noConfigDialogShownMock[Symbol.dispose]();
});
it("returns early if profileInfo is nullish", async () => {
const profInfoMock = jest.spyOn(ProfilesUtils, "getProfileInfo").mockResolvedValue(undefined as any);
const showMessageSpy = jest.spyOn(Gui, "showMessage");
Expand All @@ -1278,6 +1285,7 @@ describe("ProfilesUtils unit tests", () => {
profInfoMock.mockRestore();
});
it("prompts the user if they don't have any Zowe client configs", async () => {
const noConfigDialogShownMock = new MockedProperty(ProfilesUtils, "noConfigDialogShown", { value: false });
const profInfoMock = jest.spyOn(ProfilesUtils, "getProfileInfo").mockResolvedValue({
getTeamConfig: () => ({ exists: false }),
} as any);
Expand All @@ -1294,11 +1302,16 @@ describe("ProfilesUtils unit tests", () => {
expect(profInfoMock).toHaveBeenCalled();
profInfoMock.mockRestore();
onlyV1ProfsExistMock[Symbol.dispose]();
noConfigDialogShownMock[Symbol.dispose]();
});
it("executes zowe.ds.addSession if the user selects 'Create New' in the prompt", async () => {
const profInfoMock = jest.spyOn(ProfilesUtils, "getProfileInfo").mockResolvedValue({
getTeamConfig: () => ({ exists: false }),
} as any);
const noConfigDialogShownMock = new MockedProperty(ProfilesUtils, "noConfigDialogShown", {
configurable: true,
value: false,
});
const onlyV1ProfsExistMock = new MockedProperty(imperative.ProfileInfo, "onlyV1ProfilesExist", {
configurable: true,
get: () => false,
Expand All @@ -1315,11 +1328,16 @@ describe("ProfilesUtils unit tests", () => {
executeCommandMock.mockRestore();
profInfoMock.mockRestore();
onlyV1ProfsExistMock[Symbol.dispose]();
noConfigDialogShownMock[Symbol.dispose]();
});
it("does not prompt the user if they have a Zowe team config", async () => {
const profInfoMock = jest.spyOn(ProfilesUtils, "getProfileInfo").mockResolvedValue({
getTeamConfig: () => ({ exists: true }),
} as any);
const noConfigDialogShownMock = new MockedProperty(ProfilesUtils, "noConfigDialogShown", {
configurable: true,
value: false,
});
const onlyV1ProfsExistMock = new MockedProperty(imperative.ProfileInfo, "onlyV1ProfilesExist", {
configurable: true,
get: () => false,
Expand All @@ -1333,11 +1351,16 @@ describe("ProfilesUtils unit tests", () => {
expect(profInfoMock).toHaveBeenCalled();
profInfoMock.mockRestore();
onlyV1ProfsExistMock[Symbol.dispose]();
noConfigDialogShownMock[Symbol.dispose]();
});
it("does not prompt the user if they have v1 profiles", async () => {
const profInfoMock = jest.spyOn(ProfilesUtils, "getProfileInfo").mockResolvedValue({
getTeamConfig: () => ({ exists: false }),
} as any);
const noConfigDialogShownMock = new MockedProperty(ProfilesUtils, "noConfigDialogShown", {
configurable: true,
value: false,
});
const onlyV1ProfsExistMock = new MockedProperty(imperative.ProfileInfo, "onlyV1ProfilesExist", {
configurable: true,
get: () => true,
Expand All @@ -1351,6 +1374,7 @@ describe("ProfilesUtils unit tests", () => {
expect(profInfoMock).toHaveBeenCalled();
profInfoMock.mockRestore();
onlyV1ProfsExistMock[Symbol.dispose]();
noConfigDialogShownMock[Symbol.dispose]();
});
});

Expand Down
1 change: 0 additions & 1 deletion packages/zowe-explorer/src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,6 @@ export async function activate(context: vscode.ExtensionContext): Promise<ZoweEx
SharedInit.watchConfigProfile(context);
await SharedInit.watchForZoweButtonClick();

await ProfilesUtils.promptUserWithNoConfigs();
return ZoweExplorerApiRegister.getInstance();
}
/**
Expand Down
9 changes: 9 additions & 0 deletions packages/zowe-explorer/src/trees/dataset/DatasetInit.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import { SharedActions } from "../shared/SharedActions";
import { SharedContext } from "../shared/SharedContext";
import { SharedInit } from "../shared/SharedInit";
import { SharedUtils } from "../shared/SharedUtils";
import { ProfilesUtils } from "../../utils/ProfilesUtils";

export class DatasetInit {
public static async createDatasetTree(log: imperative.Logger): Promise<DatasetTree> {
Expand All @@ -30,6 +31,12 @@ export class DatasetInit {
return tree;
}

public static async datasetTreeVisibilityChanged(this: void, e: vscode.TreeViewVisibilityChangeEvent): Promise<void> {
if (e.visible) {
await ProfilesUtils.promptUserWithNoConfigs();
}
}

public static async initDatasetProvider(context: vscode.ExtensionContext): Promise<DatasetTree> {
ZoweLogger.trace("DatasetInit.initDatasetProvider called.");
context.subscriptions.push(vscode.workspace.registerFileSystemProvider(ZoweScheme.DS, DatasetFSProvider.instance, { isCaseSensitive: true }));
Expand All @@ -38,6 +45,8 @@ export class DatasetInit {
return null;
}

datasetProvider.getTreeView().onDidChangeVisibility(DatasetInit.datasetTreeVisibilityChanged);

context.subscriptions.push(
vscode.commands.registerCommand("zowe.all.config.init", async () => {
await datasetProvider.createZoweSchema(datasetProvider);
Expand Down
6 changes: 6 additions & 0 deletions packages/zowe-explorer/src/utils/ProfilesUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ export enum ProfilesConvertStatus {

export class ProfilesUtils {
public static PROFILE_SECURITY: string | boolean = Constants.ZOWE_CLI_SCM;
private static noConfigDialogShown: boolean = false;
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 rename this variable so it doesn't start with the word no? Please feel free to ignore, I'm definitely being picky but this was a bit hard to read because it seemed like a double negative 😋

Suggested change
private static noConfigDialogShown: boolean = false;
private static createConfigDialogShown: boolean = false;


/**
* Check if the credential manager's vsix is installed for use
Expand Down Expand Up @@ -402,6 +403,10 @@ export class ProfilesUtils {
* This aims to help direct new Zowe Explorer users to create a new team configuration.
*/
public static async promptUserWithNoConfigs(): Promise<void> {
if (ProfilesUtils.noConfigDialogShown) {
return;
}

const profInfo = await ProfilesUtils.getProfileInfo();
if (profInfo == null) {
return;
Expand All @@ -418,6 +423,7 @@ export class ProfilesUtils {
await vscode.commands.executeCommand("zowe.ds.addSession");
}
});
ProfilesUtils.noConfigDialogShown = true;
}
}

Expand Down
Loading