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

Event Operator and Processor #2136

Merged
merged 83 commits into from
Jul 11, 2024
Merged
Show file tree
Hide file tree
Changes from 81 commits
Commits
Show all changes
83 commits
Select commit Hold shift + click to select a range
fa8642d
changes to include custom events
Apr 29, 2024
cab176d
private to public chane
Apr 29, 2024
284598e
unsure if these changes are needed
Apr 29, 2024
41d3b0c
separating initalization from instance creation
Apr 30, 2024
31a1125
possibly breaking things XD
Apr 30, 2024
9cfb6fe
tinkering
Apr 30, 2024
fa6649d
tinkering pt 2!
Apr 30, 2024
5af16ea
fixin
Apr 30, 2024
bfdb9e2
poc works with this branch now, minus unscubscribe
Apr 30, 2024
7ffb3fe
WIPgit add .
May 3, 2024
721f615
about to switch to an eventEmitterManager. what you see here is still…
May 9, 2024
32429fc
finished
May 9, 2024
af0933d
unsure about keeping the name Registered Action
May 9, 2024
5f3ba16
adding in watcher setup with fernando
May 9, 2024
e7d0fb2
fixing build errors. need to fix custom logger passing
May 9, 2024
423455b
resolving multi-level circular dependency issues. also adding new cla…
May 13, 2024
ee56384
pair programming: required fixes found when rebuilding sample app
May 13, 2024
61f5b28
Merge branch 'poc-1987-mvp' of https://github.com/zowe/zowe-cli into …
zFernand0 May 14, 2024
9305b3e
chore: Address Timothy's feedbach
zFernand0 May 14, 2024
7d30717
Merge branch 'next' of https://github.com/zowe/zowe-cli into custEven…
zFernand0 May 15, 2024
ed5d468
chore: fix build issue after renaming IDisposableAction
zFernand0 May 15, 2024
8ce3066
renaming to new conventions, building cleanup methods, building out n…
May 15, 2024
37a8171
fix build issues after changing naming conventions
May 15, 2024
e0cc07d
chore: prevent unkown application names from being from getting a pro…
May 15, 2024
4a9f946
chore: prevent unkown application names from being from getting a pro…
May 15, 2024
47bba1b
Merge branch 'custEventsPt2' of https://github.com/zowe/zowe-cli into…
May 20, 2024
bca063c
style: modifying comments and interface names for clarity and consist…
May 21, 2024
c7e3ea7
feat/refactor: deciding what is a valid appName
May 21, 2024
1eaad24
refactor: unsure if this line is necessary apps.push(Zowe)
May 21, 2024
5f6ee26
fix: custom applications not being allowed
zFernand0 Jun 6, 2024
8b86ccf
fix: changelog updates and codeql remarks on tests
zFernand0 Jun 6, 2024
da91e26
chore: address PR feedback
zFernand0 Jun 6, 2024
cff8984
chore: update from next
zFernand0 Jun 7, 2024
b8a2af6
fix: don't append the root path twice
zFernand0 Jun 7, 2024
c6264f9
fix: backwards logic for zowe v. custom events
zFernand0 Jun 7, 2024
ca664a1
fix: eventTimes never defined
zFernand0 Jun 7, 2024
6212193
tests that I didn't push from last week
ATorrise Jun 10, 2024
3ae3946
Merge branch 'custEventsPt2' of https://github.com/zowe/zowe-cli into…
ATorrise Jun 10, 2024
22313f5
fix: make eventType optional
zFernand0 Jun 10, 2024
26c8c96
completed unit tests for EventOperator
ATorrise Jun 10, 2024
0cb37b7
Merge branch 'custEventsPt2' of https://github.com/zowe/zowe-cli into…
ATorrise Jun 10, 2024
180bfc1
removing uneceesary spies from EventOperator
ATorrise Jun 10, 2024
e6760b2
wip - eventProcessorUnitTest
ATorrise Jun 10, 2024
11f3bf1
fix: other tests related to old event emitter
zFernand0 Jun 10, 2024
e1d398c
fixed test
ATorrise Jun 10, 2024
9a8feef
Merge branch 'custEventsPt2' of https://github.com/zowe/zowe-cli into…
ATorrise Jun 10, 2024
a20b707
fix: prevent .events and extenders.json from being created, thanks @a…
zFernand0 Jun 10, 2024
730e843
fix: mocked the Event Operator on unrelated tests
zFernand0 Jun 10, 2024
06a6457
fix: a few more unit tests
zFernand0 Jun 10, 2024
5fac200
just 1 failing unit test for eventProcessor
ATorrise Jun 11, 2024
ada1c9a
Merge branch 'custEventsPt2' of https://github.com/zowe/zowe-cli into…
ATorrise Jun 11, 2024
c799e78
finishing all unit tests and also editing EventProcessor.unsubscribe
ATorrise Jun 11, 2024
a826e93
integration tests
ATorrise Jun 13, 2024
4aadd3b
Make some FS changes and use more restrictive file modes.
awharn Jun 14, 2024
3d111ba
tests: fix some unit tests and add more coverage
zFernand0 Jun 14, 2024
680d922
Add mock cleanup steps to unit tests
awharn Jun 20, 2024
09c2237
tests: fix integration test
Jun 20, 2024
2b90cc2
overriding previous integration tests
ATorrise Jun 24, 2024
c06ecf2
still fixing the intergration tests
ATorrise Jun 24, 2024
6621988
Merge branch 'next' of https://github.com/zowe/zowe-cli into custEven…
zFernand0 Jun 25, 2024
224c804
Merge branch 'custEventsPt2' of https://github.com/zowe/zowe-cli into…
zFernand0 Jun 25, 2024
ebc9a4d
test: fix final few integration tests
zFernand0 Jun 25, 2024
e356b65
lint: address lint errors
zFernand0 Jun 25, 2024
151b91c
Merge branch 'custEventsPt2' of https://github.com/zowe/zowe-cli into…
ATorrise Jun 25, 2024
0dc8be6
slimmed down integration tests
ATorrise Jun 27, 2024
f52bed6
attempting to fix??
ATorrise Jun 27, 2024
d824817
more sensible but small organizational changes
ATorrise Jun 27, 2024
8723259
race condition fix
ATorrise Jun 27, 2024
93f73c1
fixing integration tests and ammending race condition fix
ATorrise Jun 27, 2024
637a2d2
SPACE :alien:
ATorrise Jun 27, 2024
f36025d
:tada:
ATorrise Jun 27, 2024
cb91019
changes for clarity
ATorrise Jun 27, 2024
06ef810
changes for clarity
ATorrise Jun 27, 2024
5301fa5
creating an explanation in the type doc for EventOperator
ATorrise Jun 27, 2024
7403112
fix: make sure the env prefix is based on the app name
zFernand0 Jul 1, 2024
bd8b922
modifying descriptions
ATorrise Jul 1, 2024
aa7d980
fixes to descriptions and type doc
ATorrise Jul 1, 2024
44788ac
mild change to documentation
ATorrise Jul 1, 2024
dd29a96
addressing pt 1 of trae's comments: tidying up
ATorrise Jul 1, 2024
a4e268a
chore: addressed PR comments and a few other things
zFernand0 Jul 2, 2024
ac67acc
lint: address all lint warnings :yum:
zFernand0 Jul 2, 2024
3552378
Merge branch 'next' of https://github.com/zowe/zowe-cli into custEven…
zFernand0 Jul 9, 2024
8cb0253
tests: fix integration tests :tada:
zFernand0 Jul 11, 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
12 changes: 11 additions & 1 deletion packages/imperative/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,16 @@

All notable changes to the Imperative package will be documented in this file.

## Recent Changes

- Enhancement: Add client-side custom-event handling capabilities. [#2136](https://github.com/zowe/zowe-cli/pull/2136)
zFernand0 marked this conversation as resolved.
Show resolved Hide resolved
- Next-Breaking: Refactored the Imperative Event Emitter class. [#2136](https://github.com/zowe/zowe-cli/pull/2136)
- Removed the `ImperativeEventEmitter` class.
- Added an `EventProcessor` class to handle event listening and emitting.
- Added an `EventOperator` class to handle creation and deletion of `EventProcessors`.
- Added an `EventUtils` class to contain all common utility methods for the Client Event Handling capabilities.
- Added `IEmitter`, `IWatcher`, and `IEmitterAndWatcher` interfaces to expose what application developers should see.

## `8.0.0-next.202406201950`

- Enhancement: Added `ProfileInfo.profileManagerWillLoad` function to verify the credential manager can load. [#2111](https://github.com/zowe/zowe-cli/issues/2111)
Expand Down Expand Up @@ -71,7 +81,7 @@ All notable changes to the Imperative package will be documented in this file.

## `8.0.0-next.202405151329`

- Enhancement: Add client-side event handling capabilities. [#1987](https://github.com/zowe/zowe-cli/pull/1987)
- Enhancement: Add client-side event handling capabilities. [#1987](https://github.com/zowe/zowe-cli/issues/1987)

## `8.0.0-next.202405061946`

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,9 @@ describe("cmd-cli invalid profile-spec", () => {

it("should fail the command if the profile property is not supplied and the handler requests a profile", () => {
const response = runCliScript(__dirname + "/__scripts__/profile-spec.sh", TEST_ENVIRONMENT.workingDir);
expect(response.status).toBe(1);
expect(response.stdout.toString()).toBe('');
expect(response.stderr.toString()).toContain('Internal Error: No profiles of type "blah" were loaded for this command.');
expect(response.status).toBe(1);
expect(response.stderr.toString()).toContain('This error can occur for one of two reasons:');
expect(response.stderr.toString()).toContain('- The "profile" property on the command definition document ' +
'does NOT specify the requested profile type');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ describe("cmd-cli nested first-group", () => {

it("should display both groups and commands in the help", () => {
const response = runCliScript(__dirname + "/__scripts__/first-group/first_group_help.sh", TEST_ENVIRONMENT.workingDir);
expect(response.status).toBe(0);
expect(response.stderr.toString()).toBe("");
expect(response.status).toBe(0);
expect(response.stdout.toString()).toMatchSnapshot();
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ describe("cmd-cli nested", () => {

it("should display both groups and commands in the help", () => {
const response = runCliScript(__dirname + "/__scripts__/nested/nested_help.sh", TEST_ENVIRONMENT.workingDir);
expect(response.status).toBe(0);
expect(response.stderr.toString()).toBe("");
expect(response.status).toBe(0);
expect(response.stdout.toString()).toMatchSnapshot();
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ import { join } from "path";
jest.mock("../src/syntax/SyntaxValidator");
jest.mock("../src/utils/SharedOptions");
jest.mock("../../utilities/src/ImperativeConfig");
jest.mock("../../events/src/ImperativeEventEmitter");

// Persist the original definitions of process.write
const ORIGINAL_STDOUT_WRITE = process.stdout.write;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,6 @@ import { IConfig } from "../src/doc/IConfig";
import { IConfigLayer } from "../src/doc/IConfigLayer";
import { IConfigProfile } from "../src/doc/IConfigProfile";

jest.mock("../../events/src/ImperativeEventEmitter");

const MY_APP = "my_app";

const mergeConfig: IConfig = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ import { Config } from "../src/Config";
import { IConfig } from "../src/doc/IConfig";
import { IConfigSecure } from "../src/doc/IConfigSecure";
import { IConfigVault } from "../src/doc/IConfigVault";
import { ImperativeEventEmitter } from "../../events";

const MY_APP = "my_app";

Expand Down Expand Up @@ -47,9 +46,6 @@ describe("Config secure tests", () => {
});

beforeEach(() => {
jest.spyOn(ImperativeEventEmitter, "initialize").mockImplementation();
Object.defineProperty(ImperativeEventEmitter, "instance", { value: { emitEvent: jest.fn() }});

mockSecureLoad = jest.fn();
mockSecureSave = jest.fn();
mockVault = {
Expand Down
2 changes: 0 additions & 2 deletions packages/imperative/src/config/__tests__/Config.unit.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,6 @@ import * as JSONC from "comment-json";
import { ConfigLayers, ConfigSecure } from "../src/api";


jest.mock("../../events/src/ImperativeEventEmitter");

const MY_APP = "my_app";

describe("Config tests", () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
*/

jest.mock("../../logger/src/LoggerUtils");
jest.mock("../../events/src/ImperativeEventEmitter");

import { AbstractAuthHandler } from "../../imperative/src/auth/handlers/AbstractAuthHandler";
import { SessConstants } from "../../rest";
Expand Down
118 changes: 117 additions & 1 deletion packages/imperative/src/config/__tests__/ConfigUtils.unit.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,20 @@
*/

import * as fs from "fs";

import * as path from "path";
import * as os from "os";
import * as jsonfile from "jsonfile";
import { ConfigUtils } from "../../config/src/ConfigUtils";
import { CredentialManagerFactory } from "../../security";
import { ImperativeConfig } from "../../utilities";
import { EnvironmentalVariableSettings } from "../../imperative/src/env/EnvironmentalVariableSettings";
import { IExtendersJsonOpts } from "../src/doc/IExtenderOpts";

describe("Config Utils", () => {
afterEach(() => {
jest.restoreAllMocks();
});

describe("coercePropValue", () => {
it("should parse value when type is boolean", () => {
expect(ConfigUtils.coercePropValue("false", "boolean")).toBe(false);
Expand Down Expand Up @@ -149,4 +157,112 @@ describe("Config Utils", () => {
expect(fsExistsSyncSpy).toHaveBeenCalledTimes(1);
});
});

describe("getZoweDir", () => {
const expectedLoadedConfig = {
name: "zowe",
defaultHome: path.join("z", "zowe"),
envVariablePrefix: "ZOWE"
};
let defaultHome: string;
let envReadSpy: any;
let homeDirSpy: any;
let loadedConfigOrig: any;

beforeAll(() => {
loadedConfigOrig = ImperativeConfig.instance.loadedConfig;
});

beforeEach(() => {
envReadSpy = jest.spyOn(EnvironmentalVariableSettings, "read").mockReturnValue({
cliHome: { value: null }
} as any);
homeDirSpy = jest.spyOn(os, "homedir").mockReturnValue(expectedLoadedConfig.defaultHome);
ImperativeConfig.instance.loadedConfig = undefined as any;
defaultHome = path.join(expectedLoadedConfig.defaultHome, ".zowe");
});

afterAll(() => {
ImperativeConfig.instance.loadedConfig = loadedConfigOrig;
envReadSpy.mockRestore();
homeDirSpy.mockRestore();
});

it("should return the ENV cliHome even if loadedConfig is set in the process", () => {
jest.spyOn(EnvironmentalVariableSettings, "read").mockReturnValue({ cliHome: { value: "test" } } as any);
expect(ImperativeConfig.instance.loadedConfig).toBeUndefined();
expect(ConfigUtils.getZoweDir()).toEqual("test");
expect(ImperativeConfig.instance.loadedConfig).toEqual({ ...expectedLoadedConfig, defaultHome });
});

it("should return the defaultHome and set loadedConfig if undefined", () => {
expect(ImperativeConfig.instance.loadedConfig).toBeUndefined();
expect(ConfigUtils.getZoweDir()).toEqual(defaultHome);
expect(ImperativeConfig.instance.loadedConfig).toEqual({ ...expectedLoadedConfig, defaultHome });
});

it("should return the defaultHome and reset loadedConfig if defaultHome changes", () => {
expect(ImperativeConfig.instance.loadedConfig).toBeUndefined();
ImperativeConfig.instance.loadedConfig = { ...expectedLoadedConfig, defaultHome: "test" };
expect(ImperativeConfig.instance.loadedConfig?.defaultHome).toEqual("test");
expect(ConfigUtils.getZoweDir()).toEqual(defaultHome);
expect(ImperativeConfig.instance.loadedConfig).toEqual({ ...expectedLoadedConfig, defaultHome });
});

it("should return the defaultHome without resetting loadedConfig", () => {
expect(ImperativeConfig.instance.loadedConfig).toBeUndefined();
ImperativeConfig.instance.loadedConfig = expectedLoadedConfig;
expect(ConfigUtils.getZoweDir()).toEqual(defaultHome);
expect(ImperativeConfig.instance.loadedConfig).toEqual({ ...expectedLoadedConfig, defaultHome });
});
});

const dummyExtJson: IExtendersJsonOpts = {
profileTypes: {
"test": {
from: ["Zowe Client App"]
}
}
};
describe("readExtendersJsonFromDisk", () => {
// case 1: the JSON file doesn't exist at time of read
it("writes an empty extenders.json file if it doesn't exist on disk", async () => {
const writeFileSyncMock = jest.spyOn(jsonfile, "writeFileSync").mockImplementation();
jest.spyOn(fs, "existsSync").mockReturnValueOnce(false);
ConfigUtils.readExtendersJson();
expect(writeFileSyncMock).toHaveBeenCalled();
});

// case 2: JSON file exists on-disk at time of read
it("reads extenders.json from disk if it exists", async () => {
const readFileSyncMock = jest.spyOn(jsonfile, "readFileSync").mockReturnValueOnce(dummyExtJson);
jest.spyOn(fs, "existsSync").mockReturnValueOnce(true);
const result = ConfigUtils.readExtendersJson();
expect(readFileSyncMock).toHaveBeenCalled();
expect(result).toEqual({
profileTypes: {
"test": {
from: ["Zowe Client App"]
}
}
});
});
});

describe("writeExtendersJson", () => {
// case 1: Write operation is successful
it("returns true if written to disk successfully", async () => {
const writeFileSyncMock = jest.spyOn(jsonfile, "writeFileSync").mockImplementation();
expect(ConfigUtils.writeExtendersJson(dummyExtJson)).toBe(true);
expect(writeFileSyncMock).toHaveBeenCalled();
});

// case 2: Write operation is unsuccessful
it("returns false if it couldn't write to disk", async () => {
const writeFileSyncMock = jest.spyOn(jsonfile, "writeFileSync").mockImplementation();
writeFileSyncMock.mockImplementation(() => { throw new Error(); });
expect(ConfigUtils.writeExtendersJson(dummyExtJson)).toBe(false);
expect(writeFileSyncMock).toHaveBeenCalled();
});
});
});
Loading