-
Notifications
You must be signed in to change notification settings - Fork 11
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
test: unit tests feature components (#1423)
* DepositionFilterBanner tests * InfoLink tests * MLChallengeBanner tests * ObjectIdLink tests * mock css modules * extract MLChallenge mock utils * SurveyBanner tests * TablePageLayout tests * fix remix mock types * add comments
- Loading branch information
1 parent
bec698e
commit 2473e30
Showing
18 changed files
with
699 additions
and
15 deletions.
There are no files selected for viewing
80 changes: 80 additions & 0 deletions
80
...mponents/Dataset/SampleAndExperimentConditionsTable/components/InfoLink/InfoLink.test.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
import { createRemixStub } from '@remix-run/testing' | ||
import { render, screen } from '@testing-library/react' | ||
|
||
import { NCBI, OBO, WORMBASE } from 'app/constants/datasetInfoLinks' | ||
|
||
import { InfoLinkProps } from './InfoLink' | ||
|
||
async function renderInfoLink({ id, value }: InfoLinkProps) { | ||
const { InfoLink } = await import('./InfoLink') | ||
|
||
function InfoLinkWrapper() { | ||
return <InfoLink id={id} value={value} /> | ||
} | ||
|
||
const InfoLinkStub = createRemixStub([ | ||
{ | ||
path: '/', | ||
Component: InfoLinkWrapper, | ||
}, | ||
]) | ||
|
||
render(<InfoLinkStub />) | ||
} | ||
|
||
describe('<InfoLink />', () => { | ||
it('should render placeholder if no value', async () => { | ||
await renderInfoLink({ id: 123 }) | ||
expect(screen.getByText('--')).toBeInTheDocument() | ||
}) | ||
|
||
it('should render ncbi link', async () => { | ||
const id = 123 | ||
const value = 'value' | ||
await renderInfoLink({ id, value }) | ||
|
||
const link = screen.queryByRole('link', { name: value }) | ||
expect(link).toBeVisible() | ||
expect(link).toHaveAttribute('href', `${NCBI}${id}`) | ||
}) | ||
|
||
it('should render ncbi link with id prefix', async () => { | ||
const rawId = 123 | ||
const id = `NCBITaxon:${rawId}` | ||
const value = 'value' | ||
await renderInfoLink({ id, value }) | ||
|
||
const link = screen.queryByRole('link', { name: value }) | ||
expect(link).toBeVisible() | ||
expect(link).toHaveAttribute('href', `${NCBI}${rawId}`) | ||
}) | ||
|
||
it('should render wormbase link', async () => { | ||
const id = 'WBStrain12345678' | ||
const value = 'value' | ||
await renderInfoLink({ id, value }) | ||
|
||
const link = screen.queryByRole('link', { name: value }) | ||
expect(link).toBeVisible() | ||
expect(link).toHaveAttribute('href', `${WORMBASE}${id}`) | ||
}) | ||
|
||
it('should render obo link', async () => { | ||
const id = 'foobar:123' | ||
const value = 'value' | ||
await renderInfoLink({ id, value }) | ||
|
||
const link = screen.queryByRole('link', { name: value }) | ||
expect(link).toBeVisible() | ||
expect(link).toHaveAttribute('href', `${OBO}${id.replaceAll(':', '_')}`) | ||
}) | ||
|
||
it('should not render link if no pattern match', async () => { | ||
const id = 'someid123' | ||
const value = 'value' | ||
await renderInfoLink({ id, value }) | ||
|
||
expect(screen.queryByRole('link', { name: value })).not.toBeInTheDocument() | ||
expect(screen.getByText(value)).toBeInTheDocument() | ||
}) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
83 changes: 83 additions & 0 deletions
83
frontend/packages/data-portal/app/components/DepositionFilterBanner.test.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
import { jest } from '@jest/globals' | ||
import { createRemixStub } from '@remix-run/testing' | ||
import { render, screen } from '@testing-library/react' | ||
import userEvent from '@testing-library/user-event' | ||
|
||
import { MockI18n } from './I18n.mock' | ||
|
||
const MOCK_DEPOSITION = { | ||
id: 123, | ||
title: 'Title', | ||
} | ||
|
||
jest.unstable_mockModule('app/components/I18n', () => ({ | ||
__esModule: true, | ||
I18n: MockI18n, | ||
})) | ||
|
||
const setDepositionIdMock = jest.fn() | ||
|
||
jest.unstable_mockModule('app/hooks/useQueryParam', () => ({ | ||
useQueryParam: jest.fn().mockReturnValue([null, setDepositionIdMock]), | ||
})) | ||
|
||
const setPreviousSingleDatasetParamsMock = jest.fn() | ||
|
||
jest.unstable_mockModule('app/state/filterHistory', () => ({ | ||
useDepositionHistory: jest.fn(() => ({ | ||
previousSingleDepositionParams: 'object=foo', | ||
})), | ||
|
||
useSingleDatasetFilterHistory: jest.fn(() => ({ | ||
previousSingleDatasetParams: `object=foo&deposition-id=${MOCK_DEPOSITION.id}`, | ||
setPreviousSingleDatasetParams: setPreviousSingleDatasetParamsMock, | ||
})), | ||
})) | ||
|
||
async function renderDepositionFilterBanner() { | ||
const { DepositionFilterBanner } = await import('./DepositionFilterBanner') | ||
|
||
function DepositionFilterBannerWrapper() { | ||
return ( | ||
<DepositionFilterBanner | ||
deposition={MOCK_DEPOSITION} | ||
labelI18n="onlyDisplayingRunsWithAnnotations" | ||
/> | ||
) | ||
} | ||
|
||
const DepositionFilterBannerStub = createRemixStub([ | ||
{ | ||
path: '/', | ||
Component: DepositionFilterBannerWrapper, | ||
}, | ||
]) | ||
|
||
render(<DepositionFilterBannerStub />) | ||
} | ||
|
||
describe('<DepositionFilterBanner />', () => { | ||
it('should render deposition url', async () => { | ||
await renderDepositionFilterBanner() | ||
|
||
const text = screen.getByText('onlyDisplayingRunsWithAnnotations') | ||
expect(text).toHaveAttribute( | ||
'data-values', | ||
JSON.stringify({ | ||
...MOCK_DEPOSITION, | ||
url: `/depositions/${MOCK_DEPOSITION.id}?object=foo`, | ||
}), | ||
) | ||
}) | ||
|
||
it('should remove filter on click', async () => { | ||
await renderDepositionFilterBanner() | ||
|
||
await userEvent.click(screen.getByRole('button', { name: 'removeFilter' })) | ||
|
||
expect(setDepositionIdMock).toHaveBeenCalledWith(null) | ||
expect(setPreviousSingleDatasetParamsMock).toHaveBeenCalledWith( | ||
'object=foo', | ||
) | ||
}) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
17 changes: 17 additions & 0 deletions
17
frontend/packages/data-portal/app/components/I18n.mock.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
import type { I18nProps } from './I18n' | ||
|
||
/** | ||
* Mock I18n component for rendering span element with i18n key as the content. | ||
* Any values are passed in the data-attribute prop in case values need to be | ||
* tested. | ||
*/ | ||
export function MockI18n({ i18nKey, values, linkProps }: I18nProps) { | ||
return ( | ||
<span | ||
data-values={JSON.stringify(values)} | ||
data-link-props={JSON.stringify(linkProps)} | ||
> | ||
{i18nKey} | ||
</span> | ||
) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
90 changes: 90 additions & 0 deletions
90
frontend/packages/data-portal/app/components/MLChallenge/MLChallengeBanner.test.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
import { beforeEach, jest } from '@jest/globals' | ||
import { render, screen } from '@testing-library/react' | ||
|
||
import { MockI18n } from 'app/components/I18n.mock' | ||
import { LocalStorageMock } from 'app/mocks/LocalStorage.mock' | ||
import { RemixMock } from 'app/mocks/Remix.mock' | ||
import { getMockUser, setMockTime } from 'app/utils/mock' | ||
|
||
async function renderMlChallengeBanner() { | ||
const { MLChallengeBanner } = await import('./MLChallengeBanner') | ||
render(<MLChallengeBanner />) | ||
} | ||
|
||
jest.unstable_mockModule('app/components/I18n', () => ({ I18n: MockI18n })) | ||
|
||
const remixMock = new RemixMock() | ||
const localStorageMock = new LocalStorageMock() | ||
|
||
describe('<MLChallengeBanner />', () => { | ||
beforeEach(() => { | ||
jest.useRealTimers() | ||
localStorageMock.reset() | ||
remixMock.reset() | ||
}) | ||
|
||
const paths = ['/', '/browse-data/datasets', '/browse-data/depositions'] | ||
|
||
paths.forEach((pathname) => { | ||
it(`should render on ${pathname}`, async () => { | ||
remixMock.mockPathname(pathname) | ||
await renderMlChallengeBanner() | ||
expect(screen.queryByRole('banner')).toBeVisible() | ||
}) | ||
}) | ||
|
||
it('should not render on blocked pages', async () => { | ||
remixMock.mockPathname('/competition') | ||
await renderMlChallengeBanner() | ||
expect(screen.queryByRole('banner')).not.toBeInTheDocument() | ||
}) | ||
|
||
it('should render challenge began message', async () => { | ||
setMockTime('2024-12-01') | ||
|
||
await renderMlChallengeBanner() | ||
expect(screen.getByText('mlCompetitionHasBegun')).toBeVisible() | ||
}) | ||
|
||
it('should render challenge ending message', async () => { | ||
setMockTime('2025-01-30') | ||
|
||
await renderMlChallengeBanner() | ||
expect(screen.getByText('mlCompetitionEnding')).toBeVisible() | ||
}) | ||
|
||
it('should render challenge ended message', async () => { | ||
setMockTime('2025-02-07') | ||
|
||
await renderMlChallengeBanner() | ||
expect(screen.getByText('mlCompetitionEnded')).toBeVisible() | ||
}) | ||
|
||
it('should not render banner if was dismissed', async () => { | ||
setMockTime('2024-12-01') | ||
localStorageMock.mockValue('mlCompetitionHasBegun') | ||
|
||
await renderMlChallengeBanner() | ||
expect(screen.queryByRole('banner')).not.toBeInTheDocument() | ||
}) | ||
|
||
it('should render banner if last dismissed was previous state', async () => { | ||
setMockTime('2025-01-30') | ||
localStorageMock.mockValue('mlCompetitionHasBegun') | ||
|
||
await renderMlChallengeBanner() | ||
expect(screen.getByRole('banner')).toBeVisible() | ||
}) | ||
|
||
it('should dismiss banner on click', async () => { | ||
setMockTime('2024-12-01') | ||
|
||
await renderMlChallengeBanner() | ||
await getMockUser().click(screen.getByRole('button')) | ||
|
||
expect(screen.queryByRole('banner')).not.toBeInTheDocument() | ||
expect(localStorageMock.setValue).toHaveBeenCalledWith( | ||
'mlCompetitionHasBegun', | ||
) | ||
}) | ||
}) |
49 changes: 49 additions & 0 deletions
49
...al/app/components/Run/AnnotationObjectTable/components/ObjectIdLink/ObjectIdLink.test.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
import { createRemixStub } from '@remix-run/testing' | ||
import { render, screen } from '@testing-library/react' | ||
|
||
import { GO, UNIPROTKB } from 'app/constants/annotationObjectIdLinks' | ||
|
||
async function renderObjectIdLink(id: string) { | ||
const { ObjectIdLink } = await import('./ObjectIdLink') | ||
|
||
function ObjectIdLinkWrapper() { | ||
return <ObjectIdLink id={id} /> | ||
} | ||
|
||
const ObjectIdLinkStub = createRemixStub([ | ||
{ | ||
path: '/', | ||
Component: ObjectIdLinkWrapper, | ||
}, | ||
]) | ||
|
||
render(<ObjectIdLinkStub />) | ||
} | ||
|
||
describe('<ObjectIdLink />', () => { | ||
it('should render go link', async () => { | ||
const id = 'GO:123' | ||
await renderObjectIdLink(id) | ||
|
||
expect(screen.getByRole('link')).toHaveAttribute('href', `${GO}${id}`) | ||
}) | ||
|
||
it('should render UniProtKB link', async () => { | ||
const rawId = 123 | ||
const id = `UniProtKB:${rawId}` | ||
await renderObjectIdLink(id) | ||
|
||
expect(screen.getByRole('link')).toHaveAttribute( | ||
'href', | ||
`${UNIPROTKB}${rawId}`, | ||
) | ||
}) | ||
|
||
it('should not render link if not matched', async () => { | ||
const id = 'test-id-123' | ||
await renderObjectIdLink(id) | ||
|
||
expect(screen.queryByRole('link')).not.toBeInTheDocument() | ||
expect(screen.getByText(id)).toBeVisible() | ||
}) | ||
}) |
Oops, something went wrong.