Skip to content

Commit

Permalink
UIE-204 Narrow Ajax Usage pt3 (#5109)
Browse files Browse the repository at this point in the history
  • Loading branch information
msilva-broad authored Sep 30, 2024
1 parent 98ceddf commit e7669f6
Show file tree
Hide file tree
Showing 12 changed files with 307 additions and 321 deletions.
1 change: 1 addition & 0 deletions src/libs/ajax/workspaces/Workspaces.ts
Original file line number Diff line number Diff line change
Expand Up @@ -634,3 +634,4 @@ export const Workspaces = (signal?: AbortSignal) => ({
});

export type WorkspacesAjaxContract = ReturnType<typeof Workspaces>;
export type WorkspaceContract = ReturnType<WorkspacesAjaxContract['workspace']>;
51 changes: 26 additions & 25 deletions src/pages/workspaces/workspace/workflows/WorkflowView.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,12 @@ import { makeMenuIcon, MenuTrigger } from 'src/components/PopupTrigger';
import StepButtons from 'src/components/StepButtons';
import { HeaderCell, SimpleFlexTable, SimpleTable, Sortable, TextCell } from 'src/components/table';
import WDLViewer from 'src/components/WDLViewer';
import { Ajax } from 'src/libs/ajax';
import { Dockstore } from 'src/libs/ajax/Dockstore';
import { GoogleStorage } from 'src/libs/ajax/GoogleStorage';
import { Methods } from 'src/libs/ajax/methods/Methods';
import { Metrics } from 'src/libs/ajax/Metrics';
import { makeExportWorkflowFromWorkspaceProvider } from 'src/libs/ajax/workspaces/providers/ExportWorkflowToWorkspaceProvider';
import { Workspaces } from 'src/libs/ajax/workspaces/Workspaces';
import colors, { terraSpecial } from 'src/libs/colors';
import { reportError, withErrorReporting } from 'src/libs/error';
import Events, { extractWorkspaceDetails } from 'src/libs/events';
Expand Down Expand Up @@ -265,7 +269,7 @@ const BucketContentModal = ({
Utils.withBusyState(setLoading),
withErrorReporting('Error loading bucket data')
)(async (newPrefix = prefix) => {
const { items, prefixes: newPrefixes } = await Ajax(signal).Buckets.list(googleProject, bucketName, newPrefix);
const { items, prefixes: newPrefixes } = await GoogleStorage(signal).list(googleProject, bucketName, newPrefix);
setObjects(items);
setPrefixes(newPrefixes);
setPrefix(newPrefix);
Expand Down Expand Up @@ -507,7 +511,7 @@ export const WorkflowView = _.flow(
} = modifiedConfig;
// will only match if the current root entity type comes from a snapshot
const snapshot = _.find({ metadata: { name: modifiedConfig.dataReferenceName } }, availableSnapshots);
Ajax().Metrics.captureEvent(Events.workflowLaunch, {
void Metrics().captureEvent(Events.workflowLaunch, {
...extractWorkspaceDetails(workspace),
snapshotId: snapshot?.reference.snapshot,
referenceId: snapshot?.referenceId,
Expand Down Expand Up @@ -536,7 +540,7 @@ export const WorkflowView = _.flow(

this.setState({ snapshotReferenceError: undefined });
try {
return await Ajax(signal).Workspaces.workspace(namespace, name).methodConfig(workflowNamespace, workflowName).validate();
return await Workspaces(signal).workspace(namespace, name).methodConfig(workflowNamespace, workflowName).validate();
} catch (e) {
if (e.status === 404) {
const errmsg = await e.text();
Expand All @@ -555,7 +559,7 @@ export const WorkflowView = _.flow(
const { namespace, name, signal } = this.props;

try {
return await Ajax(signal).Workspaces.workspace(namespace, name).snapshotEntityMetadata(googleProject, modifiedConfig.dataReferenceName);
return await Workspaces(signal).workspace(namespace, name).snapshotEntityMetadata(googleProject, modifiedConfig.dataReferenceName);
} catch (error) {
return undefined;
}
Expand All @@ -575,7 +579,7 @@ export const WorkflowView = _.flow(
} = this.props;

try {
const ws = Ajax(signal).Workspaces.workspace(namespace, name);
const ws = Workspaces(signal).workspace(namespace, name);

const [entityMetadata, validationResponse, config] = await Promise.all([
ws.entityMetadata(),
Expand All @@ -587,11 +591,11 @@ export const WorkflowView = _.flow(
} = config;
const isRedacted = !validationResponse;

const inputsOutputs = isRedacted ? {} : await Ajax(signal).Methods.configInputsOutputs(config);
const inputsOutputs = isRedacted ? {} : await Methods(signal).configInputsOutputs(config);
const selection = workflowSelectionStore.get();
const readSelection = selectionKey && selection.key === selectionKey;

const { gcpDataRepoSnapshots: snapshots } = await Ajax(signal).Workspaces.workspace(namespace, name).listSnapshots(1000, 0);
const { gcpDataRepoSnapshots: snapshots } = await Workspaces(signal).workspace(namespace, name).listSnapshots(1000, 0);
const snapshotMetadata = _.map('metadata', snapshots);

// Dockstore users who target floating tags can change their WDL via Github without explicitly selecting a new version in Terra.
Expand Down Expand Up @@ -632,12 +636,12 @@ export const WorkflowView = _.flow(
});

if (sourceRepo === 'agora') {
const methods = await Ajax(signal).Methods.list({ namespace: methodNamespace, name: methodName });
const methods = await Methods(signal).list({ namespace: methodNamespace, name: methodName });
const snapshotIds = _.map('snapshotId', methods);

this.setState({ versionIds: snapshotIds });
} else if (sourceRepo === 'dockstore' || sourceRepo === 'dockstoretools') {
const versions = await Ajax(signal).Dockstore.getVersions({ path: methodPath, isTool: sourceRepo === 'dockstoretools' });
const versions = await Dockstore(signal).getVersions({ path: methodPath, isTool: sourceRepo === 'dockstoretools' });
const versionIds = _.map('name', versions);

this.setState({ versionIds });
Expand Down Expand Up @@ -728,11 +732,11 @@ export const WorkflowView = _.flow(
try {
if (sourceRepo === 'agora') {
if (!currentSnapRedacted) {
const { synopsis, documentation, payload } = await Ajax(signal).Methods.method(methodNamespace, methodName, methodVersion).get();
const { synopsis, documentation, payload } = await Methods(signal).method(methodNamespace, methodName, methodVersion).get();
this.setState({ synopsis, documentation, wdl: payload });
}
} else if (sourceRepo === 'dockstore' || sourceRepo === 'dockstoretools') {
const wdl = await Ajax(signal).Dockstore.getWdl({ path: methodPath, version: methodVersion, isTool: sourceRepo === 'dockstoretools' });
const wdl = await Dockstore(signal).getWdl({ path: methodPath, version: methodVersion, isTool: sourceRepo === 'dockstoretools' });
this.setState({ wdl });
} else {
throw new Error('unknown sourceRepo');
Expand Down Expand Up @@ -780,8 +784,8 @@ export const WorkflowView = _.flow(
},
currentSnapRedacted,
} = this.state;
const config = await Ajax(signal).Methods.template({ methodNamespace, methodName, methodPath, sourceRepo, methodVersion: newSnapshotId });
const modifiedInputsOutputs = await Ajax(signal).Methods.configInputsOutputs(config);
const config = await Methods(signal).template({ methodNamespace, methodName, methodPath, sourceRepo, methodVersion: newSnapshotId });
const modifiedInputsOutputs = await Methods(signal).configInputsOutputs(config);
this.setState({ modifiedInputsOutputs, savedSnapRedacted: currentSnapRedacted, currentSnapRedacted: false });
this.setState(_.update('modifiedConfig', _.flow(_.set('methodRepoMethod', config.methodRepoMethod), filterConfigIO(modifiedInputsOutputs))));
this.fetchInfo(config);
Expand Down Expand Up @@ -1009,8 +1013,8 @@ export const WorkflowView = _.flow(
onChange: async ({ value, source }) => {
this.setState({ snapshotReferenceError: undefined });
if (source === 'snapshot') {
const selectedSnapshotEntityMetadata = await Ajax(signal)
.Workspaces.workspace(namespace, workspaceName)
const selectedSnapshotEntityMetadata = await Workspaces(signal)
.workspace(namespace, workspaceName)
.snapshotEntityMetadata(workspace.googleProject, value);

this.setState(_.set(['modifiedConfig', 'dataReferenceName'], value));
Expand Down Expand Up @@ -1350,10 +1354,7 @@ export const WorkflowView = _.flow(
this.setState({ deleting: false, updatingConfig: true });

try {
await Ajax()
.Workspaces.workspace(workspace.namespace, workspace.name)
.methodConfig(savedConfig.namespace, savedConfig.name)
.delete();
await Workspaces().workspace(workspace.namespace, workspace.name).methodConfig(savedConfig.namespace, savedConfig.name).delete();

Nav.goToPath('workspace-workflows', _.pick(['namespace', 'name'], workspace));
} catch (err) {
Expand Down Expand Up @@ -1398,7 +1399,7 @@ export const WorkflowView = _.flow(
const {
methodRepoMethod: { methodVersion, methodNamespace, methodName, methodPath, sourceRepo },
} = modifiedConfig;
Ajax().Metrics.captureEvent(Events.workflowUploadIO, {
void Metrics().captureEvent(Events.workflowUploadIO, {
...extractWorkspaceDetails(workspace.workspace),
inputsOrOutputs: key,
methodVersion,
Expand All @@ -1425,7 +1426,7 @@ export const WorkflowView = _.flow(
const {
methodRepoMethod: { methodVersion, methodNamespace, methodName, methodPath, sourceRepo },
} = modifiedConfig;
Ajax().Metrics.captureEvent(Events.workflowClearIO, {
void Metrics().captureEvent(Events.workflowClearIO, {
...extractWorkspaceDetails(workspace.workspace),
inputsOrOutputs: key,
methodVersion,
Expand Down Expand Up @@ -1572,7 +1573,7 @@ export const WorkflowView = _.flow(
const {
methodRepoMethod: { methodVersion, methodNamespace, methodName, methodPath, sourceRepo },
} = modifiedConfig;
Ajax().Metrics.captureEvent(Events.workflowUseDefaultOutputs, {
void Metrics().captureEvent(Events.workflowUseDefaultOutputs, {
...extractWorkspaceDetails(workspace.workspace),
methodVersion,
sourceRepo,
Expand Down Expand Up @@ -1604,8 +1605,8 @@ export const WorkflowView = _.flow(
_.update('outputs', this.isSingle() ? () => ({}) : _.mapValues(_.trim))
);

const validationResponse = await Ajax()
.Workspaces.workspace(namespace, name)
const validationResponse = await Workspaces()
.workspace(namespace, name)
.methodConfig(workflowNamespace, workflowName)
.save(trimInputOutput(modifiedConfig));

Expand Down
92 changes: 51 additions & 41 deletions src/pages/workspaces/workspace/workflows/WorkflowView.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import userEvent from '@testing-library/user-event';
import { h } from 'react-hyperscript-helpers';
import { Ajax } from 'src/libs/ajax';
import { leoDiskProvider } from 'src/libs/ajax/leonardo/providers/LeoDiskProvider';
import { Methods } from 'src/libs/ajax/methods/Methods';
import { Workspaces } from 'src/libs/ajax/workspaces/Workspaces';
import { getLocalPref, setLocalPref } from 'src/libs/prefs';
import DataStepContent from 'src/pages/workspaces/workspace/workflows/DataStepContent';
import { chooseRootType } from 'src/pages/workspaces/workspace/workflows/EntitySelectionType';
Expand All @@ -11,6 +13,13 @@ import { WorkflowView } from 'src/pages/workspaces/workspace/workflows/WorkflowV
import { asMockedFn, renderWithAppContexts as render, SelectHelper } from 'src/testing/test-utils';

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

jest.mock('src/libs/ajax/Dockstore');
jest.mock('src/libs/ajax/GoogleStorage');
jest.mock('src/libs/ajax/methods/Methods');
jest.mock('src/libs/ajax/Metrics');
jest.mock('src/libs/ajax/workspaces/Workspaces');

jest.mock('src/libs/nav', () => ({
getCurrentUrl: jest.fn().mockReturnValue(new URL('https://app.terra.bio')),
getLink: jest.fn(),
Expand Down Expand Up @@ -237,44 +246,45 @@ describe('Workflow View (GCP)', () => {
};
const mockLaunchResponse = jest.fn(() => Promise.resolve({ submissionId: 'abc123', ...initializedGoogleWorkspace.workspaceId }));

const renderWorkflowView = () => {
const mockDefaultAjax = () => {
asMockedFn(leoDiskProvider.list).mockImplementation(jest.fn());
Ajax.mockImplementation(() => ({
Methods: {
list: jest.fn(() => Promise.resolve(methodList)),
method: () => ({
get: jest.fn(() => Promise.resolve(mockAgoraResponse)),

Methods.mockReturnValue({
list: jest.fn(() => Promise.resolve(methodList)),
method: () => ({
get: jest.fn(() => Promise.resolve(mockAgoraResponse)),
}),
configInputsOutputs: jest.fn(() => Promise.resolve(mockConfigInputOutputs)),
});
Workspaces.mockReturnValue({
workspace: (_namespace, _name) => ({
details: jest.fn().mockResolvedValue(initializedGoogleWorkspace),
entityMetadata: jest.fn().mockReturnValue(entityMetadata),
listSnapshots: jest.fn().mockResolvedValue({
gcpDataRepoSnapshots: [],
}),
configInputsOutputs: jest.fn(() => Promise.resolve(mockConfigInputOutputs)),
},
Workspaces: {
workspace: (_namespace, _name) => ({
details: jest.fn().mockResolvedValue(initializedGoogleWorkspace),
entityMetadata: jest.fn().mockReturnValue(entityMetadata),
listSnapshots: jest.fn().mockResolvedValue({
gcpDataRepoSnapshots: [],
}),
checkBucketReadAccess: jest.fn(),
storageCostEstimate: jest.fn(),
bucketUsage: jest.fn(),
checkBucketLocation: jest.fn().mockResolvedValue(mockStorageDetails),
methodConfig: () => ({
save: jest.fn().mockReturnValue(mockSave),
validate: jest.fn().mockReturnValue(mockValidate),
get: jest.fn().mockResolvedValue({
methodRepoMethod: {
methodNamespace: 'gatk',
methodName: 'echo_to_file',
sourceRepo: 'agora',
methodUri: 'agora://gatk/echo_to_file/12',
methodVersion: 12,
},
rootEntityType: 'sra',
name: 'echo_to_file-configured',
}),
checkBucketReadAccess: jest.fn(),
storageCostEstimate: jest.fn(),
bucketUsage: jest.fn(),
checkBucketLocation: jest.fn().mockResolvedValue(mockStorageDetails),
methodConfig: () => ({
save: jest.fn().mockReturnValue(mockSave),
validate: jest.fn().mockReturnValue(mockValidate),
get: jest.fn().mockResolvedValue({
methodRepoMethod: {
methodNamespace: 'gatk',
methodName: 'echo_to_file',
sourceRepo: 'agora',
methodUri: 'agora://gatk/echo_to_file/12',
methodVersion: 12,
},
rootEntityType: 'sra',
name: 'echo_to_file-configured',
}),
}),
},
}),
});
Ajax.mockImplementation(() => ({
Disks: {
disksV1: () => ({
list: jest.fn(),
Expand All @@ -290,7 +300,7 @@ describe('Workflow View (GCP)', () => {
};

it('view workflow in workspace from mock import', async () => {
renderWorkflowView();
mockDefaultAjax();

// Act
await act(async () => {
Expand All @@ -312,7 +322,7 @@ describe('Workflow View (GCP)', () => {
const namespace = 'gatk';
const name = 'echo_to_file-configured';

renderWorkflowView();
mockDefaultAjax();

// Act
await act(async () => {
Expand Down Expand Up @@ -403,7 +413,7 @@ describe('Workflow View (GCP)', () => {
const namespace = 'gatk';
const name = 'echo_to_file-configured';

renderWorkflowView();
mockDefaultAjax();

// Act
await act(async () => {
Expand All @@ -425,7 +435,7 @@ describe('Workflow View (GCP)', () => {
const namespace = 'gatk';
const name = 'echo_to_file-configured';

renderWorkflowView();
mockDefaultAjax();

// Act
await act(async () => {
Expand Down Expand Up @@ -461,7 +471,7 @@ describe('Workflow View (GCP)', () => {
const namespace = 'gatk';
const name = 'echo_to_file-configured';

renderWorkflowView();
mockDefaultAjax();

getLocalPref.mockReturnValue({ useReferenceDisks: true, ignoreEmptyOutputs: true });

Expand All @@ -485,7 +495,7 @@ describe('Workflow View (GCP)', () => {
const namespace = 'gatk';
const name = 'echo_to_file-configured';

renderWorkflowView();
mockDefaultAjax();

getLocalPref.mockReturnValue({ useReferenceDisks: true, ignoreEmptyOutputs: true });

Expand Down Expand Up @@ -529,7 +539,7 @@ describe('Workflow View (GCP)', () => {

getLocalPref.mockReturnValue(undefined);

renderWorkflowView();
mockDefaultAjax();

// Act
await act(async () => {
Expand Down
Loading

0 comments on commit e7669f6

Please sign in to comment.