Skip to content

Commit

Permalink
fix(tests): Resolve failing unit tests
Browse files Browse the repository at this point in the history
Signed-off-by: Trae Yelovich <[email protected]>
  • Loading branch information
traeok committed Jul 25, 2024
1 parent e008bb0 commit 38b35f4
Show file tree
Hide file tree
Showing 5 changed files with 195 additions and 10 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,6 @@ export function createJobNode(session: any, profile: imperative.IProfileLoaded)
label: "sampleJob",
collapsibleState: vscode.TreeItemCollapsibleState.Collapsed,
parentNode: session.getSessionNode(),
session,
profile,
job: createIJobObject(),
});
Expand Down
169 changes: 169 additions & 0 deletions packages/zowe-explorer/__tests__/__mocks__/vscode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -389,7 +389,176 @@ export interface FileDecorationProvider {
provideFileDecoration(uri: Uri, token: CancellationToken): ProviderResult<FileDecoration>;
}

/**
* Additional information the webview view being resolved.
*
* @param T Type of the webview's state.
*/
interface WebviewViewResolveContext<T = unknown> {
/**
* Persisted state from the webview content.
*
* To save resources, the editor normally deallocates webview documents (the iframe content) that are not visible.
* For example, when the user collapse a view or switches to another top level activity in the sidebar, the
* `WebviewView` itself is kept alive but the webview's underlying document is deallocated. It is recreated when
* the view becomes visible again.
*
* You can prevent this behavior by setting `retainContextWhenHidden` in the `WebviewOptions`. However this
* increases resource usage and should be avoided wherever possible. Instead, you can use persisted state to
* save off a webview's state so that it can be quickly recreated as needed.
*
* To save off a persisted state, inside the webview call `acquireVsCodeApi().setState()` with
* any json serializable object. To restore the state again, call `getState()`. For example:
*
* ```js
* // Within the webview
* const vscode = acquireVsCodeApi();
*
* // Get existing state
* const oldState = vscode.getState() || { value: 0 };
*
* // Update state
* setState({ value: oldState.value + 1 })
* ```
*
* The editor ensures that the persisted state is saved correctly when a webview is hidden and across
* editor restarts.
*/
readonly state: T | undefined;
}

/**
* A webview based view.
*/
export interface WebviewView {
/**
* Identifies the type of the webview view, such as `'hexEditor.dataView'`.
*/
readonly viewType: string;

/**
* The underlying webview for the view.
*/
readonly webview: any;

/**
* View title displayed in the UI.
*
* The view title is initially taken from the extension `package.json` contribution.
*/
title?: string;

/**
* Human-readable string which is rendered less prominently in the title.
*/
description?: string;

/**
* The badge to display for this webview view.
* To remove the badge, set to undefined.
*/
badge?: any;

/**
* Event fired when the view is disposed.
*
* Views are disposed when they are explicitly hidden by a user (this happens when a user
* right clicks in a view and unchecks the webview view).
*
* Trying to use the view after it has been disposed throws an exception.
*/
readonly onDidDispose: Event<void>;

/**
* Tracks if the webview is currently visible.
*
* Views are visible when they are on the screen and expanded.
*/
readonly visible: boolean;

/**
* Event fired when the visibility of the view changes.
*
* Actions that trigger a visibility change:
*
* - The view is collapsed or expanded.
* - The user switches to a different view group in the sidebar or panel.
*
* Note that hiding a view using the context menu instead disposes of the view and fires `onDidDispose`.
*/
readonly onDidChangeVisibility: Event<void>;

/**
* Reveal the view in the UI.
*
* If the view is collapsed, this will expand it.
*
* @param preserveFocus When `true` the view will not take focus.
*/
show(preserveFocus?: boolean): void;
}

/**
* Provider for creating `WebviewView` elements.
*/
export interface WebviewViewProvider {
/**
* Resolves a webview view.
*
* `resolveWebviewView` is called when a view first becomes visible. This may happen when the view is
* first loaded or when the user hides and then shows a view again.
*
* @param webviewView Webview view to restore. The provider should take ownership of this view. The
* provider must set the webview's `.html` and hook up all webview events it is interested in.
* @param context Additional metadata about the view being resolved.
* @param token Cancellation token indicating that the view being provided is no longer needed.
*
* @returns Optional thenable indicating that the view has been fully resolved.
*/
resolveWebviewView(webviewView: WebviewView, context: WebviewViewResolveContext, token: CancellationToken): Thenable<void> | void;
}

export namespace window {
/**
* Register a new provider for webview views.
*
* @param viewId Unique id of the view. This should match the `id` from the
* `views` contribution in the package.json.
* @param provider Provider for the webview views.
*
* @returns Disposable that unregisters the provider.
*/
export function registerWebviewViewProvider(
viewId: string,
provider: WebviewViewProvider,
options?: {
/**
* Content settings for the webview created for this view.
*/
readonly webviewOptions?: {
/**
* Controls if the webview element itself (iframe) is kept around even when the view
* is no longer visible.
*
* Normally the webview's html context is created when the view becomes visible
* and destroyed when it is hidden. Extensions that have complex state
* or UI can set the `retainContextWhenHidden` to make the editor keep the webview
* context around, even when the webview moves to a background tab. When a webview using
* `retainContextWhenHidden` becomes hidden, its scripts and other dynamic content are suspended.
* When the view becomes visible again, the context is automatically restored
* in the exact same state it was in originally. You cannot send messages to a
* hidden webview, even with `retainContextWhenHidden` enabled.
*
* `retainContextWhenHidden` has a high memory overhead and should only be used if
* your view's context cannot be quickly saved and restored.
*/
readonly retainContextWhenHidden?: boolean;
};
}
): Disposable {
return new Disposable();
}

export const visibleTextEditors = [];
/**
* Options for creating a {@link TreeView}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,7 @@ function createGlobalMocks() {
"zowe.jobs.sortBy",
"zowe.jobs.filterJobs",
"zowe.jobs.copyName",
"zowe.jobs.tabularView",
"zowe.updateSecureCredentials",
"zowe.manualPoll",
"zowe.editHistory",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ function createGlobalMocks() {
get: activeTextEditorDocument,
configurable: true,
});
Object.defineProperty(Profiles, "getInstance", { value: jest.fn().mockResolvedValue(newMocks.mockProfileInstance), configurable: true });
Object.defineProperty(Profiles, "getInstance", { value: jest.fn().mockReturnValue(newMocks.mockProfileInstance), configurable: true });
const executeCommand = jest.fn();
Object.defineProperty(vscode.commands, "executeCommand", { value: executeCommand, configurable: true });
Object.defineProperty(ZoweLogger, "error", { value: jest.fn(), configurable: true });
Expand Down Expand Up @@ -1130,9 +1130,20 @@ describe("cancelJob", () => {
createGlobalMocks();
const session = createISession();
const profile = createIProfile();
const jobSessionNode = createJobSessionNode(session, profile);
const jobNode = createJobNode(jobSessionNode, profile);
const jobsProvider = createJobsTree(session, jobNode.job, profile, createTreeView());

const createBlockMocks = () => {
const jobSessionNode = createJobSessionNode(session, profile);
const jobNode = createJobNode(jobSessionNode, profile);

return {
session: createISession(),
profile,
jobSessionNode,
jobNode,
jobsProvider: createJobsTree(session, jobNode.job, profile, createTreeView()),
};
};

const jesCancelJobMock = jest.fn();

const mockJesApi = (mockFn?: jest.Mock<any, any>): void => {
Expand All @@ -1155,17 +1166,20 @@ describe("cancelJob", () => {
});

it("returns early if no nodes are specified", async () => {
const { jobsProvider } = createBlockMocks();
await JobActions.cancelJobs(jobsProvider, []);
expect(Gui.showMessage).not.toHaveBeenCalled();
});

it("returns early if all nodes in selection have been cancelled", async () => {
const { jobNode, jobsProvider } = createBlockMocks();
jobNode.job.retcode = "CANCELED";
await JobActions.cancelJobs(jobsProvider, [jobNode]);
expect(Gui.showMessage).toHaveBeenCalledWith("The selected jobs were already cancelled.");
});

it("shows a warning message if one or more jobs failed to cancel", async () => {
const { jobNode, jobsProvider } = createBlockMocks();
jobNode.job.retcode = "ACTIVE";
jesCancelJobMock.mockResolvedValueOnce(false);
await JobActions.cancelJobs(jobsProvider, [jobNode]);
Expand All @@ -1175,6 +1189,7 @@ describe("cancelJob", () => {
});

it("shows a warning message if one or more APIs do not support cancelJob", async () => {
const { jobNode, jobsProvider } = createBlockMocks();
// Make cancelJob undefined
mockJesApi();
jobNode.job.retcode = "ACTIVE";
Expand All @@ -1188,6 +1203,7 @@ describe("cancelJob", () => {
});

it("shows matching error messages for one or more failed jobs", async () => {
const { jobNode, jobsProvider } = createBlockMocks();
jobNode.job.retcode = "ACTIVE";
jesCancelJobMock.mockRejectedValueOnce(new Error("Failed to cancel job... something went wrong."));
await JobActions.cancelJobs(jobsProvider, [jobNode]);
Expand All @@ -1200,18 +1216,18 @@ describe("cancelJob", () => {
});

it("shows a message confirming the jobs were cancelled", async () => {
const { jobNode, jobsProvider, jobSessionNode } = createBlockMocks();
jobNode.job.retcode = "ACTIVE";
jesCancelJobMock.mockResolvedValueOnce(true);
const setImmediateSpy = jest.spyOn(global, "setImmediate");
const getChildrenMock = jest.spyOn(jobSessionNode, "getChildren");
await JobActions.cancelJobs(jobsProvider, [jobNode]);

expect(getChildrenMock).toHaveBeenCalled();
// Check that refreshElement was called through setImmediate
expect(setImmediateSpy).toHaveBeenCalled();

expect(Gui.showMessage).toHaveBeenCalledWith("Cancelled selected jobs successfully.");
});

it("does not work for job session nodes", async () => {
const { jobsProvider, jobSessionNode } = createBlockMocks();
await JobActions.cancelJobs(jobsProvider, [jobSessionNode]);
expect(jesCancelJobMock).not.toHaveBeenCalled();
});
Expand Down
2 changes: 1 addition & 1 deletion packages/zowe-explorer/src/configuration/Constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import type { Profiles } from "./Profiles";

export class Constants {
public static CONFIG_PATH: string;
public static readonly COMMAND_COUNT = 99;
public static readonly COMMAND_COUNT = 100;
public static readonly MAX_SEARCH_HISTORY = 5;
public static readonly MAX_FILE_HISTORY = 10;
public static readonly MS_PER_SEC = 1000;
Expand Down

0 comments on commit 38b35f4

Please sign in to comment.