Skip to content
Snippets Groups Projects
Commit e6a282e0 authored by mateuszmiko's avatar mateuszmiko
Browse files

[BLOCKED]Resolve MIN-60 "Feature/ connect search mirna query"

parent bcdd750b
No related branches found
No related tags found
2 merge requests!223reset the pin numbers before search results are fetch (so the results will be...,!22[BLOCKED]Resolve MIN-60 "Feature/ connect search mirna query"
......@@ -2,6 +2,7 @@ import { useSelector } from 'react-redux';
import { selectSearchValue } from '@/redux/search/search.selectors';
import { useAppDispatch } from '@/redux/hooks/useAppDispatch';
import { getDrugs } from '@/redux/drugs/drugs.thunks';
import { getMirnas } from '@/redux/mirnas/mirnas.thunks';
const ReduxPage = (): JSX.Element => {
const dispatch = useAppDispatch();
......@@ -9,6 +10,7 @@ const ReduxPage = (): JSX.Element => {
const triggerSyncUpdate = (): void => {
dispatch(getDrugs('aspirin'));
dispatch(getMirnas('hsa-miR-302b-3p'));
};
return (
......
// eslint-disable-next-line import/no-extraneous-dependencies
import { createFixture } from 'zod-fixture';
import { z } from 'zod';
import { mirnaSchema } from '@/models/mirnaSchema';
import { ZOD_SEED } from '@/constants/zodSeed';
export const mirnasFixture = createFixture(z.array(mirnaSchema), {
seed: ZOD_SEED,
array: { min: 2, max: 2 },
});
import { z } from 'zod';
import { targetSchema } from './targetSchema';
export const mirnaSchema = z.object({
id: z.string(),
name: z.string(),
targets: z.array(targetSchema),
});
import { PROJECT_ID } from '@/constants/mapId';
import { getMirnasStringWithQuery } from './getMirnasStringWithQuery';
describe('getMirnasStringWithQuery', () => {
it('should return url string', () => {
expect(getMirnasStringWithQuery('hsa-miR-302b-3p')).toBe(
`projects/${PROJECT_ID}/miRnas:search?query=hsa-miR-302b-3p`,
);
});
});
import { PROJECT_ID } from '@/constants/mapId';
export const getMirnasStringWithQuery = (searchQuery: string): string =>
`projects/${PROJECT_ID}/miRnas:search?query=${searchQuery}`;
import { mirnasFixture } from '@/models/fixtures/mirnasFixture';
import { mockNetworkResponse } from '@/utils/mockNetworkResponse';
import {
ToolkitStoreWithSingleSlice,
createStoreInstanceUsingSliceReducer,
} from '@/utils/createStoreInstanceUsingSliceReducer';
import { getMirnasStringWithQuery } from '@/queries/getMirnasStringWithQuery';
import { HttpStatusCode } from 'axios';
import { getMirnas } from './mirnas.thunks';
import mirnasReducer from './mirnas.slice';
import { MirnasState } from './mirnas.types';
const mockedAxiosClient = mockNetworkResponse();
const SEARCH_QUERY = 'aspirin';
const INITIAL_STATE: MirnasState = {
data: [],
loading: 'idle',
error: { name: '', message: '' },
};
describe('mirnas reducer', () => {
let store = {} as ToolkitStoreWithSingleSlice<MirnasState>;
beforeEach(() => {
store = createStoreInstanceUsingSliceReducer('mirnas', mirnasReducer);
});
it('should match initial state', () => {
const action = { type: 'unknown' };
expect(mirnasReducer(undefined, action)).toEqual(INITIAL_STATE);
});
it('should update store after succesfull getMirnas query', async () => {
mockedAxiosClient
.onGet(getMirnasStringWithQuery(SEARCH_QUERY))
.reply(HttpStatusCode.Ok, mirnasFixture);
const { type } = await store.dispatch(getMirnas(SEARCH_QUERY));
const { data, loading, error } = store.getState().mirnas;
expect(type).toBe('project/getMirnas/fulfilled');
expect(loading).toEqual('succeeded');
expect(error).toEqual({ message: '', name: '' });
expect(data).toEqual(mirnasFixture);
});
it('should update store after failed getMirnas query', async () => {
mockedAxiosClient
.onGet(getMirnasStringWithQuery(SEARCH_QUERY))
.reply(HttpStatusCode.NotFound, []);
const { type } = await store.dispatch(getMirnas(SEARCH_QUERY));
const { data, loading, error } = store.getState().mirnas;
expect(type).toBe('project/getMirnas/rejected');
expect(loading).toEqual('failed');
expect(error).toEqual({ message: '', name: '' });
expect(data).toEqual([]);
});
it('should update store on loading getMirnas query', async () => {
mockedAxiosClient
.onGet(getMirnasStringWithQuery(SEARCH_QUERY))
.reply(HttpStatusCode.Ok, mirnasFixture);
const mirnasPromise = store.dispatch(getMirnas(SEARCH_QUERY));
const { data, loading } = store.getState().mirnas;
expect(data).toEqual([]);
expect(loading).toEqual('pending');
mirnasPromise.then(() => {
const { data: dataPromiseFulfilled, loading: promiseFulfilled } = store.getState().mirnas;
expect(dataPromiseFulfilled).toEqual(mirnasFixture);
expect(promiseFulfilled).toEqual('succeeded');
});
});
});
import { ActionReducerMapBuilder } from '@reduxjs/toolkit';
import { MirnasState } from './mirnas.types';
import { getMirnas } from './mirnas.thunks';
export const getMirnasReducer = (builder: ActionReducerMapBuilder<MirnasState>): void => {
builder.addCase(getMirnas.pending, state => {
state.loading = 'pending';
});
builder.addCase(getMirnas.fulfilled, (state, action) => {
state.data = action.payload;
state.loading = 'succeeded';
});
builder.addCase(getMirnas.rejected, state => {
state.loading = 'failed';
// TODO: error management to be discussed in the team
});
};
import { createSlice } from '@reduxjs/toolkit';
import { MirnasState } from '@/redux/mirnas/mirnas.types';
import { getMirnasReducer } from './mirnas.reducers';
const initialState: MirnasState = {
data: [],
loading: 'idle',
error: { name: '', message: '' },
};
export const mirnasSlice = createSlice({
name: 'mirnas',
initialState,
reducers: {},
extraReducers: builder => {
getMirnasReducer(builder);
},
});
export default mirnasSlice.reducer;
import { mirnasFixture } from '@/models/fixtures/mirnasFixture';
import { mockNetworkResponse } from '@/utils/mockNetworkResponse';
import {
ToolkitStoreWithSingleSlice,
createStoreInstanceUsingSliceReducer,
} from '@/utils/createStoreInstanceUsingSliceReducer';
import { getMirnasStringWithQuery } from '@/queries/getMirnasStringWithQuery';
import { HttpStatusCode } from 'axios';
import { getMirnas } from './mirnas.thunks';
import mirnasReducer from './mirnas.slice';
import { MirnasState } from './mirnas.types';
const mockedAxiosClient = mockNetworkResponse();
const SEARCH_QUERY = 'hsa-miR-302b-3p';
describe('mirnas thunks', () => {
let store = {} as ToolkitStoreWithSingleSlice<MirnasState>;
beforeEach(() => {
store = createStoreInstanceUsingSliceReducer('mirnas', mirnasReducer);
});
describe('getMirnas', () => {
it('should return data when data response from API is valid', async () => {
mockedAxiosClient
.onGet(getMirnasStringWithQuery(SEARCH_QUERY))
.reply(HttpStatusCode.Ok, mirnasFixture);
const { payload } = await store.dispatch(getMirnas(SEARCH_QUERY));
expect(payload).toEqual(mirnasFixture);
});
it('should return undefined when data response from API is not valid ', async () => {
mockedAxiosClient
.onGet(getMirnasStringWithQuery(SEARCH_QUERY))
.reply(HttpStatusCode.Ok, { randomProperty: 'randomValue' });
const { payload } = await store.dispatch(getMirnas(SEARCH_QUERY));
expect(payload).toEqual(undefined);
});
});
});
import { z } from 'zod';
import { createAsyncThunk } from '@reduxjs/toolkit';
import { axiosInstance } from '@/services/api/utils/axiosInstance';
import { Mirna } from '@/types/models';
import { mirnaSchema } from '@/models/mirnaSchema';
import { validateDataUsingZodSchema } from '@/utils/validateDataUsingZodSchema';
import { getMirnasStringWithQuery } from '@/queries/getMirnasStringWithQuery';
export const getMirnas = createAsyncThunk(
'project/getMirnas',
async (searchQuery: string): Promise<Mirna[] | undefined> => {
const response = await axiosInstance.get<Mirna[]>(getMirnasStringWithQuery(searchQuery));
const isDataValid = validateDataUsingZodSchema(response.data, z.array(mirnaSchema));
return isDataValid ? response.data : undefined;
},
);
import { FetchDataState } from '@/types/fetchDataState';
import { Mirna } from '@/types/models';
export type MirnasState = FetchDataState<Mirna[]>;
......@@ -2,9 +2,11 @@ import { disease } from '@/models/disease';
import { drugSchema } from '@/models/drugSchema';
import { organism } from '@/models/organism';
import { projectSchema } from '@/models/project';
import { mirnaSchema } from '@/models/mirnaSchema';
import { z } from 'zod';
export type Project = z.infer<typeof projectSchema>;
export type Organism = z.infer<typeof organism>;
export type Disease = z.infer<typeof disease>;
export type Drug = z.infer<typeof drugSchema>;
export type Mirna = z.infer<typeof mirnaSchema>;
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment