Skip to content

Commit

Permalink
Merge pull request #2688 from zowe/merge-2.14.0
Browse files Browse the repository at this point in the history
maintenance - Merge 2.14.0
  • Loading branch information
JillieBeanSim authored Feb 7, 2024
2 parents 727c593 + a4ea5c1 commit 0c09c9b
Show file tree
Hide file tree
Showing 110 changed files with 6,456 additions and 4,597 deletions.
33 changes: 33 additions & 0 deletions .github/workflows/update-project.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
name: Update GitHub Project

on:
issues:
types: [labeled]
pull_request_target:
types: [opened, reopened, converted_to_draft, ready_for_review]

env:
PROJECT_NUMBER: 15
ISSUE_STATUSES: '{"priority-high": "High Priority", "priority-medium": "Medium Priority", "priority-low": "Low Priority", "Epic": "Epics"}'
PR_STATUS_DRAFT: 'In Progress'
PR_STATUS_READY: 'Review/QA'

jobs:
update-project:
name: Move project item
runs-on: ubuntu-latest
steps:
- uses: zowe-actions/shared-actions/project-move-item@main
if: ${{ github.event.issue && fromJSON(env.ISSUE_STATUSES)[github.event.label.name] }}
with:
item-status: ${{ fromJSON(env.ISSUE_STATUSES)[github.event.label.name] }}
project-number: ${{ env.PROJECT_NUMBER }}
project-token: ${{ secrets.ZOWE_ROBOT_TOKEN }}

- uses: zowe-actions/shared-actions/project-move-item@main
if: ${{ github.event.pull_request }}
with:
assign-author: true
item-status: ${{ github.event.action == 'ready_for_review' && env.PR_STATUS_READY || env.PR_STATUS_DRAFT }}
project-number: ${{ env.PROJECT_NUMBER }}
project-token: ${{ secrets.ZOWE_ROBOT_TOKEN }}
2 changes: 1 addition & 1 deletion lerna.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"version": "2.13.2-SNAPSHOT",
"version": "2.14.1-SNAPSHOT",
"command": {
"version": {
"forcePublish": true,
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
"vscode": "^1.53.2"
},
"dependencies": {
"@zowe/cli": "7.21.1",
"@zowe/cli": "7.22.0",
"vscode-nls": "4.1.2"
},
"devDependencies": {
Expand Down
2 changes: 2 additions & 0 deletions packages/eslint-plugin-zowe-explorer/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ All notable changes to the "eslint-plugin-zowe-explorer" package will be documen

### Bug fixes

## `2.14.0`

## `2.13.1`

## `2.13.0`
Expand Down
2 changes: 1 addition & 1 deletion packages/eslint-plugin-zowe-explorer/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "eslint-plugin-zowe-explorer",
"version": "2.13.2-SNAPSHOT",
"version": "2.14.1-SNAPSHOT",
"description": "Custom ESLint Rules for ZOWE Explorer",
"keywords": [
"eslint",
Expand Down
19 changes: 19 additions & 0 deletions packages/zowe-explorer-api/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,25 @@ All notable changes to the "zowe-explorer-api" extension will be documented in t

### Bug fixes

## `2.14.0`

### New features and enhancements

- Added optional `openDs` function to `IZoweDatasetTreeNode` to open a data set or member in the editor.
- Added optional `setEncoding` function to `IZoweDatasetTreeNode` and `IZoweUSSTreeNode` to set the encoding of a node to binary, text, or a custom codepage.
- Added optional properties `binary`, `encoding`, and `encodingMap` to tree node interfaces for storing the codepage of a data set or USS file.
- Deprecated `IZoweUSSTreeNode.binaryFiles` and `IZoweUSSTreeNode.setBinary` in favor of `IZoweUSSTreeNode.encodingMap` and `IZoweUSSTreeNode.setEncoding`.
- Deprecated `ZoweTreeNode.binary`, `ZoweTreeNode.binaryFiles`, and `ZoweTreeNode.shortLabel`. These properties are not applicable for all tree nodes and should be defined in subclasses of `ZoweTreeNode` if necessary.
- Added new functions `loginWithBaseProfile` and `logoutWithBaseProfile` to provide extenders with the ability to automatically login to their respective services. [#2493](https://github.com/zowe/vscode-extension-for-zowe/pull/2493)
- Added APIML dynamic token support. [#2665](https://github.com/zowe/vscode-extension-for-zowe/issues/2665)
- Added new optional method `getCommonApi` to `ZoweExplorerApi.IApiRegisterClient` for enhanced typings in other Zowe Explorer APIs. [#2493](https://github.com/zowe/vscode-extension-for-zowe/pull/2493)

### Bug fixes

- Added a return type of void for `IZoweUSSTreeNode.openUSS`.
- Fixed use of `this` in static methods in `ZoweVsCodeExtension`. [#2606](https://github.com/zowe/vscode-extension-for-zowe/pull/2606)
- Fixed `ZoweVsCodeExtension.promptUserPass` to not use hardcoded values for user and password. [#2666](https://github.com/zowe/vscode-extension-for-zowe/issues/2666)

## `2.13.1`

### Bug fixes
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,9 @@ function createProfInfoMock(profiles: Partial<zowe.imperative.IProfileLoaded>[])
knownArgs: Object.entries(profile.profile as object).map(([k, v]) => ({ argName: k, argValue: v as unknown })),
};
},
updateProperty: jest.fn(),
updateKnownProperty: jest.fn(),
isSecured: jest.fn(),
} as any;
}

Expand Down Expand Up @@ -339,6 +342,27 @@ describe("ProfilesCache", () => {
expect(profileNames).toEqual(["lpar1", "lpar2"]);
});

describe("updateBaseProfileFile Login/Logout", () => {
const updProfile = { tokenType: "apimlAuthenticationToken", tokenValue: "tokenValue" };

it("should update the base profile on login", async () => {
const profCache = new ProfilesCache(fakeLogger as unknown as zowe.imperative.Logger);
const mockProfInfo = createProfInfoMock([lpar1Profile, lpar2Profile]);
jest.spyOn(profCache, "getProfileInfo").mockResolvedValue(mockProfInfo);
await profCache.updateBaseProfileFileLogin(lpar1Profile as any, updProfile);

expect(mockProfInfo.updateProperty).toBeCalledTimes(2);
});
it("should update the base profile on login", async () => {
const profCache = new ProfilesCache(fakeLogger as unknown as zowe.imperative.Logger);
const mockProfInfo = createProfInfoMock([lpar1Profile, lpar2Profile]);
jest.spyOn(profCache, "getProfileInfo").mockResolvedValue(mockProfInfo);
await profCache.updateBaseProfileFileLogout(lpar1Profile as any);

expect(mockProfInfo.updateKnownProperty).toBeCalledTimes(2);
});
});

describe("fetchAllProfilesByType", () => {
it("should return array of profile objects for given type", async () => {
const profCache = new ProfilesCache(fakeLogger as unknown as zowe.imperative.Logger);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,18 +12,19 @@
import * as vscode from "vscode";
import { Gui } from "../../../src/globals/Gui";
import { MessageSeverity, IZoweLogger } from "../../../src/logger/IZoweLogger";
import { IProfileLoaded } from "@zowe/imperative";
import { IProfileLoaded, Session } from "@zowe/imperative";
import { IPromptCredentialsOptions, ZoweVsCodeExtension } from "../../../src/vscode";
import { ProfilesCache, ZoweExplorerApi } from "../../../src";
import { imperative } from "@zowe/cli";
import { Login, Logout, imperative } from "@zowe/cli";

describe("ZoweVsCodeExtension", () => {
const fakeVsce = {
exports: "zowe",
packageJSON: { version: "1.0.1" },
} as vscode.Extension<unknown>;

afterEach(() => {
beforeEach(() => {
jest.restoreAllMocks();
jest.clearAllMocks();
});

Expand Down Expand Up @@ -176,6 +177,201 @@ describe("ZoweVsCodeExtension", () => {
});
});

describe("login and logout with base profiles", () => {
const testProfile = {
host: "dummy",
port: 1234,
};
const baseProfile = { name: "base", type: "base", profile: testProfile };
const serviceProfile: any = { name: "service", type: "service", profile: testProfile };
const allProfiles = [serviceProfile, baseProfile];
const testNode: any = {
setProfileToChoice: jest.fn(),
getProfile: jest.fn().mockReturnValue(serviceProfile),
};
const expectedSession = new Session({
hostname: "dummy",
password: "Password",
port: 1234,
tokenType: "apimlAuthenticationToken",
type: "token",
user: "Username",
});
const updProfile = { tokenType: "apimlAuthenticationToken", tokenValue: "tokenValue" };
const testRegister: any = {
getCommonApi: () => ({
login: jest.fn().mockReturnValue("tokenValue"),
logout: jest.fn(),
getTokenTypeName: () => "apimlAuthenticationToken",
}),
};
const testCache: any = {
allProfiles,
allExternalTypes: [],
fetchBaseProfile: jest.fn(),
loadNamedProfile: jest.fn().mockReturnValue({ profile: testProfile }),
updateBaseProfileFileLogin: jest.fn(),
updateBaseProfileFileLogout: jest.fn(),
getLoadedProfConfig: jest.fn().mockReturnValue({ profile: {} }),
getProfileInfo: jest.fn().mockReturnValue({
isSecured: jest.fn().mockReturnValue(false),
getAllProfiles: jest.fn().mockReturnValue(allProfiles),
mergeArgsForProfile: jest.fn().mockReturnValue({ knownArgs: [] }),
}),
refresh: jest.fn(),
};

beforeEach(() => {
jest.spyOn(ZoweVsCodeExtension as any, "profilesCache", "get").mockReturnValue(testCache);
jest.spyOn(vscode.extensions, "getExtension").mockReturnValueOnce(fakeVsce);
});

it("should not login if the base profile cannot be fetched", async () => {
testCache.fetchBaseProfile.mockResolvedValue(null);
await ZoweVsCodeExtension.loginWithBaseProfile("service");
expect(testCache.fetchBaseProfile).toHaveBeenCalledTimes(1);
expect(testCache.updateBaseProfileFileLogin).not.toHaveBeenCalled();
});
it("should not logout if the base profile cannot be fetched", async () => {
testCache.fetchBaseProfile.mockResolvedValue(null);
await ZoweVsCodeExtension.logoutWithBaseProfile("service");
expect(testCache.fetchBaseProfile).toHaveBeenCalledTimes(1);
expect(testCache.updateBaseProfileFileLogin).not.toHaveBeenCalled();
});
it("should login using the base profile given a simple profile name", async () => {
testCache.fetchBaseProfile.mockResolvedValue(baseProfile);
const testSpy = jest.spyOn(ZoweVsCodeExtension as any, "getServiceProfileForAuthPurposes");
jest.spyOn(ZoweVsCodeExtension as any, "promptUserPass").mockResolvedValue(["user", "pass"]);
const loginSpy = jest.spyOn(Login, "apimlLogin").mockResolvedValue("tokenValue");

await ZoweVsCodeExtension.loginWithBaseProfile("service");

const testSession = new Session(JSON.parse(JSON.stringify(expectedSession.ISession)));
delete testSession.ISession.user;
delete testSession.ISession.password;
testSession.ISession.base64EncodedAuth = "dXNlcjpwYXNz";

expect(loginSpy).toHaveBeenCalledWith(testSession);
expect(testSpy).toHaveBeenCalledWith(testCache, "service");
expect(testCache.updateBaseProfileFileLogin).toHaveBeenCalledWith(baseProfile, updProfile, false);
});
it("should logout using the base profile given a simple profile name", async () => {
testCache.fetchBaseProfile.mockResolvedValue(baseProfile);
const testSpy = jest.spyOn(ZoweVsCodeExtension as any, "getServiceProfileForAuthPurposes");
testSpy.mockResolvedValue({ profile: { ...testProfile, ...updProfile } });
const logoutSpy = jest.spyOn(Logout, "apimlLogout").mockImplementation(jest.fn());

await ZoweVsCodeExtension.logoutWithBaseProfile("service");

const testSession = new Session(JSON.parse(JSON.stringify(expectedSession.ISession)));
testSession.ISession.tokenValue = "tokenValue";
delete testSession.ISession.base64EncodedAuth;
delete testSession.ISession.user;
delete testSession.ISession.password;

expect(logoutSpy).toHaveBeenCalledWith(testSession);
expect(testSpy).toHaveBeenCalledWith(testCache, "service");
expect(testCache.updateBaseProfileFileLogout).toHaveBeenCalledWith(baseProfile);
});
it("should login using the base profile if the base profile does not have a tokenType stored", async () => {
const tempBaseProfile = JSON.parse(JSON.stringify(baseProfile));
tempBaseProfile.profile.tokenType = undefined;
testCache.fetchBaseProfile.mockResolvedValue(tempBaseProfile);
const testSpy = jest.spyOn(ZoweVsCodeExtension as any, "getServiceProfileForAuthPurposes");
const newServiceProfile = { ...serviceProfile, profile: { ...testProfile, tokenValue: "tokenValue", host: "service" } };
testSpy.mockResolvedValue(newServiceProfile);
jest.spyOn(ZoweVsCodeExtension as any, "promptUserPass").mockResolvedValue(["user", "pass"]);
const loginSpy = jest.spyOn(Login, "apimlLogin").mockResolvedValue("tokenValue");

await ZoweVsCodeExtension.loginWithBaseProfile("service");

const testSession = new Session(JSON.parse(JSON.stringify(expectedSession.ISession)));
delete testSession.ISession.user;
delete testSession.ISession.password;
testSession.ISession.hostname = "service";
testSession.ISession.base64EncodedAuth = "dXNlcjpwYXNz";

expect(loginSpy).toHaveBeenCalledWith(testSession);
expect(testSpy).toHaveBeenCalledWith(testCache, "service");
expect(testCache.updateBaseProfileFileLogin).toHaveBeenCalledWith(tempBaseProfile, updProfile, false);
});
it("should login using the service profile given a simple profile name", async () => {
const tempBaseProfile = JSON.parse(JSON.stringify(baseProfile));
tempBaseProfile.profile.tokenType = "some-dummy-token-type";
testCache.fetchBaseProfile.mockResolvedValue(tempBaseProfile);
const testSpy = jest.spyOn(ZoweVsCodeExtension as any, "getServiceProfileForAuthPurposes");
const newServiceProfile = { ...serviceProfile, profile: { ...testProfile, tokenValue: "tokenValue", host: "service" } };
testSpy.mockResolvedValue(newServiceProfile);
jest.spyOn(ZoweVsCodeExtension as any, "promptUserPass").mockResolvedValue(["user", "pass"]);
const loginSpy = jest.spyOn(Login, "apimlLogin").mockResolvedValue("tokenValue");

await ZoweVsCodeExtension.loginWithBaseProfile("service");

const testSession = new Session(JSON.parse(JSON.stringify(expectedSession.ISession)));
delete testSession.ISession.user;
delete testSession.ISession.password;
testSession.ISession.hostname = "service";
testSession.ISession.base64EncodedAuth = "dXNlcjpwYXNz";

expect(loginSpy).toHaveBeenCalledWith(testSession);
expect(testSpy).toHaveBeenCalledWith(testCache, "service");
expect(testCache.updateBaseProfileFileLogin).toHaveBeenCalledWith(newServiceProfile, updProfile, true);
});
it("should logout using the service profile given a simple profile name", async () => {
testCache.fetchBaseProfile.mockResolvedValue(baseProfile);
const testSpy = jest.spyOn(ZoweVsCodeExtension as any, "getServiceProfileForAuthPurposes");
const newServiceProfile = { ...serviceProfile, profile: { ...testProfile, ...updProfile, host: "service" } };
testSpy.mockResolvedValue(newServiceProfile);
const logoutSpy = jest.spyOn(Logout, "apimlLogout").mockImplementation(jest.fn());

await ZoweVsCodeExtension.logoutWithBaseProfile("service");

const testSession = new Session(JSON.parse(JSON.stringify(expectedSession.ISession)));
testSession.ISession.hostname = "service";
testSession.ISession.tokenValue = "tokenValue";
delete testSession.ISession.base64EncodedAuth;
delete testSession.ISession.user;
delete testSession.ISession.password;

expect(logoutSpy).toHaveBeenCalledWith(testSession);
expect(testSpy).toHaveBeenCalledWith(testCache, "service");
expect(testCache.updateBaseProfileFileLogout).toHaveBeenCalledWith(newServiceProfile);
});
it("should login using the base profile when provided with a node, register, and cache instance", async () => {
testCache.fetchBaseProfile.mockResolvedValue(baseProfile);
const testSpy = jest.spyOn(ZoweVsCodeExtension as any, "getServiceProfileForAuthPurposes");
jest.spyOn(ZoweVsCodeExtension as any, "promptUserPass").mockResolvedValue(["user", "pass"]);
const loginSpy = jest.spyOn(Login, "apimlLogin").mockResolvedValue("tokenValue");

await ZoweVsCodeExtension.loginWithBaseProfile(serviceProfile, "apimlAuthenticationToken", testNode, testRegister, testCache);

const testSession = new Session(JSON.parse(JSON.stringify(expectedSession.ISession)));
testSession.ISession.base64EncodedAuth = "dXNlcjpwYXNz";

expect(loginSpy).not.toHaveBeenCalled();
expect(testSpy).not.toHaveBeenCalled();
expect(testCache.updateBaseProfileFileLogin).toHaveBeenCalledWith(baseProfile, updProfile, false);
expect(testNode.setProfileToChoice).toHaveBeenCalled();
});
it("should logout using the base profile when provided with a node, register, and cache instance", async () => {
testCache.fetchBaseProfile.mockResolvedValue(baseProfile);
const testSpy = jest.spyOn(ZoweVsCodeExtension as any, "getServiceProfileForAuthPurposes");
const logoutSpy = jest.spyOn(Logout, "apimlLogout").mockImplementation(jest.fn());
const newServiceProfile = { ...serviceProfile, profile: { ...testProfile, ...updProfile } };

await ZoweVsCodeExtension.logoutWithBaseProfile(newServiceProfile, testRegister, testCache);

const testSession = new Session(JSON.parse(JSON.stringify(expectedSession.ISession)));
testSession.ISession.tokenValue = "tokenValue";
delete testSession.ISession.base64EncodedAuth;
delete testSession.ISession.user;
delete testSession.ISession.password;

expect(logoutSpy).not.toHaveBeenCalled();
expect(testSpy).not.toHaveBeenCalled();
expect(testCache.updateBaseProfileFileLogout).toHaveBeenCalledWith(baseProfile);
});
});
describe("updateCredentials", () => {
const promptCredsOptions: IPromptCredentialsOptions = {
sessionName: "test",
Expand Down
4 changes: 2 additions & 2 deletions packages/zowe-explorer-api/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@zowe/zowe-explorer-api",
"version": "2.13.2-SNAPSHOT",
"version": "2.14.1-SNAPSHOT",
"description": "Extensibility API for Zowe Explorer.",
"publisher": "Zowe",
"author": "Zowe",
Expand All @@ -18,7 +18,7 @@
},
"dependencies": {
"@types/vscode": "^1.53.2",
"@zowe/cli": "7.21.1",
"@zowe/cli": "7.22.0",
"@zowe/secrets-for-zowe-sdk": "7.18.6",
"handlebars": "^4.7.7",
"semver": "^7.5.3"
Expand Down
Loading

0 comments on commit 0c09c9b

Please sign in to comment.