diff --git a/src/pages/ImportWorkflow/importDockstoreWorkflow.test.ts b/src/pages/ImportWorkflow/importDockstoreWorkflow.test.ts index dc5374b6f7..bd1fccb871 100644 --- a/src/pages/ImportWorkflow/importDockstoreWorkflow.test.ts +++ b/src/pages/ImportWorkflow/importDockstoreWorkflow.test.ts @@ -1,11 +1,11 @@ -import { DeepPartial } from '@terra-ui-packages/core-utils'; -import { Ajax, AjaxContract } from 'src/libs/ajax'; -import { WorkspacesAjaxContract } from 'src/libs/ajax/workspaces/Workspaces'; -import { asMockedFn } from 'src/testing/test-utils'; +import { Methods, MethodsAjaxContract } from 'src/libs/ajax/methods/Methods'; +import { WorkspaceContract, Workspaces, WorkspacesAjaxContract } from 'src/libs/ajax/workspaces/Workspaces'; +import { asMockedFn, MockedFn, partial } from 'src/testing/test-utils'; import { importDockstoreWorkflow } from './importDockstoreWorkflow'; -jest.mock('src/libs/ajax'); +jest.mock('src/libs/ajax/methods/Methods'); +jest.mock('src/libs/ajax/workspaces/Workspaces'); describe('importDockstoreWorkflow', () => { const testWorkspace = { @@ -19,48 +19,48 @@ describe('importDockstoreWorkflow', () => { source: 'dockstore', }; - let workspaceAjax; - let workspaceMethodConfigAjax; - let methodConfigInputsOutputs; - let importMethodConfig; - let deleteMethodConfig; + let workspaceMethodConfigAjax: MockedFn; + let methodConfigInputsOutputs: MockedFn; + let importMethodConfig: MockedFn; + let deleteMethodConfig: MockedFn['delete']>; + + type MethodConfigContract = ReturnType; beforeEach(() => { // Arrange - importMethodConfig = jest.fn().mockResolvedValue(undefined); - deleteMethodConfig = jest.fn().mockResolvedValue(undefined); - - const mockWorkspaceMethodConfigAjax: Partial['methodConfig']> = { - delete: deleteMethodConfig, - }; - - workspaceMethodConfigAjax = jest.fn().mockReturnValue(mockWorkspaceMethodConfigAjax); + importMethodConfig = jest.fn(async (_config) => partial({})); + deleteMethodConfig = jest.fn(async () => partial({})); - const mockWorkspaceAjax: DeepPartial> = { - entityMetadata: () => - Promise.resolve({ - participant: { count: 1, idName: 'participant_id', attributeNames: [] }, - sample: { count: 1, idName: 'sample_id', attributeNames: [] }, - }), - importMethodConfig, - methodConfig: workspaceMethodConfigAjax, - }; - - workspaceAjax = jest.fn().mockReturnValue(mockWorkspaceAjax); + workspaceMethodConfigAjax = jest.fn((_namespace, _name) => + partial({ + delete: deleteMethodConfig, + }) + ); - methodConfigInputsOutputs = jest.fn().mockResolvedValue({ + methodConfigInputsOutputs = jest.fn(async (_configs) => ({ inputs: [], outputs: [ { name: 'taskA.output1', outputType: 'String' }, { name: 'taskA.output2', outputType: 'String' }, ], - }); - - const mockAjax: DeepPartial = { - Workspaces: { workspace: workspaceAjax }, - Methods: { configInputsOutputs: methodConfigInputsOutputs }, - }; - asMockedFn(Ajax).mockImplementation(() => mockAjax as AjaxContract); + })); + + asMockedFn(Workspaces).mockReturnValue( + partial({ + workspace: () => + partial({ + entityMetadata: async () => ({ + participant: { count: 1, idName: 'participant_id', attributeNames: [] }, + sample: { count: 1, idName: 'sample_id', attributeNames: [] }, + }), + importMethodConfig, + methodConfig: workspaceMethodConfigAjax, + }), + }) + ); + asMockedFn(Methods).mockReturnValue( + partial({ configInputsOutputs: methodConfigInputsOutputs }) + ); }); it('imports workflow into workspace', async () => { diff --git a/src/pages/ImportWorkflow/importDockstoreWorkflow.ts b/src/pages/ImportWorkflow/importDockstoreWorkflow.ts index 0bd8b8fb17..c62aa4a42d 100644 --- a/src/pages/ImportWorkflow/importDockstoreWorkflow.ts +++ b/src/pages/ImportWorkflow/importDockstoreWorkflow.ts @@ -1,5 +1,6 @@ import _ from 'lodash/fp'; -import { Ajax } from 'src/libs/ajax'; +import { Methods } from 'src/libs/ajax/methods/Methods'; +import { Workspaces } from 'src/libs/ajax/workspaces/Workspaces'; type ImportDockstoreWorkflowArgs = { workspace: { @@ -25,11 +26,11 @@ export const importDockstoreWorkflow = async ( const { name, namespace } = workspace; const { path, version, source } = workflow; - const workspaceApi = Ajax().Workspaces.workspace(namespace, name); + const workspaceApi = Workspaces().workspace(namespace, name); const [entityMetadata, { outputs: workflowOutputs }] = await Promise.all([ workspaceApi.entityMetadata(), - Ajax().Methods.configInputsOutputs({ + Methods().configInputsOutputs({ methodRepoMethod: { methodPath: path, methodVersion: version, diff --git a/src/pages/LandingPage.js b/src/pages/LandingPage.js index 18d2cc1aea..0a1b43f617 100644 --- a/src/pages/LandingPage.js +++ b/src/pages/LandingPage.js @@ -6,7 +6,7 @@ import { HeroWrapper } from 'src/components/HeroWrapper'; import { icon } from 'src/components/icons'; import hexButton from 'src/images/hex-button.svg'; import roadmapBgBanner from 'src/images/roadmap-bg-banner.png'; -import { Ajax } from 'src/libs/ajax'; +import { Billing } from 'src/libs/ajax/billing/Billing'; import { getEnabledBrand, isFirecloud, isTerra } from 'src/libs/brand-utils'; import { landingPageCardsDefault, roadMapCardDefault } from 'src/libs/brands'; import colors from 'src/libs/colors'; @@ -100,7 +100,7 @@ export const LandingPage = () => { const errorObj = (await error) instanceof Response ? error.json() : error; console.log(`Unable to load billing projects due to: ${errorObj?.message}`); // eslint-disable-line no-console })(async () => { - const projects = await Ajax(signal).Billing.listProjects(); + const projects = await Billing(signal).listProjects(); setBillingProjects(projects); }); if (signInStatus === 'authenticated') { diff --git a/src/pages/library/Code.js b/src/pages/library/Code.js index d7ac4370cd..0ff1aede88 100644 --- a/src/pages/library/Code.js +++ b/src/pages/library/Code.js @@ -8,7 +8,9 @@ import { centeredSpinner } from 'src/components/icons'; import { libraryTopMatter } from 'src/components/library-common'; import broadSquare from 'src/images/library/code/broad-square.svg'; import dockstoreLogo from 'src/images/library/code/dockstore.svg'; -import { Ajax } from 'src/libs/ajax'; +import { Dockstore } from 'src/libs/ajax/Dockstore'; +import { FirecloudBucket } from 'src/libs/ajax/firecloud/FirecloudBucket'; +import { Methods } from 'src/libs/ajax/methods/Methods'; import { getEnabledBrand } from 'src/libs/brand-utils'; import colors from 'src/libs/colors'; import { getConfig } from 'src/libs/config'; @@ -118,9 +120,9 @@ export const MethodRepoTile = () => { const getFeaturedMethods = async (signal) => { const [featuredMethods, methodsRepoMethodsList, dockstoreMethodsList] = await Promise.all([ - Ajax(signal).FirecloudBucket.getFeaturedMethods(), - Ajax(signal).Methods.list({ namespace: 'gatk' }), - Ajax(signal).Dockstore.listTools({ organization: 'gatk-workflows' }), + FirecloudBucket(signal).getFeaturedMethods(), + Methods(signal).list({ namespace: 'gatk' }), + Dockstore(signal).listTools({ organization: 'gatk-workflows' }), ]); const methodsRepoMethodDetails = _.flow( diff --git a/src/pages/library/Code.test.js b/src/pages/library/Code.test.js index 5e78bc0b46..f575d8eb92 100644 --- a/src/pages/library/Code.test.js +++ b/src/pages/library/Code.test.js @@ -1,10 +1,15 @@ import { act, screen } from '@testing-library/react'; import { h } from 'react-hyperscript-helpers'; -import { Ajax } from 'src/libs/ajax'; +import { Dockstore } from 'src/libs/ajax/Dockstore'; +import { FirecloudBucket } from 'src/libs/ajax/firecloud/FirecloudBucket'; +import { Methods } from 'src/libs/ajax/methods/Methods'; import { Code } from 'src/pages/library/Code'; import { renderWithAppContexts as render } from 'src/testing/test-utils'; -jest.mock('src/libs/ajax'); +jest.mock('src/libs/ajax/Dockstore'); +jest.mock('src/libs/ajax/firecloud/FirecloudBucket'); +jest.mock('src/libs/ajax/methods/Methods'); + jest.mock('src/libs/nav', () => ({ ...jest.requireActual('src/libs/nav'), getLink: jest.fn().mockImplementation((_) => _), @@ -12,9 +17,6 @@ jest.mock('src/libs/nav', () => ({ describe('Code page', () => { it('loads the code page', async () => { - const token = 'testtoken'; - const newToken = 'newtesttoken'; - const methodsList = [ { name: 'joint-discovery-gatk4', @@ -35,48 +37,14 @@ describe('Code page', () => { }, ]; - const mockOidcUser = { - id_token: undefined, - session_state: null, - access_token: token, - refresh_token: '', - token_type: '', - scope: undefined, - profile: { - sub: '', - iss: '', - aud: '', - exp: 0, - iat: 0, - }, - expires_at: undefined, - state: undefined, - expires_in: 0, - expired: undefined, - scopes: [], - toStorageString: '', - }; - - Ajax.mockImplementation(() => { - mockOidcUser.access_token = newToken; - return Promise.resolve({ - status: 'success', - oidcUser: mockOidcUser, - }); + FirecloudBucket.mockReturnValue({ + getFeaturedMethods: jest.fn(() => Promise.resolve(featuredMethodsList)), }); - - Ajax.mockImplementation(() => { - return { - FirecloudBucket: { - getFeaturedMethods: jest.fn(() => Promise.resolve(featuredMethodsList)), - }, - Methods: { - list: jest.fn(() => Promise.resolve(methodsList)), - }, - Dockstore: { - listTools: jest.fn(), - }, - }; + Methods.mockReturnValue({ + list: jest.fn(() => Promise.resolve(methodsList)), + }); + Dockstore.mockReturnValue({ + listTools: jest.fn(), }); // Act diff --git a/src/pages/library/Datasets.js b/src/pages/library/Datasets.js index 0578b932d0..28a8dc19d4 100644 --- a/src/pages/library/Datasets.js +++ b/src/pages/library/Datasets.js @@ -20,7 +20,7 @@ import rareXLogo from 'src/images/library/datasets/rare-x-logo.svg'; import targetLogo from 'src/images/library/datasets/target_logo.jpeg'; import tcgaLogo from 'src/images/library/datasets/TCGALogo.jpg'; import topMedLogo from 'src/images/library/datasets/TopMed@2x.png'; -import { Ajax } from 'src/libs/ajax'; +import { Metrics } from 'src/libs/ajax/Metrics'; import { getEnabledBrand } from 'src/libs/brand-utils'; import colors from 'src/libs/colors'; import { getConfig } from 'src/libs/config'; @@ -135,7 +135,7 @@ const Participant = ({ logo, title, shortDescription, description, sizeText, mod const browseTooltip = 'Look for the Export to Terra icon to export data from this provider.'; -const captureBrowseDataEvent = (datasetName) => Ajax().Metrics.captureEvent(Events.datasetLibraryBrowseData, { datasetName }); +const captureBrowseDataEvent = (datasetName) => void Metrics().captureEvent(Events.datasetLibraryBrowseData, { datasetName }); const thousandGenomesHighCoverage = () => h( @@ -654,7 +654,7 @@ export const Datasets = () => { h(DataBrowserPreviewToggler, { onChange: (value) => { setCatalogShowing(value); - Ajax().Metrics.captureEvent(Events.catalogToggle, { enabled: value }); + void Metrics().captureEvent(Events.catalogToggle, { enabled: value }); setLocalPref('catalog-toggle', value); }, catalogShowing, diff --git a/src/pages/library/Datasets.test.js b/src/pages/library/Datasets.test.js index cf4709b656..7c73d0760f 100644 --- a/src/pages/library/Datasets.test.js +++ b/src/pages/library/Datasets.test.js @@ -6,6 +6,8 @@ import { dataCatalogStore } from 'src/libs/state'; import { Datasets } from 'src/pages/library/Datasets'; import { renderWithAppContexts as render } from 'src/testing/test-utils'; +jest.mock('src/libs/ajax/Metrics'); + jest.mock('src/libs/brand-utils', () => { const { brands } = jest.requireActual('src/libs/brands'); return { diff --git a/src/pages/library/SearchAndFilterComponent.ts b/src/pages/library/SearchAndFilterComponent.ts index 5430455367..a8ed2cf192 100644 --- a/src/pages/library/SearchAndFilterComponent.ts +++ b/src/pages/library/SearchAndFilterComponent.ts @@ -8,7 +8,7 @@ import Collapse from 'src/components/Collapse'; import { ButtonPrimary, Clickable, IdContainer, LabeledCheckbox, Link, Select } from 'src/components/common'; import { icon } from 'src/components/icons'; import { DelayedAutoCompleteInput, DelayedSearchInput } from 'src/components/input'; -import { Ajax } from 'src/libs/ajax'; +import { Metrics } from 'src/libs/ajax/Metrics'; import colors from 'src/libs/colors'; import Events from 'src/libs/events'; import * as Nav from 'src/libs/nav'; @@ -378,7 +378,7 @@ const getContextualSuggestion = ([leftContext, match, rightContext]) => { ]; }; -const sendSearchEvent = (term) => Ajax().Metrics.captureEvent(Events.catalogFilterSearch, { term }); +const sendSearchEvent = (term) => void Metrics().captureEvent(Events.catalogFilterSearch, { term }); const debounceSearchEvent = _.debounce(5000, sendSearchEvent); /** @@ -759,7 +759,7 @@ export const SearchAndFilterComponent = ({ const sectionToAlter = selectedSections[sectionSelected]; const valuesSelected = _.xor(sectionEntries, sectionToAlter.values); _.forEach( - (sectionEntry) => Ajax().Metrics.captureEvent(Events.catalogFilterSidebar, { tag: sectionEntry }), + (sectionEntry) => void Metrics().captureEvent(Events.catalogFilterSidebar, { tag: sectionEntry }), sectionEntries ); valuesSelected.length > 0 diff --git a/src/pages/library/Showcase.js b/src/pages/library/Showcase.js index 2db5085347..85e80bd802 100644 --- a/src/pages/library/Showcase.js +++ b/src/pages/library/Showcase.js @@ -8,7 +8,7 @@ import { FirstParagraphMarkdownViewer } from 'src/components/markdown'; import covidBg from 'src/images/library/showcase/covid-19.jpg'; import featuredBg from 'src/images/library/showcase/featured-workspace.svg'; import gatkLogo from 'src/images/library/showcase/gatk-logo-light.svg'; -import { Ajax } from 'src/libs/ajax'; +import { FirecloudBucket } from 'src/libs/ajax/firecloud/FirecloudBucket'; import colors from 'src/libs/colors'; import { withErrorReporting } from 'src/libs/error'; import * as Nav from 'src/libs/nav'; @@ -153,7 +153,7 @@ export const Showcase = () => { useOnMount(() => { const loadData = withErrorReporting('Error loading showcase')(async () => { - const showcase = await Ajax().FirecloudBucket.getShowcaseWorkspaces(); + const showcase = await FirecloudBucket().getShowcaseWorkspaces(); const featuredWorkspaces = _.map((workspace) => { // SearchAndFilterComponent compares lowercased filters from the sidebar to diff --git a/src/pages/library/Showcase.test.js b/src/pages/library/Showcase.test.js index 8bb424b963..dda78fd5df 100644 --- a/src/pages/library/Showcase.test.js +++ b/src/pages/library/Showcase.test.js @@ -1,10 +1,10 @@ import { act, screen } from '@testing-library/react'; import { h } from 'react-hyperscript-helpers'; -import { Ajax } from 'src/libs/ajax'; +import { FirecloudBucket } from 'src/libs/ajax/firecloud/FirecloudBucket'; import { Showcase, sidebarSections } from 'src/pages/library/Showcase'; import { renderWithAppContexts as render } from 'src/testing/test-utils'; -jest.mock('src/libs/ajax'); +jest.mock('src/libs/ajax/firecloud/FirecloudBucket'); jest.mock('src/libs/nav', () => ({ ...jest.requireActual('src/libs/nav'), getLink: jest.fn().mockImplementation((_) => _), @@ -27,13 +27,7 @@ describe('Showcase', () => { }); it('loads the showcase page', async () => { - Ajax.mockImplementation(() => { - return { - FirecloudBucket: { - getShowcaseWorkspaces: jest.fn(), - }, - }; - }); + FirecloudBucket.mockReturnValue({ getShowcaseWorkspaces: jest.fn() }); // Act await act(async () => {