Skip to content

Commit

Permalink
add tests for cohortApi
Browse files Browse the repository at this point in the history
  • Loading branch information
craigrbarnes committed Feb 3, 2025
1 parent 4d23c88 commit 0e4f651
Show file tree
Hide file tree
Showing 4 changed files with 252 additions and 15 deletions.
160 changes: 160 additions & 0 deletions src/lib/AnalysisApps/GWAS/Utils/cohortApi.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
import { waitFor } from '@testing-library/react';
import { http, HttpResponse } from 'msw';
import { setupServer } from 'msw/node';
import {
describe,
expect,
it,
beforeAll,
afterAll,
afterEach,
beforeEach,
} from '@jest/globals';
import { renderHook } from '../../../test/test-utils';

import {
GEN3_COHORT_MIDDLEWARE_API,
useGetCohortDefinitionsQuery,
useGetSourcesQuery
} from './cohortApi';

const server = setupServer();

const cohortDefinitionAndStatsData = {
cohort_definitions_and_stats: [
{
cohort_definition_id: 573,
cohort_name: 'team2 - test new cohort - catch all',
size: 70240,
},
{
cohort_definition_id: 559,
cohort_name: 'test new cohort - catch all',
size: 70240,
},
{
cohort_definition_id: 574,
cohort_name: 'team2 - test new cohort - medium + large',
size: 23800,
},
{
cohort_definition_id: 575,
cohort_name: 'team2 - test new cohort - small',
size: 80,
},
]};

describe('cohortApi', () => {
beforeAll(() => {
// Start the interception.
server.listen();
});
beforeEach(() => {});

afterEach(() => {
// Remove any handlers you may have added
// in individual tests (runtime handlers).
server.resetHandlers();
});

afterAll(() => {
// Disable request interception and clean up.
server.close();
});

it('fetches and returns cohort definitions successfully', async () => {
const sourceId = '1234567890';
const selectedTeamProject = 'project2';

server.use(
http.get(
`${GEN3_COHORT_MIDDLEWARE_API}/cohortdefinition-stats/by-source-id/1234567890/by-team-project`,
({ request }) => {
const url = new URL(request.url);
const project = url.searchParams.get('team-project');
if (project !== 'project2') {
return new HttpResponse(null, {
status: 403,
});
}
return HttpResponse.json(cohortDefinitionAndStatsData);
},
),
);

const { result } = renderHook(() =>
useGetCohortDefinitionsQuery({ sourceId, selectedTeamProject }),
);

expect(result.current.isFetching).toBe(true);

await waitFor(() => expect(result.current.isSuccess).toBeTruthy());

expect(result.current).toMatchObject({
isError: false,
isFetching: false,
isSuccess: true,
isLoading: false,
data: cohortDefinitionAndStatsData,
});
});

it('returns error if project id not accessible ', async () => {

const sourceId = '1234567890';
const selectedTeamProject = 'project2345';

server.use(
http.get(
`${GEN3_COHORT_MIDDLEWARE_API}/cohortdefinition-stats/by-source-id/1234567890/by-team-project`,
() => {
return new HttpResponse(null, {
status: 403,
});
},
),
);

const { result } = renderHook(() =>
useGetCohortDefinitionsQuery({ sourceId, selectedTeamProject }),
);

expect(result.current.isFetching).toBe(true);

await waitFor(() => expect(result.current.isError).toBeTruthy());
expect(result.current).toMatchObject({
isError: true,
isFetching: false,
isSuccess: false,
isLoading: false,
error: { status: 403}
});
});

it('test for successful useGetSources ', async () => {
const data = {"sources":[{"source_id":123,"source_name":"MVP-batch19000101"}]};
server.use(
http.get(
`${GEN3_COHORT_MIDDLEWARE_API}/sources`,
() => {
return HttpResponse.json(data);
},
),
);

const { result } = renderHook(() =>
useGetSourcesQuery(),
);

expect(result.current.isFetching).toBe(true);

await waitFor(() => expect(result.current.isSuccess).toBeTruthy());
expect(result.current).toMatchObject({
isError: false,
isFetching: false,
isSuccess: true,
isLoading: false,
data: data
});
});
});
61 changes: 61 additions & 0 deletions src/lib/AnalysisApps/GWAS/Utils/cohortApi.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import { gen3Api, GEN3_API} from '@gen3/core';

const TAGS = 'GWASApp';
export const GEN3_COHORT_MIDDLEWARE_API = `${GEN3_API}/cohort-middleware`;

const hareConceptId = 2000007027;

export const gwasCohortApiTags = gen3Api.enhanceEndpoints({
addTagTypes: [TAGS],
});

// Types for API calls

interface CohortDefinitionQueryParams {
sourceId: string;
selectedTeamProject: string;
}

export interface GWASCohortDefinition {
cohort_definition_id: number;
cohort_name: string;
size: number;
}

export interface GWASCohortDefinitionResponse {
cohort_definitions_and_stats: Array<GWASCohortDefinition>;
}

interface SourcesResponse {
sources: Array<{source_id: string, source_name: string}>
}

export const gwasCohortApi = gwasCohortApiTags.injectEndpoints({
endpoints: (builder) => ({
getCohortDefinitions: builder.query<GWASCohortDefinitionResponse, CohortDefinitionQueryParams>({
query: ({
sourceId,
selectedTeamProject
}) => `${GEN3_COHORT_MIDDLEWARE_API}/cohortdefinition-stats/by-source-id/${sourceId}/by-team-project?team-project=${selectedTeamProject}`,
transformResponse: (response: Record<string, never>) => {
// confirm data is valid
if (!response || typeof response !== 'object') {
throw new Error('Invalid response format');
}
if (!('cohort_definitions_and_stats' in response)) {
throw new Error('Missing field cohort_definitions_and_stats');
}
return { cohort_definitions_and_stats: response.cohort_definitions_and_stats };
},
}),
getSources: builder.query< SourcesResponse, void> ({
query: () => `${GEN3_COHORT_MIDDLEWARE_API}/sources`,
}),
}),
});


export const {
useGetCohortDefinitionsQuery,
useGetSourcesQuery
} = gwasCohortApi;
29 changes: 29 additions & 0 deletions src/lib/AnalysisApps/GWAS/Utils/cohortHooks.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { useCallback, useState, useEffect } from 'react';
import { useGetSourcesQuery } from '@/lib/AnalysisApps/GWAS/Utils/cohortApi';

export const useSourceFetch = () => {
const [sourceId, setSourceId] = useState<string | undefined>(undefined);
const { data, error, isError, isSuccess, isFetching } = useGetSourcesQuery();
const getSources = () => {
// fetch sources on initialization

if (isSuccess) {
if (Array.isArray(data?.sources) && data.sources.length === 1) {
setSourceId(data.sources[0].source_id);
} else {
const message = `Data source received in an invalid format: ${JSON.stringify(
data?.sources,
)}`;
throw new Error(message);
}
}
if (isError) {
const message = `Data source received an error: ${error}`;
throw new Error(message);
}
};
useEffect(() => {
getSources();
}, [getSources]);
return { isFetching, sourceId };
};
Original file line number Diff line number Diff line change
Expand Up @@ -15,21 +15,7 @@ import { http, HttpResponse } from 'msw';
import { setupServer } from 'msw/node';
import { GEN3_AUTHZ_API } from '@gen3/core';

const server = setupServer(
http.get(`${GEN3_AUTHZ_API}/mapping`, () => {
return HttpResponse.json({
'/gwas_projects/project1': [{ abc: 'def' }],
'/gwas_projects/project2': [
{ abc: 'def' },
{
service: 'atlas-argo-wrapper-and-cohort-middleware',
method: 'access',
},
],
'/other/project3': [{ abc: 'def' }],
});
}),
);
const server = setupServer();

describe('useTeamProjects', () => {
beforeAll(() => {
Expand Down Expand Up @@ -82,6 +68,7 @@ describe('useTeamProjects', () => {
],
});
});

it('fetches and returns isError', async () => {
server.use(
http.get(`${GEN3_AUTHZ_API}/mapping`, () => {
Expand Down

0 comments on commit 0e4f651

Please sign in to comment.