Skip to content

Commit

Permalink
Merge pull request #436 from katelynienaber/url_error_message_wait_418
Browse files Browse the repository at this point in the history
Don't show an error message when adding a z/OSMF URL until press enter
  • Loading branch information
Colin-Stone authored Jan 6, 2020
2 parents 6c38d93 + 2218655 commit 5e95b1e
Show file tree
Hide file tree
Showing 3 changed files with 70 additions and 21 deletions.
60 changes: 47 additions & 13 deletions __tests__/__unit__/Profiles.unit.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,16 +24,39 @@ describe("Profile class unit tests", () => {

const profileOne = { name: "profile1", profile: {}, type: "zosmf" };
const profileTwo = { name: "profile2", profile: {}, type: "zosmf" };
const inputBox: vscode.InputBox = {
value: "input",
title: null,
enabled: true,
busy: false,
show: jest.fn(),
hide: jest.fn(),
step: null,
dispose: jest.fn(),
ignoreFocusOut: false,
totalSteps: null,
placeholder: undefined,
password: false,
onDidChangeValue: jest.fn(),
onDidAccept: jest.fn(),
onDidHide: jest.fn(),
buttons: [],
onDidTriggerButton: jest.fn(),
prompt: undefined,
validationMessage: undefined
};

const mockJSONParse = jest.spyOn(JSON, "parse");
const showInformationMessage = jest.fn();
const showInputBox = jest.fn();
const createInputBox = jest.fn();
const showQuickPick = jest.fn();
const showErrorMessage = jest.fn();

Object.defineProperty(vscode.window, "showInformationMessage", { value: showInformationMessage });
Object.defineProperty(vscode.window, "showErrorMessage", { value: showErrorMessage });
Object.defineProperty(vscode.window, "showInputBox", { value: showInputBox });
Object.defineProperty(vscode.window, "createInputBox", { value: createInputBox });
Object.defineProperty(vscode.window, "showQuickPick", { value: showQuickPick });

beforeEach(() => {
Expand Down Expand Up @@ -114,22 +137,24 @@ describe("Profile class unit tests", () => {

afterEach(() => {
showQuickPick.mockReset();
showInputBox.mockReset();
createInputBox.mockReset();
showInformationMessage.mockReset();
showErrorMessage.mockReset();
});

it("should indicate missing property: zosmf url", async () => {
// No valid zosmf value
showInputBox.mockResolvedValueOnce(undefined);
createInputBox.mockReturnValue(inputBox);
profiles.getUrl = () => new Promise((resolve) => { resolve(undefined); });
await profiles.createNewConnection(profileOne.name);
expect(showInformationMessage.mock.calls.length).toBe(1);
expect(showInformationMessage.mock.calls[0][0]).toBe("No valid value for z/OSMF URL. Operation Cancelled");
});

it("should indicate missing property: username", async () => {
// Enter z/OS password
showInputBox.mockResolvedValueOnce("https://fake:143");
createInputBox.mockReturnValue(inputBox);
profiles.getUrl = () => new Promise((resolve) => { resolve("https://fake:143"); });
showInputBox.mockResolvedValueOnce(undefined);
await profiles.createNewConnection(profileOne.name);
expect(showInformationMessage.mock.calls.length).toBe(1);
Expand All @@ -138,7 +163,8 @@ describe("Profile class unit tests", () => {

it("should indicate missing property: password", async () => {
// Enter z/OS password
showInputBox.mockResolvedValueOnce("https://fake:143");
createInputBox.mockReturnValue(inputBox);
profiles.getUrl = () => new Promise((resolve) => { resolve("https://fake:143"); });
showInputBox.mockResolvedValueOnce("fake");
showInputBox.mockResolvedValueOnce(undefined);
await profiles.createNewConnection(profileOne.name);
Expand All @@ -148,7 +174,8 @@ describe("Profile class unit tests", () => {

it("should indicate missing property: rejectUnauthorized", async () => {
// Operation cancelled
showInputBox.mockResolvedValueOnce("https://fake:143");
createInputBox.mockReturnValue(inputBox);
profiles.getUrl = () => new Promise((resolve) => { resolve("https://fake:143"); });
showInputBox.mockResolvedValueOnce("fake");
showInputBox.mockResolvedValueOnce("fake");
showInputBox.mockResolvedValueOnce(undefined);
Expand All @@ -158,7 +185,8 @@ describe("Profile class unit tests", () => {
});

it("should validate that profile name already exists", async () => {
showInputBox.mockResolvedValueOnce("https://fake:143");
createInputBox.mockReturnValue(inputBox);
profiles.getUrl = () => new Promise((resolve) => { resolve("https://fake:143"); });
showInputBox.mockResolvedValueOnce("fake");
showInputBox.mockResolvedValueOnce("fake");
showQuickPick.mockReset();
Expand All @@ -169,7 +197,8 @@ describe("Profile class unit tests", () => {
});

it("should create new profile", async () => {
showInputBox.mockResolvedValueOnce("https://fake:143");
createInputBox.mockReturnValue(inputBox);
profiles.getUrl = () => new Promise((resolve) => { resolve("https://fake:143"); });
showInputBox.mockResolvedValueOnce("fake");
showInputBox.mockResolvedValueOnce("fake");
showQuickPick.mockReset();
Expand All @@ -180,7 +209,8 @@ describe("Profile class unit tests", () => {
});

it("should create profile with optional credentials", async () => {
showInputBox.mockResolvedValueOnce("https://fake:143");
createInputBox.mockReturnValue(inputBox);
profiles.getUrl = () => new Promise((resolve) => { resolve("https://fake:143"); });
showInputBox.mockResolvedValueOnce("");
showInputBox.mockResolvedValueOnce("");
showQuickPick.mockReset();
Expand All @@ -191,8 +221,8 @@ describe("Profile class unit tests", () => {
});

it("should create profile https+443", async () => {

showInputBox.mockResolvedValueOnce("https://fake:443");
createInputBox.mockReturnValue(inputBox);
profiles.getUrl = () => new Promise((resolve) => { resolve("https://fake:143"); });
showInputBox.mockResolvedValueOnce("fake");
showInputBox.mockResolvedValueOnce("fake");
showQuickPick.mockReset();
Expand All @@ -203,7 +233,8 @@ describe("Profile class unit tests", () => {
});

it("should create 2 consecutive profiles", async () => {
showInputBox.mockResolvedValueOnce("https://fake1:143");
createInputBox.mockReturnValue(inputBox);
profiles.getUrl = () => new Promise((resolve) => { resolve("https://fake:143"); });
showInputBox.mockResolvedValueOnce("fake1");
showInputBox.mockResolvedValueOnce("fake1");
showQuickPick.mockReset();
Expand All @@ -214,11 +245,14 @@ describe("Profile class unit tests", () => {

showInputBox.mockReset();
showInformationMessage.mockReset();

showInputBox.mockResolvedValueOnce("fake2");
showInputBox.mockResolvedValueOnce("https://fake2:143");
profiles.getUrl = () => new Promise((resolve) => { resolve("https://fake:143"); });
showInputBox.mockResolvedValueOnce("fake2");
showInputBox.mockResolvedValueOnce("fake2");

showQuickPick.mockReset();

showQuickPick.mockResolvedValueOnce("True - Reject connections with self-signed certificates");
await profiles.createNewConnection("fake2");
expect(showInformationMessage.mock.calls.length).toBe(1);
Expand Down Expand Up @@ -272,7 +306,7 @@ describe("Profile class unit tests", () => {
expect(showErrorMessage.mock.calls[0][0]).toBe("Please enter your z/OS username. Operation Cancelled");
});

it("should prompt credentials: username invalid", async () => {
it("should prompt credentials: password invalid", async () => {
const promptProfile = {name: "profile1", profile: {user: "fake", password: "1234"}};
const session = (await ZosmfSession.createBasicZosmfSession(promptProfile.profile) as ISession);
Object.defineProperty(Profiles.getInstance, "promptCredentials", {
Expand Down
1 change: 1 addition & 0 deletions i18n/sample/src/Profiles.i18n.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
"loadNamedProfile.error.profileName": "Could not find profile named: ",
"loadNamedProfile.error.period": ".",
"loadNamedProfile.warn.noDefaultProfile": "Unable to locate a default profile. CLI may not be installed. ",
"createNewConnection.invalidzosmfURL": "Please enter a valid URL in the format https://url:port.",
"createNewConnection.option.prompt.url.placeholder": "https://url:port",
"createNewConnection.option.prompt.url": "Enter a z/OSMF URL in the format 'https://url:port'.",
"createNewConnection.invalidzosmfURL": "Please enter a valid URL in the format https://url:port.",
Expand Down
30 changes: 22 additions & 8 deletions src/Profiles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -138,21 +138,35 @@ export class Profiles { // Processing stops if there are no profiles detected
return validationResult;
}

public async getUrl(urlInputBox): Promise<string | undefined> {
return new Promise<string | undefined> ((resolve) => {
urlInputBox.onDidHide(() => { resolve(urlInputBox.value); });
urlInputBox.onDidAccept(() => {
if (this.validateAndParseUrl(urlInputBox.value).valid) {
resolve(urlInputBox.value);
} else {
urlInputBox.validationMessage = localize("createNewConnection.invalidzosmfURL", "Please enter a valid URL in the format https://url:port.");
}
});
});
}

public async createNewConnection(profileName: string): Promise<string | undefined> {
let userName: string;
let passWord: string;
let zosmfURL: string;
let rejectUnauthorize: boolean;
let options: vscode.InputBoxOptions;

zosmfURL = await vscode.window.showInputBox({
ignoreFocusOut: true,
placeHolder: localize("createNewConnection.option.prompt.url.placeholder", "https://url:port"),
prompt: localize("createNewConnection.option.prompt.url",
"Enter a z/OSMF URL in the format 'https://url:port'."),
validateInput: (text: string) => (this.validateAndParseUrl(text).valid ? "" : localize("createNewConnection.invalidzosmfURL", "Please enter a valid URL in the format https://url:port.")),
value: zosmfURL
});
const urlInputBox = vscode.window.createInputBox();
urlInputBox.ignoreFocusOut = true;
urlInputBox.placeholder = localize("createNewConnection.option.prompt.url.placeholder", "https://url:port");
urlInputBox.prompt = localize("createNewConnection.option.prompt.url",
"Enter a z/OSMF URL in the format 'https://url:port'.");

urlInputBox.show();
zosmfURL = await this.getUrl(urlInputBox);
urlInputBox.dispose();

if (!zosmfURL) {
vscode.window.showInformationMessage(localize("createNewConnection.zosmfURL",
Expand Down

0 comments on commit 5e95b1e

Please sign in to comment.