Skip to content

Commit

Permalink
Merge branch 'dev' into rj/dc-710-mock-visualizations
Browse files Browse the repository at this point in the history
  • Loading branch information
raejohanek committed Oct 4, 2024
2 parents 17466c5 + 3e1f96a commit 9709e28
Show file tree
Hide file tree
Showing 17 changed files with 149 additions and 214 deletions.
6 changes: 3 additions & 3 deletions integration-tests/tests/run-analysis-azure.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ const {
getAnimatedDrawer,
input,
noSpinnersAfter,
waitForNoModal,
waitForNoModalDrawer,
waitForNoSpinners,
} = require('../utils/integration-utils');
const { registerTest } = require('../utils/jest-utils');
Expand Down Expand Up @@ -51,7 +51,7 @@ const testRunAnalysisAzure = _.flowRight(
timeout: Millis.ofMinute,
});
await click(page, clickable({ textContains: 'Close' }), { timeout: Millis.ofMinute });
await waitForNoModal(page);
await waitForNoModalDrawer(page);

// Navigate to analysis launcher
await click(page, clickable({ textContains: `${notebookName}.ipynb` }));
Expand All @@ -63,7 +63,7 @@ const testRunAnalysisAzure = _.flowRight(
await click(page, clickable({ textContains: 'Open' }));
await findText(page, 'Azure Cloud Environment');
await click(page, clickable({ textContains: 'Create' }));
await waitForNoModal(page);
await waitForNoModalDrawer(page);

// Wait for env to begin creating
await findElement(page, clickable({ textContains: 'JupyterLab Environment' }));
Expand Down
6 changes: 3 additions & 3 deletions integration-tests/tests/run-analysis.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ const {
getAnimatedDrawer,
input,
noSpinnersAfter,
waitForNoModal,
waitForNoModalDrawer,
waitForNoSpinners,
} = require('../utils/integration-utils');
const { registerTest } = require('../utils/jest-utils');
Expand Down Expand Up @@ -47,7 +47,7 @@ const testRunAnalysisFn = _.flowRight(
timeout: Millis.ofMinute,
});
await click(page, clickable({ textContains: 'Close' }), { timeout: Millis.ofMinute });
await waitForNoModal(page);
await waitForNoModalDrawer(page);

// Navigate to analysis launcher
await click(page, clickable({ textContains: `${notebookName}.ipynb` }));
Expand All @@ -61,7 +61,7 @@ const testRunAnalysisFn = _.flowRight(
});
await findText(page, 'Jupyter Cloud Environment');
await click(page, clickable({ text: 'Create' }));
await waitForNoModal(page);
await waitForNoModalDrawer(page);

// Wait for env to begin creating
await findElement(page, clickable({ textContains: 'Jupyter Environment' }), { timeout: Millis.ofSeconds(40) });
Expand Down
6 changes: 3 additions & 3 deletions integration-tests/tests/run-rstudio.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ const {
getAnimatedDrawer,
input,
noSpinnersAfter,
waitForNoModal,
waitForNoModalDrawer,
waitForNoSpinners,
} = require('../utils/integration-utils');
const { registerTest } = require('../utils/jest-utils');
Expand Down Expand Up @@ -50,7 +50,7 @@ const testRunRStudioFn = _.flowRight(
timeout: Millis.ofMinute,
});
await click(page, clickable({ textContains: 'Close' }), { timeout: Millis.ofMinute });
await waitForNoModal(page);
await waitForNoModalDrawer(page);

// Navigate to analysis launcher
await click(page, clickable({ textContains: `${rFileName}.Rmd` }));
Expand All @@ -63,7 +63,7 @@ const testRunRStudioFn = _.flowRight(
action: () => click(page, clickable({ textContains: 'Open' })),
});
await click(page, clickable({ text: 'Create' }));
await waitForNoModal(page);
await waitForNoModalDrawer(page);

// Wait for env to begin creating
await findElement(page, clickable({ textContains: 'RStudio Environment' }), { timeout: Millis.ofMinutes(2) });
Expand Down
7 changes: 7 additions & 0 deletions integration-tests/utils/integration-utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,12 @@ const waitForModal = (page, { timeout = 30000 } = {}) => {
return page.waitForSelector('.ReactModal__Overlay', { hidden: false, timeout });
};

const waitForNoModalDrawer = async (page) => {
await waitForNoModal(page);
// Matches the animation transition time
await delay(200);
};

// Puppeteer works by internally using MutationObserver. We are setting up the listener before
// the action to ensure that the spinner rendering is captured by the observer, followed by
// waiting for the spinner to be removed
Expand Down Expand Up @@ -631,6 +637,7 @@ module.exports = {
waitForNoModal,
waitForMenu,
waitForModal,
waitForNoModalDrawer,
waitForNoSpinners,
withPageLogging,
withScreenshot,
Expand Down
22 changes: 7 additions & 15 deletions src/pages/workspaces/workspace/workflows/WorkflowView.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@ import { act, fireEvent, screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { h } from 'react-hyperscript-helpers';
import { Ajax } from 'src/libs/ajax';
import { Apps } from 'src/libs/ajax/leonardo/Apps';
import { leoDiskProvider } from 'src/libs/ajax/leonardo/providers/LeoDiskProvider';
import { Runtimes } from 'src/libs/ajax/leonardo/Runtimes';
import { Methods } from 'src/libs/ajax/methods/Methods';
import { Workspaces } from 'src/libs/ajax/workspaces/Workspaces';
import { getLocalPref, setLocalPref } from 'src/libs/prefs';
Expand All @@ -16,6 +18,8 @@ jest.mock('src/libs/ajax');

jest.mock('src/libs/ajax/Dockstore');
jest.mock('src/libs/ajax/GoogleStorage');
jest.mock('src/libs/ajax/leonardo/Apps');
jest.mock('src/libs/ajax/leonardo/Runtimes');
jest.mock('src/libs/ajax/methods/Methods');
jest.mock('src/libs/ajax/Metrics');
jest.mock('src/libs/ajax/workspaces/Workspaces');
Expand Down Expand Up @@ -247,8 +251,6 @@ describe('Workflow View (GCP)', () => {
const mockLaunchResponse = jest.fn(() => Promise.resolve({ submissionId: 'abc123', ...initializedGoogleWorkspace.workspaceId }));

const mockDefaultAjax = () => {
asMockedFn(leoDiskProvider.list).mockImplementation(jest.fn());

Methods.mockReturnValue({
list: jest.fn(() => Promise.resolve(methodList)),
method: () => ({
Expand Down Expand Up @@ -284,19 +286,9 @@ describe('Workflow View (GCP)', () => {
}),
}),
});
Ajax.mockImplementation(() => ({
Disks: {
disksV1: () => ({
list: jest.fn(),
}),
},
Runtimes: {
listV2: jest.fn(),
},
Apps: {
list: jest.fn().mockReturnValue([]),
},
}));
Apps.mockReturnValue({ list: jest.fn().mockReturnValue([]) });
Runtimes.mockReturnValue({ listV2: jest.fn() });
asMockedFn(leoDiskProvider.list).mockImplementation(jest.fn());
};

it('view workflow in workspace from mock import', async () => {
Expand Down
6 changes: 3 additions & 3 deletions src/workspaces/common/state/useAppPolling.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { useEffect, useRef, useState } from 'react';
import { Ajax } from 'src/libs/ajax';
import { Apps } from 'src/libs/ajax/leonardo/Apps';
import { ListAppItem } from 'src/libs/ajax/leonardo/models/app-models';
import { withErrorIgnoring, withErrorReporting } from 'src/libs/error';
import { InitializedWorkspaceWrapper as Workspace } from 'src/workspaces/common/state/useWorkspace';
Expand Down Expand Up @@ -30,14 +30,14 @@ export const useAppPolling = (name: string, namespace: string, workspace?: Works
try {
const newGoogleApps =
workspace?.workspaceInitialized && isGoogleWorkspace(workspace)
? await Ajax(signal).Apps.list(workspace.workspace.googleProject, {
? await Apps(signal).list(workspace.workspace.googleProject, {
role: 'creator',
saturnWorkspaceName: workspace.workspace.name,
})
: [];
const newAzureApps =
workspace?.workspaceInitialized && isAzureWorkspace(workspace)
? await Ajax(signal).Apps.listAppsV2(workspace.workspace.workspaceId)
? await Apps(signal).listAppsV2(workspace.workspace.workspaceId)
: [];
const combinedNewApps = [...newGoogleApps, ...newAzureApps];

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@ import { DeepPartial } from '@terra-ui-packages/core-utils';
import { NotificationType } from '@terra-ui-packages/notifications';
import { waitFor } from '@testing-library/react';
import React from 'react';
import { Ajax } from 'src/libs/ajax';
import { WorkspaceContract, Workspaces, WorkspacesAjaxContract } from 'src/libs/ajax/workspaces/Workspaces';
import { clearNotification, notify } from 'src/libs/notifications';
import { cloningWorkspacesStore } from 'src/libs/state';
import { asMockedFn, renderWithAppContexts as render } from 'src/testing/test-utils';
import { asMockedFn, partial, renderWithAppContexts as render } from 'src/testing/test-utils';
import { defaultAzureWorkspace } from 'src/testing/workspace-fixtures';
import {
notifyNewWorkspaceClone,
Expand All @@ -14,15 +14,7 @@ import {
import { WORKSPACE_UPDATE_POLLING_INTERVAL } from 'src/workspaces/common/state/useWorkspaceStatePolling';
import { WorkspaceInfo, WorkspaceState, WorkspaceWrapper } from 'src/workspaces/utils';

type AjaxContract = ReturnType<typeof Ajax>;
type AjaxWorkspacesContract = AjaxContract['Workspaces'];

jest.mock('src/libs/ajax', (): typeof import('src/libs/ajax') => {
return {
...jest.requireActual('src/libs/ajax'),
Ajax: jest.fn(),
};
});
jest.mock('src/libs/ajax/workspaces/Workspaces');

type NotificationExports = typeof import('src/libs/notifications');
jest.mock<NotificationExports>(
Expand Down Expand Up @@ -95,15 +87,11 @@ describe('useCloningWorkspaceNotifications', () => {
},
};
const mockDetailsFn = jest.fn().mockResolvedValue(update);
const mockAjax: DeepPartial<AjaxContract> = {
Workspaces: {
workspace: () =>
({
details: mockDetailsFn,
} as Partial<AjaxWorkspacesContract['workspace']>),
},
};
asMockedFn(Ajax).mockImplementation(() => mockAjax as AjaxContract);
asMockedFn(Workspaces).mockReturnValue(
partial<WorkspacesAjaxContract>({
workspace: () => partial<WorkspaceContract>({ details: mockDetailsFn }),
})
);

// Act
render(<CloningTestComponent />);
Expand Down Expand Up @@ -136,12 +124,11 @@ describe('useCloningWorkspaceNotifications', () => {
},
};
const mockDetailsFn = jest.fn().mockImplementation(() => Promise.resolve(update));
const mockAjax: DeepPartial<AjaxContract> = {
Workspaces: {
workspace: () => ({ details: mockDetailsFn }),
},
};
asMockedFn(Ajax).mockImplementation(() => mockAjax as AjaxContract);
asMockedFn(Workspaces).mockReturnValue(
partial<WorkspacesAjaxContract>({
workspace: () => partial<WorkspaceContract>({ details: mockDetailsFn }),
})
);
jest.useFakeTimers();
// Act
render(<CloningTestComponent />);
Expand Down Expand Up @@ -170,15 +157,11 @@ describe('useCloningWorkspaceNotifications', () => {
},
};
const mockDetailsFn = jest.fn().mockResolvedValue(update);
const mockAjax: DeepPartial<AjaxContract> = {
Workspaces: {
workspace: () =>
({
details: mockDetailsFn,
} as Partial<AjaxWorkspacesContract['workspace']>),
},
};
asMockedFn(Ajax).mockImplementation(() => mockAjax as AjaxContract);
asMockedFn(Workspaces).mockReturnValue(
partial<WorkspacesAjaxContract>({
workspace: () => partial<WorkspaceContract>({ details: mockDetailsFn }),
})
);
jest.useFakeTimers();

// Act
Expand Down
14 changes: 6 additions & 8 deletions src/workspaces/common/state/useCloudEnvironmentPolling.test.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,15 @@
import { generateTestDiskWithGoogleWorkspace } from 'src/analysis/_testData/testData';
import { Ajax } from 'src/libs/ajax';
import { leoDiskProvider, PersistentDisk } from 'src/libs/ajax/leonardo/providers/LeoDiskProvider';
import { RuntimesAjaxContract } from 'src/libs/ajax/leonardo/Runtimes';
import { asMockedFn, renderHookInAct } from 'src/testing/test-utils';
import { Runtimes, RuntimesAjaxContract } from 'src/libs/ajax/leonardo/Runtimes';
import { asMockedFn, partial, renderHookInAct } from 'src/testing/test-utils';
import { defaultGoogleWorkspace, defaultInitializedGoogleWorkspace } from 'src/testing/workspace-fixtures';

import { useCloudEnvironmentPolling } from './useCloudEnvironmentPolling';

jest.mock('src/libs/ajax');
jest.mock('src/libs/ajax/leonardo/Runtimes');
jest.mock('src/libs/ajax/leonardo/providers/LeoDiskProvider');

// This code will be needed when we mock and test the runtime methods
type AjaxContract = ReturnType<typeof Ajax>;
type RuntimesNeeds = Pick<RuntimesAjaxContract, 'listV2'>;
interface RuntimeMockNeeds {
topLevel: RuntimesNeeds;
Expand All @@ -30,9 +28,9 @@ const mockAjaxNeeds = (): AjaxMockNeeds => {
const partialRuntimes: RuntimesNeeds = {
listV2: jest.fn(),
};
const mockRuntimes = partialRuntimes as RuntimesAjaxContract;
const mockRuntimes = partial<RuntimesAjaxContract>(partialRuntimes);

asMockedFn(Ajax).mockReturnValue({ Runtimes: mockRuntimes } as AjaxContract);
asMockedFn(Runtimes).mockReturnValue(mockRuntimes);

return {
Runtimes: {
Expand Down Expand Up @@ -69,7 +67,7 @@ describe('useCloudEnvironmentPolling', () => {

// Assert
// Runtimes and disk ajax calls
expect(Ajax).toBeCalledTimes(1);
expect(Runtimes).toBeCalledTimes(1);
expect(leoDiskProvider.list).toBeCalledTimes(1);
expect(result.current.persistentDisks).toEqual([persistentDisk]);
expect(result.current.appDataDisks).toEqual([appDisk]);
Expand Down
4 changes: 2 additions & 2 deletions src/workspaces/common/state/useCloudEnvironmentPolling.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ import _ from 'lodash/fp';
import { useEffect, useRef, useState } from 'react';
import { getDiskAppType } from 'src/analysis/utils/app-utils';
import { getConvertedRuntimeStatus, getCurrentRuntime } from 'src/analysis/utils/runtime-utils';
import { Ajax } from 'src/libs/ajax';
import { ListRuntimeItem } from 'src/libs/ajax/leonardo/models/runtime-models';
import { leoDiskProvider, PersistentDisk } from 'src/libs/ajax/leonardo/providers/LeoDiskProvider';
import { Runtimes } from 'src/libs/ajax/leonardo/Runtimes';
import { withErrorIgnoring, withErrorReporting } from 'src/libs/error';
import { InitializedWorkspaceWrapper as Workspace } from 'src/workspaces/common/state/useWorkspace';

Expand Down Expand Up @@ -58,7 +58,7 @@ export const useCloudEnvironmentPolling = (
},
{ signal: controller.current.signal }
),
Ajax(controller.current.signal).Runtimes.listV2(cloudEnvFilters),
Runtimes(controller.current.signal).listV2(cloudEnvFilters),
]);

setRuntimes(newRuntimes);
Expand Down
1 change: 0 additions & 1 deletion src/workspaces/common/state/useWorkspace.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ import {
} from 'src/workspaces/common/state/useWorkspace';

jest.mock('src/libs/ajax/AzureStorage');

jest.mock('src/libs/ajax/Metrics');
jest.mock('src/libs/ajax/workspaces/Workspaces');

Expand Down
30 changes: 5 additions & 25 deletions src/workspaces/common/state/useWorkspaceById.test.ts
Original file line number Diff line number Diff line change
@@ -1,31 +1,16 @@
import { DeepPartial } from '@terra-ui-packages/core-utils';
import { act } from '@testing-library/react';
import { Ajax } from 'src/libs/ajax';
import { asMockedFn, renderHookInAct } from 'src/testing/test-utils';
import { Workspaces, WorkspacesAjaxContract } from 'src/libs/ajax/workspaces/Workspaces';
import { asMockedFn, partial, renderHookInAct } from 'src/testing/test-utils';

import { useWorkspaceById } from './useWorkspaceById';

type AjaxExports = typeof import('src/libs/ajax');
jest.mock('src/libs/ajax', (): AjaxExports => {
const actual = jest.requireActual<AjaxExports>('src/libs/ajax');
return {
...actual,
Ajax: jest.fn(),
};
});

type AjaxContract = ReturnType<typeof Ajax>;
jest.mock('src/libs/ajax/workspaces/Workspaces');

describe('useWorkspaceById', () => {
it('fetches a workspace by ID', async () => {
// Arrange
const getWorkspaceById = jest.fn().mockResolvedValue({});
const mockAjax: DeepPartial<AjaxContract> = {
Workspaces: {
getById: getWorkspaceById,
},
};
asMockedFn(Ajax).mockImplementation(() => mockAjax as AjaxContract);
asMockedFn(Workspaces).mockReturnValue(partial<WorkspacesAjaxContract>({ getById: getWorkspaceById }));

// Act
await renderHookInAct(() => useWorkspaceById('test-workspace'));
Expand All @@ -37,12 +22,7 @@ describe('useWorkspaceById', () => {
it('fetches workspace when ID changes', async () => {
// Arrange
const getWorkspaceById = jest.fn().mockResolvedValue({});
const mockAjax: DeepPartial<AjaxContract> = {
Workspaces: {
getById: getWorkspaceById,
},
};
asMockedFn(Ajax).mockImplementation(() => mockAjax as AjaxContract);
asMockedFn(Workspaces).mockReturnValue(partial<WorkspacesAjaxContract>({ getById: getWorkspaceById }));

const { rerender } = await renderHookInAct(useWorkspaceById, { initialProps: 'workspace-1' });

Expand Down
Loading

0 comments on commit 9709e28

Please sign in to comment.